diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-03-06 22:14:44 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-03-06 22:15:18 +0100 |
commit | cd5e4381d46d01ca8282f02a18515e7b61de1dde (patch) | |
tree | dfcb265d1bac859d8fa0ed46db45ac6073573330 /test/functional | |
parent | 12ac2f0d7129151ec4c49be4061575dacb9199d4 (diff) | |
parent | 1dfb4e7d753e9282c89d55bde358b8ad96d3bfc2 (diff) |
Merge #12479: RPC: Add child transactions to getrawmempool verbose output
1dfb4e7d7 [Tests] Check output of parent/child tx list from getrawmempool, getmempooldescendants, getmempoolancestors, and REST interface (Conor Scott)
fc44cb108 [RPC] Add list of child transactions to verbose output of getrawmempool (Conor Scott)
Pull request description:
`bitcoin-cli getrawmempool true` only lists a transaction's parents in the `depends` field. This change adds a `spentby` field to the json response, which lists the transaction's children in the mempool.
Currently the only way to find child transactions is to use `getrawmempool` or make another call to `getmempooldescendants` and search the response for transactions that list the parent_txid in the `depends` list, which is inefficient.
This change allows direct lookup of children.
Example Output
```
"9a9b5733c0d89f207908cfa3fe17809bee71f629aa095c9f8754524e29e98ba4": {
...other geterawmempool data...
"wtxid": "9a9b5733c0d89f207908cfa3fe17809bee71f629aa095c9f8754524e29e98ba4",
"depends": [
"bdd92851d5766a42aeb62af667bb422a116cab4e032bba5e3dd6efe5b4b40aa0"
],
"spentby": [
"dc5d3ec388a9121421208738a041ac30a22163bc2e17758f2275b6c51a15ba7b"
]
},
```
Tree-SHA512: 83da7d421c9799a40ef65af3b7fdb586d6d87385f3f2ede3afd2c311725444b858f9d91cc110422a0fa31905779934fee07211ca6fe6b746792b83692c94b3ce
Diffstat (limited to 'test/functional')
-rwxr-xr-x | test/functional/interface_rest.py | 4 | ||||
-rwxr-xr-x | test/functional/mempool_packages.py | 46 |
2 files changed, 46 insertions, 4 deletions
diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py index 3e87f6d33f..8440f13a0d 100755 --- a/test/functional/interface_rest.py +++ b/test/functional/interface_rest.py @@ -296,8 +296,10 @@ class RESTTest (BitcoinTestFramework): # check that there are our submitted transactions in the TX memory pool json_string = http_get_call(url.hostname, url.port, '/rest/mempool/contents'+self.FORMAT_SEPARATOR+'json') json_obj = json.loads(json_string) - for tx in txs: + for i, tx in enumerate(txs): assert_equal(tx in json_obj, True) + assert_equal(json_obj[tx]['spentby'], txs[i+1:i+2]) + assert_equal(json_obj[tx]['depends'], txs[i-1:i]) # now mine the transactions newblockhash = self.nodes[1].generate(1) diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py index 23797d83db..8880db8002 100755 --- a/test/functional/mempool_packages.py +++ b/test/functional/mempool_packages.py @@ -47,7 +47,7 @@ class MempoolPackagesTest(BitcoinTestFramework): value = sent_value chain.append(txid) - # Check mempool has MAX_ANCESTORS transactions in it, and descendant + # Check mempool has MAX_ANCESTORS transactions in it, and descendant and ancestor # count and fees should look correct mempool = self.nodes[0].getrawmempool(True) assert_equal(len(mempool), MAX_ANCESTORS) @@ -55,6 +55,10 @@ class MempoolPackagesTest(BitcoinTestFramework): descendant_fees = 0 descendant_size = 0 + ancestor_size = sum([mempool[tx]['size'] for tx in mempool]) + ancestor_count = MAX_ANCESTORS + ancestor_fees = sum([mempool[tx]['fee'] for tx in mempool]) + descendants = [] ancestors = list(chain) for x in reversed(chain): @@ -71,14 +75,43 @@ class MempoolPackagesTest(BitcoinTestFramework): assert_equal(mempool[x]['descendantsize'], descendant_size) descendant_count += 1 + # Check that ancestor calculations are correct + assert_equal(mempool[x]['ancestorcount'], ancestor_count) + assert_equal(mempool[x]['ancestorfees'], ancestor_fees * COIN) + assert_equal(mempool[x]['ancestorsize'], ancestor_size) + ancestor_size -= mempool[x]['size'] + ancestor_fees -= mempool[x]['fee'] + ancestor_count -= 1 + + # Check that parent/child list is correct + assert_equal(mempool[x]['spentby'], descendants[-1:]) + assert_equal(mempool[x]['depends'], ancestors[-2:-1]) + # Check that getmempooldescendants is correct assert_equal(sorted(descendants), sorted(self.nodes[0].getmempooldescendants(x))) + + # Check getmempooldescendants verbose output is correct + for descendant, dinfo in self.nodes[0].getmempooldescendants(x, True).items(): + assert_equal(dinfo['depends'], [chain[chain.index(descendant)-1]]) + if dinfo['descendantcount'] > 1: + assert_equal(dinfo['spentby'], [chain[chain.index(descendant)+1]]) + else: + assert_equal(dinfo['spentby'], []) descendants.append(x) # Check that getmempoolancestors is correct ancestors.remove(x) assert_equal(sorted(ancestors), sorted(self.nodes[0].getmempoolancestors(x))) + # Check that getmempoolancestors verbose output is correct + for ancestor, ainfo in self.nodes[0].getmempoolancestors(x, True).items(): + assert_equal(ainfo['spentby'], [chain[chain.index(ancestor)+1]]) + if ainfo['ancestorcount'] > 1: + assert_equal(ainfo['depends'], [chain[chain.index(ancestor)-1]]) + else: + assert_equal(ainfo['depends'], []) + + # Check that getmempoolancestors/getmempooldescendants correctly handle verbose=true v_ancestors = self.nodes[0].getmempoolancestors(chain[-1], True) assert_equal(len(v_ancestors), len(chain)-1) @@ -100,7 +133,7 @@ class MempoolPackagesTest(BitcoinTestFramework): for x in chain: ancestor_fees += mempool[x]['fee'] assert_equal(mempool[x]['ancestorfees'], ancestor_fees * COIN + 1000) - + # Undo the prioritisetransaction for later tests self.nodes[0].prioritisetransaction(txid=chain[0], fee_delta=-1000) @@ -149,6 +182,7 @@ class MempoolPackagesTest(BitcoinTestFramework): vout = utxo[1]['vout'] transaction_package = [] + tx_children = [] # First create one parent tx with 10 children (txid, sent_value) = self.chain_transaction(self.nodes[0], txid, vout, value, fee, 10) parent_transaction = txid @@ -159,11 +193,17 @@ class MempoolPackagesTest(BitcoinTestFramework): for i in range(MAX_DESCENDANTS - 1): utxo = transaction_package.pop(0) (txid, sent_value) = self.chain_transaction(self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) + if utxo['txid'] is parent_transaction: + tx_children.append(txid) for j in range(10): transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) mempool = self.nodes[0].getrawmempool(True) assert_equal(mempool[parent_transaction]['descendantcount'], MAX_DESCENDANTS) + assert_equal(sorted(mempool[parent_transaction]['spentby']), sorted(tx_children)) + + for child in tx_children: + assert_equal(mempool[child]['depends'], [parent_transaction]) # Sending one more chained transaction will fail utxo = transaction_package.pop(0) @@ -232,7 +272,7 @@ class MempoolPackagesTest(BitcoinTestFramework): signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx) txid = self.nodes[0].sendrawtransaction(signedtx['hex']) sync_mempools(self.nodes) - + # Now try to disconnect the tip on each node... self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash()) self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) |