From 344be21821bff13dc9073d35ed6a9014a2ba0437 Mon Sep 17 00:00:00 2001 From: Andreas Schildbach Date: Wed, 28 May 2014 15:31:22 +0200 Subject: [PATCH] Fix 'shortest possible pushdata' logic for transaction inputs. Also add a testcase. --- .../bitcoin/wallet/DefaultRiskAnalysis.java | 2 +- .../wallet/DefaultRiskAnalysisTest.java | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/bitcoin/wallet/DefaultRiskAnalysis.java b/core/src/main/java/com/google/bitcoin/wallet/DefaultRiskAnalysis.java index 636db5bce..28c71c55b 100644 --- a/core/src/main/java/com/google/bitcoin/wallet/DefaultRiskAnalysis.java +++ b/core/src/main/java/com/google/bitcoin/wallet/DefaultRiskAnalysis.java @@ -144,7 +144,7 @@ public class DefaultRiskAnalysis implements RiskAnalysis { for (int i = 0; i < inputs.size(); i++) { TransactionInput input = inputs.get(i); for (ScriptChunk chunk : input.getScriptSig().getChunks()) { - if (chunk.data != null && chunk.isShortestPossiblePushData()) { + if (chunk.data != null && !chunk.isShortestPossiblePushData()) { log.warn("TX considered non-standard due to input {} having a longer than necessary data push: {}", i, chunk); return RuleViolation.SHORTEST_POSSIBLE_PUSHDATA; diff --git a/core/src/test/java/com/google/bitcoin/wallet/DefaultRiskAnalysisTest.java b/core/src/test/java/com/google/bitcoin/wallet/DefaultRiskAnalysisTest.java index ce0cb9d8d..9b2ff3509 100644 --- a/core/src/test/java/com/google/bitcoin/wallet/DefaultRiskAnalysisTest.java +++ b/core/src/test/java/com/google/bitcoin/wallet/DefaultRiskAnalysisTest.java @@ -21,10 +21,13 @@ import java.math.BigInteger; import com.google.bitcoin.core.*; import com.google.bitcoin.params.MainNetParams; +import com.google.bitcoin.script.ScriptBuilder; +import com.google.bitcoin.script.ScriptChunk; import com.google.common.collect.ImmutableList; import org.junit.Before; import org.junit.Test; +import static com.google.bitcoin.script.ScriptOpCodes.OP_PUSHDATA1; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; @@ -141,4 +144,20 @@ public class DefaultRiskAnalysisTest { edgeCaseTx.addOutput(DefaultRiskAnalysis.MIN_ANALYSIS_NONDUST_OUTPUT, key1); // Dust threshold assertEquals(RiskAnalysis.Result.OK, DefaultRiskAnalysis.FACTORY.create(wallet, edgeCaseTx, NO_DEPS).analyze()); } + + @Test + public void nonShortestPossiblePushData() { + ScriptChunk nonStandardChunk = new ScriptChunk(OP_PUSHDATA1, new byte[75]); + byte[] nonStandardScript = new ScriptBuilder().addChunk(nonStandardChunk).build().getProgram(); + // Test non-standard script as an input. + Transaction tx = new Transaction(params); + assertEquals(DefaultRiskAnalysis.RuleViolation.NONE, DefaultRiskAnalysis.isStandard(tx)); + tx.addInput(new TransactionInput(params, null, nonStandardScript)); + assertEquals(DefaultRiskAnalysis.RuleViolation.SHORTEST_POSSIBLE_PUSHDATA, DefaultRiskAnalysis.isStandard(tx)); + // Test non-standard script as an output. + tx.clearInputs(); + assertEquals(DefaultRiskAnalysis.RuleViolation.NONE, DefaultRiskAnalysis.isStandard(tx)); + tx.addOutput(new TransactionOutput(params, null, Utils.COIN, nonStandardScript)); + assertEquals(DefaultRiskAnalysis.RuleViolation.SHORTEST_POSSIBLE_PUSHDATA, DefaultRiskAnalysis.isStandard(tx)); + } }