Changeset View
Changeset View
Standalone View
Standalone View
test/functional/mempool_packages.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2014-2019 The Bitcoin Core developers | # Copyright (c) 2014-2019 The Bitcoin Core developers | ||||
# Distributed under the MIT software license, see the accompanying | # Distributed under the MIT software license, see the accompanying | ||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
"""Test descendant package tracking code.""" | """Test descendant package tracking code.""" | ||||
from decimal import Decimal | from decimal import Decimal | ||||
from test_framework.messages import COIN | from test_framework.messages import XEC | ||||
from test_framework.p2p import P2PTxInvStore | from test_framework.p2p import P2PTxInvStore | ||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.util import ( | from test_framework.util import ( | ||||
assert_equal, | assert_equal, | ||||
assert_raises_rpc_error, | assert_raises_rpc_error, | ||||
satoshi_round, | satoshi_round, | ||||
) | ) | ||||
Show All 38 Lines | def run_test(self): | ||||
# keep track of invs | # keep track of invs | ||||
self.nodes[0].add_p2p_connection(P2PTxInvStore()) | self.nodes[0].add_p2p_connection(P2PTxInvStore()) | ||||
self.nodes[0].generate(101) | self.nodes[0].generate(101) | ||||
utxo = self.nodes[0].listunspent(10) | utxo = self.nodes[0].listunspent(10) | ||||
txid = utxo[0]['txid'] | txid = utxo[0]['txid'] | ||||
vout = utxo[0]['vout'] | vout = utxo[0]['vout'] | ||||
value = utxo[0]['amount'] | value = utxo[0]['amount'] | ||||
fee = Decimal("0.0001") | fee = Decimal("100") | ||||
# MAX_ANCESTORS transactions off a confirmed tx should be fine | # MAX_ANCESTORS transactions off a confirmed tx should be fine | ||||
chain = [] | chain = [] | ||||
for i in range(MAX_ANCESTORS): | for i in range(MAX_ANCESTORS): | ||||
(txid, sent_value) = self.chain_transaction( | (txid, sent_value) = self.chain_transaction( | ||||
self.nodes[0], txid, 0, value, fee, 1) | self.nodes[0], txid, 0, value, fee, 1) | ||||
value = sent_value | value = sent_value | ||||
chain.append(txid) | chain.append(txid) | ||||
Show All 24 Lines | def run_test(self): | ||||
# Check that the descendant calculations are correct | # Check that the descendant calculations are correct | ||||
assert_equal(mempool[x]['descendantcount'], descendant_count) | assert_equal(mempool[x]['descendantcount'], descendant_count) | ||||
descendant_fees += mempool[x]['fee'] | descendant_fees += mempool[x]['fee'] | ||||
assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']) | assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']) | ||||
assert_equal(mempool[x]['fees']['base'], mempool[x]['fee']) | assert_equal(mempool[x]['fees']['base'], mempool[x]['fee']) | ||||
assert_equal(mempool[x]['fees']['modified'], | assert_equal(mempool[x]['fees']['modified'], | ||||
mempool[x]['modifiedfee']) | mempool[x]['modifiedfee']) | ||||
assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN) | assert_equal(mempool[x]['descendantfees'], descendant_fees * XEC) | ||||
assert_equal(mempool[x]['fees']['descendant'], descendant_fees) | assert_equal(mempool[x]['fees']['descendant'], descendant_fees) | ||||
descendant_size += mempool[x]['size'] | descendant_size += mempool[x]['size'] | ||||
assert_equal(mempool[x]['descendantsize'], descendant_size) | assert_equal(mempool[x]['descendantsize'], descendant_size) | ||||
descendant_count += 1 | descendant_count += 1 | ||||
# Check that ancestor calculations are correct | # Check that ancestor calculations are correct | ||||
assert_equal(mempool[x]['ancestorcount'], ancestor_count) | assert_equal(mempool[x]['ancestorcount'], ancestor_count) | ||||
assert_equal(mempool[x]['ancestorfees'], ancestor_fees * COIN) | assert_equal(mempool[x]['ancestorfees'], ancestor_fees * XEC) | ||||
assert_equal(mempool[x]['ancestorsize'], ancestor_size) | assert_equal(mempool[x]['ancestorsize'], ancestor_size) | ||||
ancestor_size -= mempool[x]['size'] | ancestor_size -= mempool[x]['size'] | ||||
ancestor_fees -= mempool[x]['fee'] | ancestor_fees -= mempool[x]['fee'] | ||||
ancestor_count -= 1 | ancestor_count -= 1 | ||||
# Check that parent/child list is correct | # Check that parent/child list is correct | ||||
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]) | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
# Check that ancestor modified fees includes fee deltas from | # Check that ancestor modified fees includes fee deltas from | ||||
# prioritisetransaction | # prioritisetransaction | ||||
self.nodes[0].prioritisetransaction(txid=chain[0], fee_delta=1000) | self.nodes[0].prioritisetransaction(txid=chain[0], fee_delta=1000) | ||||
mempool = self.nodes[0].getrawmempool(True) | mempool = self.nodes[0].getrawmempool(True) | ||||
ancestor_fees = 0 | ancestor_fees = 0 | ||||
for x in chain: | for x in chain: | ||||
ancestor_fees += mempool[x]['fee'] | ancestor_fees += mempool[x]['fee'] | ||||
assert_equal(mempool[x]['fees']['ancestor'], | assert_equal(mempool[x]['fees']['ancestor'], | ||||
ancestor_fees + Decimal('0.00001')) | ancestor_fees + Decimal('10.00')) | ||||
assert_equal(mempool[x]['ancestorfees'], | assert_equal(mempool[x]['ancestorfees'], | ||||
ancestor_fees * COIN + 1000) | ancestor_fees * XEC + 1000) | ||||
# Undo the prioritisetransaction for later tests | # Undo the prioritisetransaction for later tests | ||||
self.nodes[0].prioritisetransaction(txid=chain[0], fee_delta=-1000) | self.nodes[0].prioritisetransaction(txid=chain[0], fee_delta=-1000) | ||||
# Check that descendant modified fees includes fee deltas from | # Check that descendant modified fees includes fee deltas from | ||||
# prioritisetransaction | # prioritisetransaction | ||||
self.nodes[0].prioritisetransaction(txid=chain[-1], fee_delta=1000) | self.nodes[0].prioritisetransaction(txid=chain[-1], fee_delta=1000) | ||||
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'] | ||||
assert_equal(mempool[x]['fees']['descendant'], | assert_equal(mempool[x]['fees']['descendant'], | ||||
descendant_fees + Decimal('0.00001')) | descendant_fees + Decimal('10.00')) | ||||
assert_equal(mempool[x]['descendantfees'], | assert_equal(mempool[x]['descendantfees'], | ||||
descendant_fees * COIN + 1000) | descendant_fees * XEC + 1000) | ||||
# Adding one more transaction on to the chain should fail. | # Adding one more transaction on to the chain should fail. | ||||
assert_raises_rpc_error(-26, "too-long-mempool-chain", | assert_raises_rpc_error(-26, "too-long-mempool-chain", | ||||
self.chain_transaction, self.nodes[0], txid, vout, value, fee, 1) | self.chain_transaction, self.nodes[0], txid, vout, value, fee, 1) | ||||
# Check that prioritising a tx before it's added to the mempool works | # Check that prioritising a tx before it's added to the mempool works | ||||
# First clear the mempool by mining a block. | # First clear the mempool by mining a block. | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
Show All 10 Lines | def run_test(self): | ||||
# modified fee | # 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(20.00)) | ||||
assert_equal(mempool[x]['fees']['modified'], | assert_equal(mempool[x]['fees']['modified'], | ||||
mempool[x]['fee'] + satoshi_round(0.00002)) | mempool[x]['fee'] + satoshi_round(20.00)) | ||||
assert_equal(mempool[x]['descendantfees'], | assert_equal(mempool[x]['descendantfees'], | ||||
descendant_fees * COIN + 2000) | descendant_fees * XEC + 2000) | ||||
assert_equal(mempool[x]['fees']['descendant'], | assert_equal(mempool[x]['fees']['descendant'], | ||||
descendant_fees + satoshi_round(0.00002)) | descendant_fees + satoshi_round(20.00)) | ||||
# Check that node1's mempool is as expected (-> custom ancestor limit) | # Check that node1's mempool is as expected (-> custom ancestor limit) | ||||
mempool0 = self.nodes[0].getrawmempool(False) | mempool0 = self.nodes[0].getrawmempool(False) | ||||
mempool1 = self.nodes[1].getrawmempool(False) | mempool1 = self.nodes[1].getrawmempool(False) | ||||
assert_equal(len(mempool1), MAX_ANCESTORS_CUSTOM) | assert_equal(len(mempool1), MAX_ANCESTORS_CUSTOM) | ||||
assert set(mempool1).issubset(set(mempool0)) | assert set(mempool1).issubset(set(mempool0)) | ||||
for tx in chain[:MAX_ANCESTORS_CUSTOM]: | for tx in chain[:MAX_ANCESTORS_CUSTOM]: | ||||
assert tx in mempool1 | assert tx in mempool1 | ||||
▲ Show 20 Lines • Show All 124 Lines • Show Last 20 Lines |