Unify setting Transaction's initial group-approval status.

Refactored duplicate code into Transaction.setInitialApprovalStatus().

This is make sure transactions HAVE a group-approval status
in Synchronizer before Block.isValid is called.

This wasn't a problem for new, unconfirmed, individual transactions
arriving over the wire due to Transaction.importAsUnconfirmed()
doing the right thing.

Also added a groupApprovalTimestamp to BlockChain feature-triggers
to support legacy chains.

Tested by syncing mainnet from scratch.
This commit is contained in:
catbref 2019-07-02 11:37:03 +01:00
parent ad827ae01d
commit 192a072796
4 changed files with 27 additions and 18 deletions

View File

@ -78,7 +78,8 @@ public class BlockChain {
arbitraryTimestamp,
powfixTimestamp,
v2Timestamp,
newAssetPricingTimestamp;
newAssetPricingTimestamp,
groupApprovalTimestamp;
}
/** Map of which blockchain features are enabled when (height/timestamp) */
@ -299,6 +300,10 @@ public class BlockChain {
return featureTriggers.get("newAssetPricingTimestamp");
}
public long getGroupApprovalTimestamp() {
return featureTriggers.get("groupApprovalTimestamp");
}
// More complex getters for aspects that change by height or timestamp
public BigDecimal getRewardAtHeight(int ourHeight) {

View File

@ -26,7 +26,6 @@ import org.qora.repository.DataException;
import org.qora.repository.Repository;
import org.qora.repository.RepositoryManager;
import org.qora.transaction.Transaction;
import org.qora.transaction.Transaction.ApprovalStatus;
public class Synchronizer {
@ -252,6 +251,10 @@ public class Synchronizer {
return SynchronizationResult.INVALID_DATA;
}
// Transactions are transmitted without approval status so determine that now
for (Transaction transaction : newBlock.getTransactions())
transaction.setInitialApprovalStatus();
ValidationResult blockResult = newBlock.isValid();
if (blockResult != ValidationResult.OK) {
LOGGER.info(String.format("Peer %s sent invalid block for height %d: %s", peer, ourHeight, blockResult.name()));
@ -261,14 +264,6 @@ public class Synchronizer {
// Save transactions attached to this block
for (Transaction transaction : newBlock.getTransactions()) {
TransactionData transactionData = transaction.getTransactionData();
// Fix up approval status
if (transaction.needsGroupApproval()) {
transactionData.setApprovalStatus(ApprovalStatus.PENDING);
} else {
transactionData.setApprovalStatus(ApprovalStatus.NOT_REQUIRED);
}
repository.getTransactionRepository().save(transactionData);
}

View File

@ -778,6 +778,10 @@ public abstract class Transaction {
if (!this.transactionData.getType().needsApproval)
return false;
// Is group-approval even in effect yet?
if (this.transactionData.getTimestamp() < BlockChain.getInstance().getGroupApprovalTimestamp())
return false;
int txGroupId = this.transactionData.getTxGroupId();
if (txGroupId == Group.NO_GROUP)
@ -797,6 +801,14 @@ public abstract class Transaction {
return true;
}
public void setInitialApprovalStatus() throws DataException {
if (this.needsGroupApproval()) {
transactionData.setApprovalStatus(ApprovalStatus.PENDING);
} else {
transactionData.setApprovalStatus(ApprovalStatus.NOT_REQUIRED);
}
}
public Boolean getApprovalDecision() throws DataException {
// Grab latest decisions from repository
GroupApprovalData groupApprovalData = this.repository.getTransactionRepository().getApprovalData(this.transactionData.getSignature());
@ -841,17 +853,13 @@ public abstract class Transaction {
if (repository.getTransactionRepository().exists(transactionData.getSignature()))
return ValidationResult.TRANSACTION_ALREADY_EXISTS;
// Fix up approval status
this.setInitialApprovalStatus();
ValidationResult validationResult = this.isValidUnconfirmed();
if (validationResult != ValidationResult.OK)
return validationResult;
// Fix up approval status
if (this.needsGroupApproval()) {
transactionData.setApprovalStatus(ApprovalStatus.PENDING);
} else {
transactionData.setApprovalStatus(ApprovalStatus.NOT_REQUIRED);
}
repository.getTransactionRepository().save(transactionData);
repository.getTransactionRepository().unconfirmTransaction(transactionData);
repository.saveChanges();

View File

@ -167,6 +167,7 @@
"arbitraryTimestamp": "1405702800000",
"powfixTimestamp": "1456426800000",
"v2Timestamp": "1559347200000",
"newAssetPricingTimestamp": "2000000000000"
"newAssetPricingTimestamp": "2000000000000",
"groupApprovalTimestamp": "2000000000000"
}
}