Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc-phonon-mempoolpolicy.py
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
#!/usr/bin/env python3 | |||||
# Copyright (c) 2020 The Bitcoin developers | |||||
# Distributed under the MIT software license, see the accompanying | |||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | |||||
"""Test that long chains are trimmed from mempool on phonon-rollback. | |||||
This test does not cover that the limits are enforced by sendrawtransaction, | |||||
the test mempool_packages.py covers that. | |||||
This test can be deleted after new policy takes effect.""" | |||||
from test_framework.test_framework import BitcoinTestFramework | |||||
from test_framework.util import ( | |||||
assert_equal, | |||||
satoshi_round, | |||||
) | |||||
from decimal import Decimal | |||||
# Phonon dummy activation time | |||||
ACTIVATION_TIME = 2000000000 | |||||
# Replay protection time needs to be moved beyond phonon activation | |||||
REPLAY_PROTECTION_TIME = ACTIVATION_TIME * 2 | |||||
PREFORK_MAX_ANCESTORS = 25 | |||||
POSTFORK_MAX_ANCESTORS = 50 | |||||
def mine_until_mtp(node, new_mtp): | |||||
"""Generates blocks until new mtp is reached""" | |||||
node.setmocktime(new_mtp) | |||||
while True: | |||||
current_mtp = node.getblockheader( | |||||
node.getbestblockhash())['mediantime'] | |||||
assert(current_mtp <= new_mtp) | |||||
if current_mtp == new_mtp: | |||||
break | |||||
node.generate(1) | |||||
jasonbcox: This function looks fragile. Check how it's done in `abc-op-reversebytes-activation.py:203` | |||||
class PhononMempoolPolicyTest(BitcoinTestFramework): | |||||
def set_test_params(self): | |||||
self.num_nodes = 1 | |||||
self.extra_args = [[ | |||||
"-phononactivationtime={}".format(ACTIVATION_TIME), | |||||
"-replayprotectionactivationtime={}".format( | |||||
REPLAY_PROTECTION_TIME)]] | |||||
def skip_test_if_missing_module(self): | |||||
self.skip_if_no_wallet() | |||||
def chain_transaction(self, node, parent_txid, vout, value): | |||||
"""Build a transaction that spends parent_txid:vout. Return txid and amount sent""" | |||||
fee = Decimal(0.0001) | |||||
jasonbcoxUnsubmitted Not Done Inline ActionsMake 0.0001 a string, otherwise it's possible to run into this problem: https://stackoverflow.com/questions/32053647/comparing-python-decimals-created-from-float-and-string jasonbcox: Make 0.0001 a string, otherwise it's possible to run into this problem: https://stackoverflow. | |||||
send_value = satoshi_round(value - fee) | |||||
inputs = [{'txid': parent_txid, 'vout': vout}] | |||||
outputs = {node.getnewaddress(): send_value} | |||||
rawtx = node.createrawtransaction(inputs, outputs) | |||||
signedtx = node.signrawtransactionwithwallet(rawtx) | |||||
txid = node.sendrawtransaction(signedtx['hex']) | |||||
fulltx = node.getrawtransaction(txid, 1) | |||||
# make sure we didn't generate a change output | |||||
assert len(fulltx['vout']) == 1 | |||||
return (txid, send_value) | |||||
def run_test(self): | |||||
# Mine some pre-fork blocks | |||||
node = self.nodes[0] | |||||
mine_until_mtp(node, ACTIVATION_TIME - 1) | |||||
pre_fork_height = node.getblockcount() | |||||
# Activate phonon | |||||
mine_until_mtp(node, ACTIVATION_TIME) | |||||
# Mine a POSTFORK_MAX_ANCESTORS length chain | |||||
assert_equal(0, len(node.getrawmempool(True))) | |||||
utxo = self.nodes[0].listunspent(1)[0] | |||||
txid = utxo['txid'] | |||||
value = utxo['amount'] | |||||
for _ in range(POSTFORK_MAX_ANCESTORS): | |||||
(txid, value) = self.chain_transaction( | |||||
node, txid, vout=0, value=value) | |||||
assert_equal(POSTFORK_MAX_ANCESTORS, len(node.getrawmempool(True))) | |||||
# Rollback the fork | |||||
node.invalidateblock(node.getblockhash(pre_fork_height + 1)) | |||||
# Assert that the mempool was trimmed to PREFORK_MAX_ANCESTORS | |||||
assert_equal(PREFORK_MAX_ANCESTORS, len(node.getrawmempool(True))) | |||||
jasonbcoxUnsubmitted Not Done Inline ActionsThis is good, but a similar test needs to done to make sure that long-chains get trimmed even if they were mined. jasonbcox: This is good, but a similar test needs to done to make sure that long-chains get trimmed even… | |||||
if __name__ == '__main__': | |||||
PhononMempoolPolicyTest().main() |
This function looks fragile. Check how it's done in abc-op-reversebytes-activation.py:203