mirror of
				https://github.com/Qortal/qortal.git
				synced 2025-10-30 17:47:04 +00:00 
			
		
		
		
	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:
		| @@ -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) { | ||||
|   | ||||
| @@ -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); | ||||
| 						} | ||||
|  | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -167,6 +167,7 @@ | ||||
| 		"arbitraryTimestamp": "1405702800000", | ||||
| 		"powfixTimestamp": "1456426800000", | ||||
| 		"v2Timestamp": "1559347200000", | ||||
| 		"newAssetPricingTimestamp": "2000000000000" | ||||
| 		"newAssetPricingTimestamp": "2000000000000", | ||||
| 		"groupApprovalTimestamp": "2000000000000" | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user