diff --git a/core/src/main/java/com/google/bitcoin/core/Peer.java b/core/src/main/java/com/google/bitcoin/core/Peer.java index 9f882441..deb028cf 100644 --- a/core/src/main/java/com/google/bitcoin/core/Peer.java +++ b/core/src/main/java/com/google/bitcoin/core/Peer.java @@ -448,6 +448,8 @@ public class Peer { } private void processTransaction(Transaction tx) throws VerificationException, IOException { + // Check a few basic syntax issues to ensure the received TX isn't nonsense. + tx.verify(); lock.lock(); try { log.debug("{}: Received tx {}", vAddress, tx.getHashAsString()); diff --git a/core/src/main/java/com/google/bitcoin/core/Wallet.java b/core/src/main/java/com/google/bitcoin/core/Wallet.java index 0a052092..42035332 100644 --- a/core/src/main/java/com/google/bitcoin/core/Wallet.java +++ b/core/src/main/java/com/google/bitcoin/core/Wallet.java @@ -883,6 +883,7 @@ public class Wallet implements Serializable, BlockChainListener { // Do a brief risk analysis of the transaction and its dependencies to check for any possible attacks. lock.lock(); try { + tx.verify(); // Repeat the check of relevancy here, even though the caller may have already done so - this is to avoid // race conditions where receivePending may be being called in parallel. if (!isPendingTransactionRelevant(tx)) @@ -1440,6 +1441,7 @@ public class Wallet implements Serializable, BlockChainListener { *

Triggers an auto save.

*/ public void commitTx(Transaction tx) throws VerificationException { + tx.verify(); lock.lock(); try { checkArgument(!pending.containsKey(tx.getHash()), "commitTx called on the same transaction twice"); diff --git a/core/src/test/java/com/google/bitcoin/core/PeerTest.java b/core/src/test/java/com/google/bitcoin/core/PeerTest.java index 6935369b..f94a3ab4 100644 --- a/core/src/test/java/com/google/bitcoin/core/PeerTest.java +++ b/core/src/test/java/com/google/bitcoin/core/PeerTest.java @@ -786,9 +786,12 @@ public class PeerTest extends TestWithNetworkConnections { connect(); Transaction t1 = new Transaction(unitTestParams); t1.addInput(new TransactionInput(unitTestParams, t1, new byte[]{})); - t1.addOutput(Utils.toNanoCoins(1, 0), wallet.getChangeAddress()); - inbound(peer, t1); - inbound(peer, new NotFoundMessage(unitTestParams, Lists.newArrayList(new InventoryItem(InventoryItem.Type.Transaction, t1.getInput(0).getHash())))); + t1.addOutput(Utils.toNanoCoins(1, 0), new ECKey().toAddress(unitTestParams)); + Transaction t2 = new Transaction(unitTestParams); + t2.addInput(t1.getOutput(0)); + t2.addOutput(Utils.toNanoCoins(1, 0), wallet.getChangeAddress()); + inbound(peer, t2); + inbound(peer, new NotFoundMessage(unitTestParams, Lists.newArrayList(new InventoryItem(InventoryItem.Type.Transaction, t2.getInput(0).getHash())))); assertTrue(throwables[0] instanceof NullPointerException); }