Improve TRANSACTION_SIGNATURES handling in Controller.

Don't disconnect peers that fail to send a requested transaction,
as they may no longer have it. e.g. transaction might have expired
or become invalid.

For some other cases, e.g. we have transaction already, move on to
requesting the next transaction instead of giving up on the list.
This commit is contained in:
catbref 2019-06-17 10:30:57 +01:00
parent b48f671774
commit 5acc92ef26

View File

@ -738,15 +738,16 @@ public class Controller extends Thread {
// Do we have it already? (Before requesting transaction data itself) // Do we have it already? (Before requesting transaction data itself)
if (repository.getTransactionRepository().exists(signature)) { if (repository.getTransactionRepository().exists(signature)) {
LOGGER.trace(String.format("Ignoring existing transaction %s from peer %s", Base58.encode(signature), peer)); LOGGER.trace(String.format("Ignoring existing transaction %s from peer %s", Base58.encode(signature), peer));
break; continue;
} }
// Fetch actual transaction data from peer // Fetch actual transaction data from peer
Message getTransactionMessage = new GetTransactionMessage(signature); Message getTransactionMessage = new GetTransactionMessage(signature);
Message responseMessage = peer.getResponse(getTransactionMessage); Message responseMessage = peer.getResponse(getTransactionMessage);
if (responseMessage == null || !(responseMessage instanceof TransactionMessage)) { if (responseMessage == null || !(responseMessage instanceof TransactionMessage)) {
peer.disconnect("failed to fetch unconfirmed transaction"); // Maybe peer no longer has this transaction
break; LOGGER.trace(String.format("Peer %s didn't send transaction %s", peer, Base58.encode(signature)));
continue;
} }
TransactionMessage transactionMessage = (TransactionMessage) responseMessage; TransactionMessage transactionMessage = (TransactionMessage) responseMessage;
@ -756,24 +757,25 @@ public class Controller extends Thread {
// Check signature // Check signature
if (!transaction.isSignatureValid()) { if (!transaction.isSignatureValid()) {
LOGGER.trace(String.format("Ignoring %s transaction %s with invalid signature from peer %s", transactionData.getType().name(), Base58.encode(transactionData.getSignature()), peer)); LOGGER.trace(String.format("Ignoring %s transaction %s with invalid signature from peer %s", transactionData.getType().name(), Base58.encode(transactionData.getSignature()), peer));
break; continue;
} }
ValidationResult validationResult = transaction.importAsUnconfirmed(); ValidationResult validationResult = transaction.importAsUnconfirmed();
if (validationResult == ValidationResult.TRANSACTION_ALREADY_EXISTS) { if (validationResult == ValidationResult.TRANSACTION_ALREADY_EXISTS) {
LOGGER.trace(String.format("Ignoring existing transaction %s from peer %s", Base58.encode(transactionData.getSignature()), peer)); LOGGER.trace(String.format("Ignoring existing transaction %s from peer %s", Base58.encode(transactionData.getSignature()), peer));
break; continue;
} }
if (validationResult == ValidationResult.NO_BLOCKCHAIN_LOCK) { if (validationResult == ValidationResult.NO_BLOCKCHAIN_LOCK) {
LOGGER.trace(String.format("Couldn't lock blockchain to import unconfirmed transaction %s from peer %s", Base58.encode(transactionData.getSignature()), peer)); LOGGER.trace(String.format("Couldn't lock blockchain to import unconfirmed transaction %s from peer %s", Base58.encode(transactionData.getSignature()), peer));
// Some other thread (e.g. Synchronizer) might have blockchain lock for a while so might as well give up for now
break; break;
} }
if (validationResult != ValidationResult.OK) { if (validationResult != ValidationResult.OK) {
LOGGER.trace(String.format("Ignoring invalid (%s) %s transaction %s from peer %s", validationResult.name(), transactionData.getType().name(), Base58.encode(transactionData.getSignature()), peer)); LOGGER.trace(String.format("Ignoring invalid (%s) %s transaction %s from peer %s", validationResult.name(), transactionData.getType().name(), Base58.encode(transactionData.getSignature()), peer));
break; continue;
} }
LOGGER.debug(String.format("Imported %s transaction %s from peer %s", transactionData.getType().name(), Base58.encode(transactionData.getSignature()), peer)); LOGGER.debug(String.format("Imported %s transaction %s from peer %s", transactionData.getType().name(), Base58.encode(transactionData.getSignature()), peer));