Changeset View
Changeset View
Standalone View
Standalone View
test/functional/mempool_packages.py
Show All 25 Lines | def set_test_params(self): | ||||
self.extra_args = [["-maxorphantx=1000"], | self.extra_args = [["-maxorphantx=1000"], | ||||
["-maxorphantx=1000", "-limitancestorcount=5"]] | ["-maxorphantx=1000", "-limitancestorcount=5"]] | ||||
def skip_test_if_missing_module(self): | def skip_test_if_missing_module(self): | ||||
self.skip_if_no_wallet() | self.skip_if_no_wallet() | ||||
# Build a transaction that spends parent_txid:vout | # Build a transaction that spends parent_txid:vout | ||||
# Return amount sent | # Return amount sent | ||||
def chain_transaction(self, node, parent_txid, vout, value, fee, num_outputs): | def chain_transaction(self, node, parent_txid, vout, | ||||
value, fee, num_outputs): | |||||
send_value = satoshi_round((value - fee) / num_outputs) | send_value = satoshi_round((value - fee) / num_outputs) | ||||
inputs = [{'txid': parent_txid, 'vout': vout}] | inputs = [{'txid': parent_txid, 'vout': vout}] | ||||
outputs = {} | outputs = {} | ||||
for i in range(num_outputs): | for i in range(num_outputs): | ||||
outputs[node.getnewaddress()] = send_value | outputs[node.getnewaddress()] = send_value | ||||
rawtx = node.createrawtransaction(inputs, outputs) | rawtx = node.createrawtransaction(inputs, outputs) | ||||
signedtx = node.signrawtransactionwithwallet(rawtx) | signedtx = node.signrawtransactionwithwallet(rawtx) | ||||
txid = node.sendrawtransaction(signedtx['hex']) | txid = node.sendrawtransaction(signedtx['hex']) | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
assert_equal(mempool[x]['spentby'], descendants[-1:]) | assert_equal(mempool[x]['spentby'], descendants[-1:]) | ||||
assert_equal(mempool[x]['depends'], ancestors[-2:-1]) | assert_equal(mempool[x]['depends'], ancestors[-2:-1]) | ||||
# Check that getmempooldescendants is correct | # Check that getmempooldescendants is correct | ||||
assert_equal(sorted(descendants), sorted( | assert_equal(sorted(descendants), sorted( | ||||
self.nodes[0].getmempooldescendants(x))) | self.nodes[0].getmempooldescendants(x))) | ||||
# Check getmempooldescendants verbose output is correct | # Check getmempooldescendants verbose output is correct | ||||
for descendant, dinfo in self.nodes[0].getmempooldescendants(x, True).items(): | for descendant, dinfo in self.nodes[0].getmempooldescendants( | ||||
x, True).items(): | |||||
assert_equal(dinfo['depends'], [ | assert_equal(dinfo['depends'], [ | ||||
chain[chain.index(descendant) - 1]]) | chain[chain.index(descendant) - 1]]) | ||||
if dinfo['descendantcount'] > 1: | if dinfo['descendantcount'] > 1: | ||||
assert_equal(dinfo['spentby'], [ | assert_equal(dinfo['spentby'], [ | ||||
chain[chain.index(descendant) + 1]]) | chain[chain.index(descendant) + 1]]) | ||||
else: | else: | ||||
assert_equal(dinfo['spentby'], []) | assert_equal(dinfo['spentby'], []) | ||||
descendants.append(x) | descendants.append(x) | ||||
# Check that getmempoolancestors is correct | # Check that getmempoolancestors is correct | ||||
ancestors.remove(x) | ancestors.remove(x) | ||||
assert_equal(sorted(ancestors), sorted( | assert_equal(sorted(ancestors), sorted( | ||||
self.nodes[0].getmempoolancestors(x))) | self.nodes[0].getmempoolancestors(x))) | ||||
# Check that getmempoolancestors verbose output is correct | # Check that getmempoolancestors verbose output is correct | ||||
for ancestor, ainfo in self.nodes[0].getmempoolancestors(x, True).items(): | for ancestor, ainfo in self.nodes[0].getmempoolancestors( | ||||
x, True).items(): | |||||
assert_equal(ainfo['spentby'], [ | assert_equal(ainfo['spentby'], [ | ||||
chain[chain.index(ancestor) + 1]]) | chain[chain.index(ancestor) + 1]]) | ||||
if ainfo['ancestorcount'] > 1: | if ainfo['ancestorcount'] > 1: | ||||
assert_equal(ainfo['depends'], [ | assert_equal(ainfo['depends'], [ | ||||
chain[chain.index(ancestor) - 1]]) | chain[chain.index(ancestor) - 1]]) | ||||
else: | else: | ||||
assert_equal(ainfo['depends'], []) | assert_equal(ainfo['depends'], []) | ||||
# Check that getmempoolancestors/getmempooldescendants correctly handle verbose=true | # Check that getmempoolancestors/getmempooldescendants correctly handle | ||||
# verbose=true | |||||
v_ancestors = self.nodes[0].getmempoolancestors(chain[-1], True) | v_ancestors = self.nodes[0].getmempoolancestors(chain[-1], True) | ||||
assert_equal(len(v_ancestors), len(chain) - 1) | assert_equal(len(v_ancestors), len(chain) - 1) | ||||
for x in v_ancestors.keys(): | for x in v_ancestors.keys(): | ||||
assert_equal(mempool[x], v_ancestors[x]) | assert_equal(mempool[x], v_ancestors[x]) | ||||
assert chain[-1] not in v_ancestors.keys() | assert chain[-1] not in v_ancestors.keys() | ||||
v_descendants = self.nodes[0].getmempooldescendants(chain[0], True) | v_descendants = self.nodes[0].getmempooldescendants(chain[0], True) | ||||
assert_equal(len(v_descendants), len(chain) - 1) | assert_equal(len(v_descendants), len(chain) - 1) | ||||
Show All 40 Lines | def run_test(self): | ||||
assert_equal(len(self.nodes[0].getrawmempool()), 0) | assert_equal(len(self.nodes[0].getrawmempool()), 0) | ||||
# Prioritise a transaction that has been mined, then add it back to the | # Prioritise a transaction that has been mined, then add it back to the | ||||
# mempool by using invalidateblock. | # mempool by using invalidateblock. | ||||
self.nodes[0].prioritisetransaction(txid=chain[-1], fee_delta=2000) | self.nodes[0].prioritisetransaction(txid=chain[-1], fee_delta=2000) | ||||
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) | self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) | ||||
# Keep node1's tip synced with node0 | # Keep node1's tip synced with node0 | ||||
self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash()) | self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash()) | ||||
# Now check that the transaction is in the mempool, with the right modified fee | # Now check that the transaction is in the mempool, with the right | ||||
# modified fee | |||||
mempool = self.nodes[0].getrawmempool(True) | mempool = self.nodes[0].getrawmempool(True) | ||||
descendant_fees = 0 | descendant_fees = 0 | ||||
for x in reversed(chain): | for x in reversed(chain): | ||||
descendant_fees += mempool[x]['fee'] | descendant_fees += mempool[x]['fee'] | ||||
if (x == chain[-1]): | if (x == chain[-1]): | ||||
assert_equal(mempool[x]['modifiedfee'], | assert_equal(mempool[x]['modifiedfee'], | ||||
mempool[x]['fee'] + satoshi_round(0.00002)) | mempool[x]['fee'] + satoshi_round(0.00002)) | ||||
Show All 18 Lines | def run_test(self): | ||||
# First create one parent tx with 10 children | # First create one parent tx with 10 children | ||||
(txid, sent_value) = self.chain_transaction( | (txid, sent_value) = self.chain_transaction( | ||||
self.nodes[0], txid, vout, value, fee, 10) | self.nodes[0], txid, vout, value, fee, 10) | ||||
parent_transaction = txid | parent_transaction = txid | ||||
for i in range(10): | for i in range(10): | ||||
transaction_package.append( | transaction_package.append( | ||||
{'txid': txid, 'vout': i, 'amount': sent_value}) | {'txid': txid, 'vout': i, 'amount': sent_value}) | ||||
# Sign and send up to MAX_DESCENDANT transactions chained off the parent tx | # Sign and send up to MAX_DESCENDANT transactions chained off the | ||||
# parent tx | |||||
for i in range(MAX_DESCENDANTS - 1): | for i in range(MAX_DESCENDANTS - 1): | ||||
utxo = transaction_package.pop(0) | utxo = transaction_package.pop(0) | ||||
(txid, sent_value) = self.chain_transaction( | (txid, sent_value) = self.chain_transaction( | ||||
self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) | self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) | ||||
if utxo['txid'] is parent_transaction: | if utxo['txid'] is parent_transaction: | ||||
tx_children.append(txid) | tx_children.append(txid) | ||||
for j in range(10): | for j in range(10): | ||||
transaction_package.append( | transaction_package.append( | ||||
▲ Show 20 Lines • Show All 90 Lines • Show Last 20 Lines |