]> Git Repo - VerusCoin.git/commitdiff
Additional testing of -mempooltxinputlimit
authorJack Grigg <[email protected]>
Tue, 20 Jun 2017 03:58:46 +0000 (15:58 +1200)
committerJack Grigg <[email protected]>
Tue, 20 Jun 2017 03:58:46 +0000 (15:58 +1200)
qa/pull-tester/rpc-tests.sh
qa/rpc-tests/mempool_tx_input_limit.py [new file with mode: 0755]
src/gtest/test_mempool.cpp

index 08ff3fe7adcf257292c0d16ebef06f90da9e1b37..99706f1789b95a1814f3faf985ebcfbb785a7b31 100755 (executable)
@@ -26,6 +26,7 @@ testScripts=(
     'rest.py'
     'mempool_spendcoinbase.py'
     'mempool_coinbase_spends.py'
+    'mempool_tx_input_limit.py'
     'httpbasics.py'
     'zapwallettxes.py'
     'proxy_test.py'
diff --git a/qa/rpc-tests/mempool_tx_input_limit.py b/qa/rpc-tests/mempool_tx_input_limit.py
new file mode 100755 (executable)
index 0000000..ed0bf20
--- /dev/null
@@ -0,0 +1,138 @@
+#!/usr/bin/env python2
+# Copyright (c) 2017 The Zcash developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os
+import shutil
+from time import sleep
+
+# Create one-input, one-output, no-fee transaction:
+class MempoolTxInputLimitTest(BitcoinTestFramework):
+
+    alert_filename = None  # Set by setup_network
+
+    def setup_network(self):
+        args = ["-checkmempool", "-debug=mempool", "-mempooltxinputlimit=2"]
+        self.nodes = []
+        self.nodes.append(start_node(0, self.options.tmpdir, args))
+        self.nodes.append(start_node(1, self.options.tmpdir, args))
+        connect_nodes(self.nodes[1], 0)
+        self.is_network_split = False
+        self.sync_all
+
+    def setup_chain(self):
+        print "Initializing test directory "+self.options.tmpdir
+        initialize_chain_clean(self.options.tmpdir, 2)
+
+    def call_z_sendmany(self, from_addr, to_addr, amount):
+        recipients = []
+        recipients.append({"address": to_addr, "amount": amount})
+        myopid = self.nodes[0].z_sendmany(from_addr, recipients)
+
+        opids = []
+        opids.append(myopid)
+
+        timeout = 120
+        status = None
+        for x in xrange(1, timeout):
+            results = self.nodes[0].z_getoperationresult(opids)
+            if len(results)==0:
+                sleep(1)
+            else:
+                status = results[0]["status"]
+                assert_equal("success", status)
+                return results[0]["result"]["txid"]
+
+    def run_test(self):
+        start_count = self.nodes[0].getblockcount()
+
+        self.nodes[0].generate(100)
+        self.sync_all()
+        # Mine three blocks. After this, nodes[0] blocks
+        # 1, 2, and 3 are spend-able.
+        self.nodes[1].generate(3)
+        self.sync_all()
+
+        # Check 1: z_sendmany is limited by -mempooltxinputlimit
+
+        # Add zaddr to node 0
+        node0_zaddr = self.nodes[0].z_getnewaddress()
+
+        # Send three inputs from node 0 taddr to zaddr to get out of coinbase
+        node0_taddr = self.nodes[0].getnewaddress();
+        recipients = []
+        recipients.append({"address":node0_zaddr, "amount":Decimal('30.0')-Decimal('0.0001')}) # utxo amount less fee
+        myopid = self.nodes[0].z_sendmany(node0_taddr, recipients)
+
+        opids = []
+        opids.append(myopid)
+
+        # Spend should fail due to -mempooltxinputlimit
+        timeout = 120
+        status = None
+        for x in xrange(1, timeout):
+            results = self.nodes[0].z_getoperationresult(opids)
+            if len(results)==0:
+                sleep(1)
+            else:
+                status = results[0]["status"]
+                msg = results[0]["error"]["message"]
+                assert_equal("failed", status)
+                assert_equal("Too many transparent inputs 3 > limit 2", msg)
+                break
+
+        # Mempool should be empty.
+        assert_equal(set(self.nodes[0].getrawmempool()), set())
+
+        # Reduce amount to only use two inputs
+        spend_zaddr_amount = Decimal('20.0') - Decimal('0.0001')
+        spend_zaddr_id = self.call_z_sendmany(node0_taddr, node0_zaddr, spend_zaddr_amount) # utxo amount less fee
+        self.sync_all()
+
+        # Spend should be in the mempool
+        assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_zaddr_id ]))
+
+        self.nodes[0].generate(1)
+        self.sync_all()
+
+        # mempool should be empty.
+        assert_equal(set(self.nodes[0].getrawmempool()), set())
+
+        # Check 2: sendfrom is limited by -mempooltxinputlimit
+        node1_taddr = self.nodes[1].getnewaddress();
+        recipients = []
+        spend_taddr_amount = spend_zaddr_amount - Decimal('0.0001')
+        spend_taddr_output = Decimal('8')
+        # Create three outputs
+        self.call_z_sendmany(node0_zaddr, node1_taddr, spend_taddr_output - Decimal('0.0001'))
+        self.nodes[1].generate(1)
+        self.sync_all()
+        self.call_z_sendmany(node0_zaddr, node1_taddr, spend_taddr_output - Decimal('0.0001'))
+        self.nodes[1].generate(1)
+        self.sync_all()
+        self.call_z_sendmany(node0_zaddr, node1_taddr, spend_taddr_amount - spend_taddr_output - spend_taddr_output - Decimal('0.0001')) # note amount less fees
+        self.nodes[1].generate(1)
+        self.sync_all()
+
+        # Should use three UTXOs and fail
+        try:
+            self.nodes[1].sendtoaddress(node0_taddr, spend_taddr_amount - Decimal('1'))
+            assert(False)
+        except JSONRPCException,e:
+            msg = e.error['message']
+            assert_equal("Too many transparent inputs 3 > limit 2", msg)
+
+        # mempool should be empty.
+        assert_equal(set(self.nodes[1].getrawmempool()), set())
+
+        # Should use two UTXOs and succeed
+        spend_taddr_id2 = self.nodes[1].sendtoaddress(node0_taddr, spend_taddr_output + spend_taddr_output - Decimal('1'))
+
+        # Spend should be in the mempool
+        assert_equal(set(self.nodes[1].getrawmempool()), set([ spend_taddr_id2 ]))
+
+if __name__ == '__main__':
+    MempoolTxInputLimitTest().main()
index e84b2deadcfef0cf37a17f73c2ecd9518ba3c5b5..14b4d83b1054f572b0b9ca011c4d1c8d09708c81 100644 (file)
@@ -96,6 +96,9 @@ TEST(Mempool, TxInputLimit) {
     bool missingInputs;
 
     // Create an obviously-invalid transaction
+    // We intentionally set tx.nVersion = 0 to reliably trigger an error, as
+    // it's the first check that occurs after the -mempooltxinputlimit check,
+    // and it means that we don't have to mock out a lot of global state.
     CMutableTransaction mtx;
     mtx.nVersion = 0;
     mtx.vin.resize(10);
@@ -121,7 +124,8 @@ TEST(Mempool, TxInputLimit) {
     CValidationState state3;
     CTransaction tx3(mtx);
     EXPECT_FALSE(AcceptToMemoryPool(pool, state3, tx3, false, &missingInputs));
-    EXPECT_NE(state3.GetRejectReason(), "bad-txns-version-too-low");
+    // The -mempooltxinputlimit check doesn't set a reason
+    EXPECT_EQ(state3.GetRejectReason(), "");
 
     // Clear the limit
     mapArgs.erase("-mempooltxinputlimit");
This page took 0.029882 seconds and 4 git commands to generate.