forked from Qortal/qortal
Fix up some group-approval related issues
UPDATE_NAME requires txGroupId to match original txGroupId used in REGISTER_NAME UPDATE_GROUP requires txGroupId to match original txGroupId used in CREATE_GROUP Extraneous JAXB unmarshal code removed from various transaction constructors. Incorrect, old, groupID vs txGroupId checks removed from various transactions. Fix bug in UPDATE_GROUP fromBase() method using mismatched column indexes. Fix bug in API's pending transaction fetch not checking admin is of the same group as the txGroupId. (Fix actually in HSQLDBTransactionRepository). Similar fix in GroupApprovalTransaction.
This commit is contained in:
parent
c7123df79d
commit
ec5eba9c60
@ -28,6 +28,12 @@ public class GroupData {
|
||||
@XmlTransient
|
||||
@Schema(hidden = true)
|
||||
private byte[] reference;
|
||||
// For internal use
|
||||
@XmlTransient
|
||||
@Schema(
|
||||
hidden = true
|
||||
)
|
||||
private int creationGroupId;
|
||||
|
||||
// Constructors
|
||||
|
||||
@ -36,7 +42,7 @@ public class GroupData {
|
||||
}
|
||||
|
||||
/** Constructs new GroupData with nullable groupId and nullable updated [timestamp] */
|
||||
public GroupData(Integer groupId, String owner, String name, String description, long created, Long updated, boolean isOpen, ApprovalThreshold approvalThreshold, int minBlockDelay, int maxBlockDelay, byte[] reference) {
|
||||
public GroupData(Integer groupId, String owner, String name, String description, long created, Long updated, boolean isOpen, ApprovalThreshold approvalThreshold, int minBlockDelay, int maxBlockDelay, byte[] reference, int creationGroupId) {
|
||||
this.groupId = groupId;
|
||||
this.owner = owner;
|
||||
this.groupName = name;
|
||||
@ -48,11 +54,12 @@ public class GroupData {
|
||||
this.reference = reference;
|
||||
this.minimumBlockDelay = minBlockDelay;
|
||||
this.maximumBlockDelay = maxBlockDelay;
|
||||
this.creationGroupId = creationGroupId;
|
||||
}
|
||||
|
||||
/** Constructs new GroupData with unassigned groupId */
|
||||
public GroupData(String owner, String name, String description, long created, boolean isOpen, ApprovalThreshold approvalThreshold, int minBlockDelay, int maxBlockDelay, byte[] reference) {
|
||||
this(null, owner, name, description, created, null, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference);
|
||||
public GroupData(String owner, String name, String description, long created, boolean isOpen, ApprovalThreshold approvalThreshold, int minBlockDelay, int maxBlockDelay, byte[] reference, int creationGroupId) {
|
||||
this(null, owner, name, description, created, null, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference, creationGroupId);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
@ -129,4 +136,8 @@ public class GroupData {
|
||||
return this.maximumBlockDelay;
|
||||
}
|
||||
|
||||
public int getCreationGroupId() {
|
||||
return this.creationGroupId;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,10 +20,18 @@ public class NameData {
|
||||
private Long updated;
|
||||
// No need to expose this via API
|
||||
@XmlTransient
|
||||
@Schema(hidden = true)
|
||||
@Schema(
|
||||
hidden = true
|
||||
)
|
||||
private byte[] reference;
|
||||
private boolean isForSale;
|
||||
private BigDecimal salePrice;
|
||||
// For internal use
|
||||
@XmlTransient
|
||||
@Schema(
|
||||
hidden = true
|
||||
)
|
||||
private int creationGroupId;
|
||||
|
||||
// Constructors
|
||||
|
||||
@ -31,8 +39,8 @@ public class NameData {
|
||||
protected NameData() {
|
||||
}
|
||||
|
||||
public NameData(String owner, String name, String data, long registered, Long updated, byte[] reference, boolean isForSale,
|
||||
BigDecimal salePrice) {
|
||||
public NameData(String owner, String name, String data, long registered, Long updated, byte[] reference, boolean isForSale, BigDecimal salePrice,
|
||||
int creationGroupId) {
|
||||
this.owner = owner;
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
@ -41,10 +49,11 @@ public class NameData {
|
||||
this.reference = reference;
|
||||
this.isForSale = isForSale;
|
||||
this.salePrice = salePrice;
|
||||
this.creationGroupId = creationGroupId;
|
||||
}
|
||||
|
||||
public NameData(String owner, String name, String data, long registered, byte[] reference) {
|
||||
this(owner, name, data, registered, null, reference, false, null);
|
||||
public NameData(String owner, String name, String data, long registered, byte[] reference, int creationGroupId) {
|
||||
this(owner, name, data, registered, null, reference, false, null, creationGroupId);
|
||||
}
|
||||
|
||||
// Getters / setters
|
||||
@ -105,4 +114,8 @@ public class NameData {
|
||||
this.salePrice = salePrice;
|
||||
}
|
||||
|
||||
public int getCreationGroupId() {
|
||||
return this.creationGroupId;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,6 +46,11 @@ public class IssueAssetTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||
/*
|
||||
* If we're being constructed as part of the genesis block info inside blockchain config
|
||||
* and no specific issuer's public key is supplied
|
||||
* then use genesis account's public key.
|
||||
*/
|
||||
if (parent instanceof GenesisBlock.GenesisInfo && this.issuerPublicKey == null)
|
||||
this.issuerPublicKey = GenesisAccount.PUBLIC_KEY;
|
||||
|
||||
|
@ -116,7 +116,7 @@ public class Group {
|
||||
this.groupData = new GroupData(createGroupTransactionData.getOwner(), createGroupTransactionData.getGroupName(),
|
||||
createGroupTransactionData.getDescription(), createGroupTransactionData.getTimestamp(), createGroupTransactionData.getIsOpen(),
|
||||
createGroupTransactionData.getApprovalThreshold(), createGroupTransactionData.getMinimumBlockDelay(),
|
||||
createGroupTransactionData.getMaximumBlockDelay(), createGroupTransactionData.getSignature());
|
||||
createGroupTransactionData.getMaximumBlockDelay(), createGroupTransactionData.getSignature(), createGroupTransactionData.getTxGroupId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,7 +35,7 @@ public class Name {
|
||||
this.repository = repository;
|
||||
this.nameData = new NameData(registerNameTransactionData.getOwner(),
|
||||
registerNameTransactionData.getName(), registerNameTransactionData.getData(), registerNameTransactionData.getTimestamp(),
|
||||
registerNameTransactionData.getSignature());
|
||||
registerNameTransactionData.getSignature(), registerNameTransactionData.getTxGroupId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -568,6 +568,21 @@ public class HSQLDBDatabaseUpdates {
|
||||
stmt.execute("ALTER TABLE UpdateGroupTransactions ADD COLUMN new_max_block_delay INT NOT NULL DEFAULT 1440 BEFORE group_reference");
|
||||
break;
|
||||
|
||||
case 36:
|
||||
// Adding group-ness to record types that could require approval for their related transactions
|
||||
// e.g. REGISTER_NAME might require approval and so Names table requires groupID
|
||||
// Registered Names
|
||||
stmt.execute("ALTER TABLE Names ADD COLUMN creation_group_id GroupID NOT NULL DEFAULT 0");
|
||||
// Assets aren't ever updated so don't need group-ness
|
||||
// for future use: stmt.execute("ALTER TABLE Assets ADD COLUMN creation_group_id GroupID NOT NULL DEFAULT 0");
|
||||
// Polls aren't ever updated, only voted upon using option index so don't need group-ness
|
||||
// for future use: stmt.execute("ALTER TABLE Polls ADD COLUMN creation_group_id GroupID NOT NULL DEFAULT 0");
|
||||
// CIYAM ATs
|
||||
stmt.execute("ALTER TABLE ATs ADD COLUMN creation_group_id GroupID NOT NULL DEFAULT 0");
|
||||
// Groups can be updated but updates require approval from original groupID
|
||||
stmt.execute("ALTER TABLE Groups ADD COLUMN creation_group_id GroupID NOT NULL DEFAULT 0");
|
||||
break;
|
||||
|
||||
default:
|
||||
// nothing to do
|
||||
return false;
|
||||
|
@ -30,7 +30,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
@Override
|
||||
public GroupData fromGroupId(int groupId) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT group_name, owner, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay FROM Groups WHERE group_id = ?", groupId)) {
|
||||
.checkedExecute("SELECT group_name, owner, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups WHERE group_id = ?", groupId)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
@ -51,7 +51,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
int minBlockDelay = resultSet.getInt(9);
|
||||
int maxBlockDelay = resultSet.getInt(10);
|
||||
|
||||
return new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference);
|
||||
int creationGroupId = resultSet.getInt(11);
|
||||
|
||||
return new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference, creationGroupId);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group info from repository", e);
|
||||
}
|
||||
@ -60,7 +62,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
@Override
|
||||
public GroupData fromGroupName(String groupName) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT group_id, owner, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay FROM Groups WHERE group_name = ?", groupName)) {
|
||||
.checkedExecute("SELECT group_id, owner, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups WHERE group_name = ?", groupName)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
@ -81,7 +83,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
int minBlockDelay = resultSet.getInt(9);
|
||||
int maxBlockDelay = resultSet.getInt(10);
|
||||
|
||||
return new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference);
|
||||
int creationGroupId = resultSet.getInt(11);
|
||||
|
||||
return new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference, creationGroupId);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch group info from repository", e);
|
||||
}
|
||||
@ -107,7 +111,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
|
||||
@Override
|
||||
public List<GroupData> getAllGroups(Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay FROM Groups ORDER BY group_name";
|
||||
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups ORDER BY group_name";
|
||||
if (reverse != null && reverse)
|
||||
sql += " DESC";
|
||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||
@ -137,7 +141,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
int minBlockDelay = resultSet.getInt(10);
|
||||
int maxBlockDelay = resultSet.getInt(11);
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference));
|
||||
int creationGroupId = resultSet.getInt(12);
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference, creationGroupId));
|
||||
} while (resultSet.next());
|
||||
|
||||
return groups;
|
||||
@ -148,7 +154,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
|
||||
@Override
|
||||
public List<GroupData> getGroupsByOwner(String owner, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
String sql = "SELECT group_id, group_name, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay FROM Groups WHERE owner = ? ORDER BY group_name";
|
||||
String sql = "SELECT group_id, group_name, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups WHERE owner = ? ORDER BY group_name";
|
||||
if (reverse != null && reverse)
|
||||
sql += " DESC";
|
||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||
@ -177,7 +183,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
int minBlockDelay = resultSet.getInt(9);
|
||||
int maxBlockDelay = resultSet.getInt(10);
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference));
|
||||
int creationGroupId = resultSet.getInt(11);
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference, creationGroupId));
|
||||
} while (resultSet.next());
|
||||
|
||||
return groups;
|
||||
@ -188,7 +196,7 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
|
||||
@Override
|
||||
public List<GroupData> getGroupsWithMember(String member, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold min_block_delay, max_block_delay FROM Groups "
|
||||
String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold min_block_delay, max_block_delay, creation_group_id FROM Groups "
|
||||
+ "JOIN GroupMembers USING (group_id) WHERE address = ? ORDER BY group_name";
|
||||
if (reverse != null && reverse)
|
||||
sql += " DESC";
|
||||
@ -219,7 +227,9 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
int minBlockDelay = resultSet.getInt(10);
|
||||
int maxBlockDelay = resultSet.getInt(11);
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference));
|
||||
int creationGroupId = resultSet.getInt(12);
|
||||
|
||||
groups.add(new GroupData(groupId, owner, groupName, description, created, updated, isOpen, approvalThreshold, minBlockDelay, maxBlockDelay, reference, creationGroupId));
|
||||
} while (resultSet.next());
|
||||
|
||||
return groups;
|
||||
@ -239,7 +249,8 @@ public class HSQLDBGroupRepository implements GroupRepository {
|
||||
saveHelper.bind("group_id", groupData.getGroupId()).bind("owner", groupData.getOwner()).bind("group_name", groupData.getGroupName())
|
||||
.bind("description", groupData.getDescription()).bind("created", new Timestamp(groupData.getCreated())).bind("updated", updatedTimestamp)
|
||||
.bind("reference", groupData.getReference()).bind("is_open", groupData.getIsOpen()).bind("approval_threshold", groupData.getApprovalThreshold().value)
|
||||
.bind("min_block_delay", groupData.getMinimumBlockDelay()).bind("max_block_delay", groupData.getMaximumBlockDelay());
|
||||
.bind("min_block_delay", groupData.getMinimumBlockDelay()).bind("max_block_delay", groupData.getMaximumBlockDelay())
|
||||
.bind("creation_group_id", groupData.getCreationGroupId());
|
||||
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
|
@ -23,7 +23,7 @@ public class HSQLDBNameRepository implements NameRepository {
|
||||
@Override
|
||||
public NameData fromName(String name) throws DataException {
|
||||
try (ResultSet resultSet = this.repository
|
||||
.checkedExecute("SELECT owner, data, registered, updated, reference, is_for_sale, sale_price FROM Names WHERE name = ?", name)) {
|
||||
.checkedExecute("SELECT owner, data, registered, updated, reference, is_for_sale, sale_price, creation_group_id FROM Names WHERE name = ?", name)) {
|
||||
if (resultSet == null)
|
||||
return null;
|
||||
|
||||
@ -38,8 +38,9 @@ public class HSQLDBNameRepository implements NameRepository {
|
||||
byte[] reference = resultSet.getBytes(5);
|
||||
boolean isForSale = resultSet.getBoolean(6);
|
||||
BigDecimal salePrice = resultSet.getBigDecimal(7);
|
||||
int creationGroupId = resultSet.getInt(8);
|
||||
|
||||
return new NameData(owner, name, data, registered, updated, reference, isForSale, salePrice);
|
||||
return new NameData(owner, name, data, registered, updated, reference, isForSale, salePrice, creationGroupId);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch name info from repository", e);
|
||||
}
|
||||
@ -56,7 +57,7 @@ public class HSQLDBNameRepository implements NameRepository {
|
||||
|
||||
@Override
|
||||
public List<NameData> getAllNames(Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
String sql = "SELECT name, data, owner, registered, updated, reference, is_for_sale, sale_price FROM Names ORDER BY name";
|
||||
String sql = "SELECT name, data, owner, registered, updated, reference, is_for_sale, sale_price, creation_group_id FROM Names ORDER BY name";
|
||||
if (reverse != null && reverse)
|
||||
sql += " DESC";
|
||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||
@ -80,8 +81,9 @@ public class HSQLDBNameRepository implements NameRepository {
|
||||
byte[] reference = resultSet.getBytes(6);
|
||||
boolean isForSale = resultSet.getBoolean(7);
|
||||
BigDecimal salePrice = resultSet.getBigDecimal(8);
|
||||
int creationGroupId = resultSet.getInt(9);
|
||||
|
||||
names.add(new NameData(owner, name, data, registered, updated, reference, isForSale, salePrice));
|
||||
names.add(new NameData(owner, name, data, registered, updated, reference, isForSale, salePrice, creationGroupId));
|
||||
} while (resultSet.next());
|
||||
|
||||
return names;
|
||||
@ -92,7 +94,7 @@ public class HSQLDBNameRepository implements NameRepository {
|
||||
|
||||
@Override
|
||||
public List<NameData> getNamesForSale(Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
String sql = "SELECT name, data, owner, registered, updated, reference, sale_price FROM Names WHERE is_for_sale = TRUE ORDER BY name";
|
||||
String sql = "SELECT name, data, owner, registered, updated, reference, sale_price, creation_group_id FROM Names WHERE is_for_sale = TRUE ORDER BY name";
|
||||
if (reverse != null && reverse)
|
||||
sql += " DESC";
|
||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||
@ -116,8 +118,9 @@ public class HSQLDBNameRepository implements NameRepository {
|
||||
byte[] reference = resultSet.getBytes(6);
|
||||
boolean isForSale = true;
|
||||
BigDecimal salePrice = resultSet.getBigDecimal(7);
|
||||
int creationGroupId = resultSet.getInt(8);
|
||||
|
||||
names.add(new NameData(owner, name, data, registered, updated, reference, isForSale, salePrice));
|
||||
names.add(new NameData(owner, name, data, registered, updated, reference, isForSale, salePrice, creationGroupId));
|
||||
} while (resultSet.next());
|
||||
|
||||
return names;
|
||||
@ -128,7 +131,7 @@ public class HSQLDBNameRepository implements NameRepository {
|
||||
|
||||
@Override
|
||||
public List<NameData> getNamesByOwner(String owner, Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
String sql = "SELECT name, data, registered, updated, reference, is_for_sale, sale_price FROM Names WHERE owner = ? ORDER BY name";
|
||||
String sql = "SELECT name, data, registered, updated, reference, is_for_sale, sale_price, creation_group_id FROM Names WHERE owner = ? ORDER BY name";
|
||||
if (reverse != null && reverse)
|
||||
sql += " DESC";
|
||||
sql += HSQLDBRepository.limitOffsetSql(limit, offset);
|
||||
@ -151,8 +154,9 @@ public class HSQLDBNameRepository implements NameRepository {
|
||||
byte[] reference = resultSet.getBytes(5);
|
||||
boolean isForSale = resultSet.getBoolean(6);
|
||||
BigDecimal salePrice = resultSet.getBigDecimal(7);
|
||||
int creationGroupId = resultSet.getInt(8);
|
||||
|
||||
names.add(new NameData(owner, name, data, registered, updated, reference, isForSale, salePrice));
|
||||
names.add(new NameData(owner, name, data, registered, updated, reference, isForSale, salePrice, creationGroupId));
|
||||
} while (resultSet.next());
|
||||
|
||||
return names;
|
||||
@ -171,7 +175,8 @@ public class HSQLDBNameRepository implements NameRepository {
|
||||
|
||||
saveHelper.bind("owner", nameData.getOwner()).bind("name", nameData.getName()).bind("data", nameData.getData())
|
||||
.bind("registered", new Timestamp(nameData.getRegistered())).bind("updated", updatedTimestamp).bind("reference", nameData.getReference())
|
||||
.bind("is_for_sale", nameData.getIsForSale()).bind("sale_price", nameData.getSalePrice());
|
||||
.bind("is_for_sale", nameData.getIsForSale()).bind("sale_price", nameData.getSalePrice())
|
||||
.bind("creation_group_id", nameData.getCreationGroupId());
|
||||
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
|
@ -508,7 +508,7 @@ public class HSQLDBTransactionRepository implements TransactionRepository {
|
||||
String sql = "SELECT signature FROM UnconfirmedTransactions "
|
||||
+ "NATURAL JOIN Transactions "
|
||||
+ "LEFT OUTER JOIN Accounts ON Accounts.public_key = Transactions.creator "
|
||||
+ "LEFT OUTER JOIN GroupAdmins ON GroupAdmins.admin = Accounts.account "
|
||||
+ "LEFT OUTER JOIN GroupAdmins ON GroupAdmins.admin = Accounts.account AND GroupAdmins.group_id = Transactions.tx_group_id "
|
||||
+ "WHERE Transactions.tx_group_id != ? AND GroupAdmins.admin IS NULL "
|
||||
+ "AND Transactions.type IN (" + txTypes + ") "
|
||||
+ "ORDER BY creation";
|
||||
|
@ -29,9 +29,9 @@ public class HSQLDBUpdateGroupTransactionRepository extends HSQLDBTransactionRep
|
||||
String newDescription = resultSet.getString(3);
|
||||
boolean newIsOpen = resultSet.getBoolean(4);
|
||||
ApprovalThreshold newApprovalThreshold = ApprovalThreshold.valueOf(resultSet.getInt(5));
|
||||
byte[] groupReference = resultSet.getBytes(6);
|
||||
int newMinBlockDelay = resultSet.getInt(7);
|
||||
int newMaxBlockDelay = resultSet.getInt(8);
|
||||
int newMinBlockDelay = resultSet.getInt(6);
|
||||
int newMaxBlockDelay = resultSet.getInt(7);
|
||||
byte[] groupReference = resultSet.getBytes(8);
|
||||
|
||||
return new UpdateGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, newOwner, newDescription, newIsOpen,
|
||||
newApprovalThreshold, newMinBlockDelay, newMaxBlockDelay, groupReference, fee, signature);
|
||||
|
@ -84,10 +84,6 @@ public class AddGroupAdminTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != addGroupAdminTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account owner = getOwner();
|
||||
|
||||
// Check transaction's public key matches group's current owner
|
||||
|
@ -28,10 +28,6 @@ public class BuyNameTransaction extends Transaction {
|
||||
super(repository, transactionData);
|
||||
|
||||
this.buyNameTransactionData = (BuyNameTransactionData) this.transactionData;
|
||||
|
||||
// XXX This is horrible - thanks to JAXB unmarshalling not calling constructor
|
||||
if (this.transactionData.getCreatorPublicKey() == null)
|
||||
this.transactionData.setCreatorPublicKey(this.buyNameTransactionData.getBuyerPublicKey());
|
||||
}
|
||||
|
||||
// More information
|
||||
|
@ -84,10 +84,6 @@ public class CancelGroupBanTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != groupUnbanTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Can't unban if not an admin
|
||||
|
@ -84,10 +84,6 @@ public class CancelGroupInviteTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != cancelGroupInviteTransactionData.getGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Check admin is actually an admin
|
||||
|
@ -28,10 +28,6 @@ public class CancelSellNameTransaction extends Transaction {
|
||||
super(repository, transactionData);
|
||||
|
||||
this.cancelSellNameTransactionData = (CancelSellNameTransactionData) this.transactionData;
|
||||
|
||||
// XXX This is horrible - thanks to JAXB unmarshalling not calling constructor
|
||||
if (this.transactionData.getCreatorPublicKey() == null)
|
||||
this.transactionData.setCreatorPublicKey(this.cancelSellNameTransactionData.getOwnerPublicKey());
|
||||
}
|
||||
|
||||
// More information
|
||||
|
@ -69,10 +69,6 @@ public class GroupApprovalTransaction extends Transaction {
|
||||
if (pendingTransactionData == null)
|
||||
return ValidationResult.TRANSACTION_UNKNOWN;
|
||||
|
||||
// Check pending transaction's groupID matches our transaction's groupID
|
||||
if (groupApprovalTransactionData.getTxGroupId() != pendingTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
// Check pending transaction is not already in a block
|
||||
if (this.repository.getTransactionRepository().getHeightFromSignature(groupApprovalTransactionData.getPendingSignature()) != 0)
|
||||
return ValidationResult.TRANSACTION_ALREADY_CONFIRMED;
|
||||
@ -80,7 +76,7 @@ public class GroupApprovalTransaction extends Transaction {
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Can't cast approval decision if not an admin
|
||||
if (!this.repository.getGroupRepository().adminExists(groupApprovalTransactionData.getTxGroupId(), admin.getAddress()))
|
||||
if (!this.repository.getGroupRepository().adminExists(pendingTransactionData.getTxGroupId(), admin.getAddress()))
|
||||
return ValidationResult.NOT_GROUP_ADMIN;
|
||||
|
||||
// Check fee is positive
|
||||
|
@ -84,10 +84,6 @@ public class GroupBanTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != groupBanTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Can't ban if not an admin
|
||||
|
@ -75,10 +75,6 @@ public class GroupInviteTransaction extends Transaction {
|
||||
public ValidationResult isValid() throws DataException {
|
||||
int groupId = groupInviteTransactionData.getGroupId();
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupInviteTransactionData.getTxGroupId() != groupId)
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
// Check time to live zero (infinite) or positive
|
||||
if (groupInviteTransactionData.getTimeToLive() < 0)
|
||||
return ValidationResult.INVALID_LIFETIME;
|
||||
|
@ -87,10 +87,6 @@ public class GroupKickTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != groupKickTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account admin = getAdmin();
|
||||
|
||||
// Can't kick if not an admin
|
||||
|
@ -32,10 +32,6 @@ public class IssueAssetTransaction extends Transaction {
|
||||
super(repository, transactionData);
|
||||
|
||||
this.issueAssetTransactionData = (IssueAssetTransactionData) this.transactionData;
|
||||
|
||||
// XXX This is horrible - thanks to JAXB unmarshalling not calling constructor
|
||||
if (this.transactionData.getCreatorPublicKey() == null)
|
||||
this.transactionData.setCreatorPublicKey(this.issueAssetTransactionData.getIssuerPublicKey());
|
||||
}
|
||||
|
||||
// More information
|
||||
|
@ -67,11 +67,6 @@ public class JoinGroupTransaction extends Transaction {
|
||||
public ValidationResult isValid() throws DataException {
|
||||
int groupId = joinGroupTransactionData.getGroupId();
|
||||
|
||||
// Check txGroupId
|
||||
int txGroupId = joinGroupTransactionData.getTxGroupId();
|
||||
if (txGroupId != Group.NO_GROUP && txGroupId != groupId)
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
// Check group exists
|
||||
if (!this.repository.getGroupRepository().groupExists(groupId))
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
@ -72,10 +72,6 @@ public class LeaveGroupTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != leaveGroupTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account leaver = getLeaver();
|
||||
|
||||
// Can't leave if group owner
|
||||
|
@ -26,10 +26,6 @@ public class PaymentTransaction extends Transaction {
|
||||
super(repository, transactionData);
|
||||
|
||||
this.paymentTransactionData = (PaymentTransactionData) this.transactionData;
|
||||
|
||||
// XXX This is horrible - thanks to JAXB unmarshalling not calling constructor
|
||||
if (this.transactionData.getCreatorPublicKey() == null)
|
||||
this.transactionData.setCreatorPublicKey(this.paymentTransactionData.getSenderPublicKey());
|
||||
}
|
||||
|
||||
// More information
|
||||
|
@ -28,10 +28,6 @@ public class RegisterNameTransaction extends Transaction {
|
||||
super(repository, transactionData);
|
||||
|
||||
this.registerNameTransactionData = (RegisterNameTransactionData) this.transactionData;
|
||||
|
||||
// XXX This is horrible - thanks to JAXB unmarshalling not calling constructor
|
||||
if (this.transactionData.getCreatorPublicKey() == null)
|
||||
this.transactionData.setCreatorPublicKey(this.registerNameTransactionData.getRegistrantPublicKey());
|
||||
}
|
||||
|
||||
// More information
|
||||
|
@ -84,10 +84,6 @@ public class RemoveGroupAdminTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != removeGroupAdminTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
|
||||
Account owner = getOwner();
|
||||
|
||||
// Check transaction's public key matches group's current owner
|
||||
|
@ -29,10 +29,6 @@ public class SellNameTransaction extends Transaction {
|
||||
super(repository, transactionData);
|
||||
|
||||
this.sellNameTransactionData = (SellNameTransactionData) this.transactionData;
|
||||
|
||||
// XXX This is horrible - thanks to JAXB unmarshalling not calling constructor
|
||||
if (this.transactionData.getCreatorPublicKey() == null)
|
||||
this.transactionData.setCreatorPublicKey(this.sellNameTransactionData.getOwnerPublicKey());
|
||||
}
|
||||
|
||||
// More information
|
||||
|
@ -185,6 +185,7 @@ public abstract class Transaction {
|
||||
TRANSACTION_UNKNOWN(65),
|
||||
TRANSACTION_ALREADY_CONFIRMED(66),
|
||||
INVALID_TX_GROUP_ID(67),
|
||||
TX_GROUP_ID_MISMATCH(68),
|
||||
NOT_YET_RELEASED(1000);
|
||||
|
||||
public final int value;
|
||||
@ -665,7 +666,7 @@ public abstract class Transaction {
|
||||
// Group no longer exists? Possibly due to blockchain orphaning undoing group creation?
|
||||
return true; // stops tx being included in block but it will eventually expire
|
||||
|
||||
// If transaction's creator is group admin then auto-approve
|
||||
// If transaction's creator is group admin (of group with ID txGroupId) then auto-approve
|
||||
PublicKeyAccount creator = this.getCreator();
|
||||
if (groupRepository.adminExists(txGroupId, creator.getAddress()))
|
||||
return false;
|
||||
|
@ -95,9 +95,9 @@ public class UpdateGroupTransaction extends Transaction {
|
||||
if (groupData == null)
|
||||
return ValidationResult.GROUP_DOES_NOT_EXIST;
|
||||
|
||||
// Check transaction's groupID matches group's ID
|
||||
if (groupData.getGroupId() != updateGroupTransactionData.getTxGroupId())
|
||||
return ValidationResult.GROUP_ID_MISMATCH;
|
||||
// As this transaction type could require approval, check txGroupId matches groupID at creation
|
||||
if (groupData.getCreationGroupId() != updateGroupTransactionData.getTxGroupId())
|
||||
return ValidationResult.TX_GROUP_ID_MISMATCH;
|
||||
|
||||
Account owner = getOwner();
|
||||
|
||||
|
@ -29,10 +29,6 @@ public class UpdateNameTransaction extends Transaction {
|
||||
super(repository, transactionData);
|
||||
|
||||
this.updateNameTransactionData = (UpdateNameTransactionData) this.transactionData;
|
||||
|
||||
// XXX This is horrible - thanks to JAXB unmarshalling not calling constructor
|
||||
if (this.transactionData.getCreatorPublicKey() == null)
|
||||
this.transactionData.setCreatorPublicKey(this.updateNameTransactionData.getOwnerPublicKey());
|
||||
}
|
||||
|
||||
// More information
|
||||
@ -104,6 +100,10 @@ public class UpdateNameTransaction extends Transaction {
|
||||
if (nameData == null)
|
||||
return ValidationResult.NAME_DOES_NOT_EXIST;
|
||||
|
||||
// As this transaction type could require approval, check txGroupId matches groupID at creation
|
||||
if (nameData.getCreationGroupId() != updateNameTransactionData.getTxGroupId())
|
||||
return ValidationResult.TX_GROUP_ID_MISMATCH;
|
||||
|
||||
// Check name isn't currently for sale
|
||||
if (nameData.getIsForSale())
|
||||
return ValidationResult.NAME_ALREADY_FOR_SALE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user