From da1bd82c19faf3e9675e1feb8bfefb1650abe6de Mon Sep 17 00:00:00 2001 From: catbref Date: Sat, 1 Jun 2019 10:45:07 +0100 Subject: [PATCH] Minor integration progress Remove fetching unconfirmed from Synchronizer Add extra validity/reference/processable checks to Transaction.isValidUnconfirmed Update TransactionUtils to use Transaction.importAsUnconfirmed for unit tests. --- .../org/qora/controller/Synchronizer.java | 58 ------------------- .../org/qora/transaction/Transaction.java | 19 +++++- .../qora/test/common/TransactionUtils.java | 4 +- 3 files changed, 19 insertions(+), 62 deletions(-) diff --git a/src/main/java/org/qora/controller/Synchronizer.java b/src/main/java/org/qora/controller/Synchronizer.java index abdfaa21..9e848272 100644 --- a/src/main/java/org/qora/controller/Synchronizer.java +++ b/src/main/java/org/qora/controller/Synchronizer.java @@ -13,8 +13,6 @@ import org.qora.block.BlockChain; import org.qora.block.GenesisBlock; import org.qora.data.block.BlockData; import org.qora.data.network.BlockSummaryData; -import org.qora.data.transaction.GroupApprovalTransactionData; -import org.qora.data.transaction.TransactionData; import org.qora.network.Peer; import org.qora.network.message.BlockMessage; import org.qora.network.message.BlockSummariesMessage; @@ -22,17 +20,13 @@ import org.qora.network.message.GetBlockMessage; import org.qora.network.message.GetBlockSummariesMessage; import org.qora.network.message.GetSignaturesMessage; import org.qora.network.message.GetSignaturesV2Message; -import org.qora.network.message.GetTransactionMessage; import org.qora.network.message.Message; import org.qora.network.message.Message.MessageType; import org.qora.network.message.SignaturesMessage; -import org.qora.network.message.TransactionMessage; 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.TransactionType; -import org.qora.utils.Base58; import org.qora.utils.NTP; public class Synchronizer { @@ -237,46 +231,6 @@ public class Synchronizer { return SynchronizationResult.NO_REPLY; } - // If block contains GROUP_APPROVAL transactions then we need to make sure we have the relevant pending transactions too - for (Transaction transaction : newBlock.getTransactions()) { - TransactionData transactionData = transaction.getTransactionData(); - - if (transactionData.getType() != TransactionType.GROUP_APPROVAL) - continue; - - GroupApprovalTransactionData groupApprovalTransactionData = (GroupApprovalTransactionData) transactionData; - - byte[] pendingSignature = groupApprovalTransactionData.getPendingSignature(); - - if (repository.getTransactionRepository().exists(pendingSignature)) - continue; - - LOGGER.debug(String.format("Fetching unknown approval-pending transaction %s from peer %s, needed for block at height %d", Base58.encode(pendingSignature), peer, ourHeight)); - - TransactionData pendingTransactionData = this.fetchTransaction(peer, pendingSignature); - if (pendingTransactionData == null) { - LOGGER.info(String.format("Peer %s failed to respond with pending transaction %s", peer, Base58.encode(pendingSignature))); - return SynchronizationResult.NO_REPLY; - } - - // Check the signature is valid at least! - Transaction pendingTransaction = Transaction.fromData(repository, pendingTransactionData); - if (!pendingTransaction.isSignatureValid()) { - LOGGER.info(String.format("Peer %s sent pending transaction %s with invalid signature", peer, Base58.encode(pendingSignature))); - return SynchronizationResult.INVALID_DATA; - } - - Transaction.ValidationResult transactionResult = pendingTransaction.isValidUnconfirmed(); - if (transactionResult != Transaction.ValidationResult.OK) { - LOGGER.info(String.format("Peer %s sent invalid (%s) pending transaction %s", peer, transactionResult.name(), Base58.encode(pendingSignature))); - return SynchronizationResult.INVALID_DATA; - } - - // Add to our unconfirmed pile - this.repository.getTransactionRepository().save(pendingTransactionData); - this.repository.getTransactionRepository().unconfirmTransaction(pendingTransactionData); - } - if (!newBlock.isSignatureValid()) { LOGGER.info(String.format("Peer %s sent block with invalid signature for height %d", peer, ourHeight)); return SynchronizationResult.INVALID_DATA; @@ -437,16 +391,4 @@ public class Synchronizer { } } - private TransactionData fetchTransaction(Peer peer, byte[] signature) { - Message getTransactionMessage = new GetTransactionMessage(signature); - - Message message = peer.getResponse(getTransactionMessage); - if (message == null || message.getType() != MessageType.TRANSACTION) - return null; - - TransactionMessage transactionMessage = (TransactionMessage) message; - - return transactionMessage.getTransactionData(); - } - } diff --git a/src/main/java/org/qora/transaction/Transaction.java b/src/main/java/org/qora/transaction/Transaction.java index e1bf6245..409dbca5 100644 --- a/src/main/java/org/qora/transaction/Transaction.java +++ b/src/main/java/org/qora/transaction/Transaction.java @@ -548,7 +548,17 @@ public abstract class Transaction { if (unconfirmedLastReference != null) creator.setLastReference(unconfirmedLastReference); + // Check transaction is valid ValidationResult result = this.isValid(); + if (result != ValidationResult.OK) + return result; + + // Check transaction references + if (!this.hasValidReference()) + return ValidationResult.INVALID_REFERENCE; + + // Check transction is processable + result = this.isProcessable(); return result; } finally { @@ -807,7 +817,13 @@ public abstract class Transaction { return null; } - /** Import into our repository as a new, unconfirmed transaction. */ + /** + * Import into our repository as a new, unconfirmed transaction. + *

+ * Calls repository.saveChanges() + * + * @throws DataException + */ public void importAsUnconfirmed() throws DataException { // Fix up approval status if (this.needsGroupApproval()) { @@ -829,6 +845,7 @@ public abstract class Transaction { * Transactions that have already been processed will return false. * * @return true if transaction can be processed, false otherwise + * @throws DataException */ public abstract ValidationResult isValid() throws DataException; diff --git a/src/test/java/org/qora/test/common/TransactionUtils.java b/src/test/java/org/qora/test/common/TransactionUtils.java index 31f99975..1debfa24 100644 --- a/src/test/java/org/qora/test/common/TransactionUtils.java +++ b/src/test/java/org/qora/test/common/TransactionUtils.java @@ -33,9 +33,7 @@ public class TransactionUtils { ValidationResult result = transaction.isValidUnconfirmed(); assertEquals("Transaction invalid", ValidationResult.OK, result); - repository.getTransactionRepository().save(transactionData); - repository.getTransactionRepository().unconfirmTransaction(transactionData); - repository.saveChanges(); + transaction.importAsUnconfirmed(); } public static void signAndForge(Repository repository, TransactionData transactionData, PrivateKeyAccount signingAccount) throws DataException {