Changeset View
Standalone View
test/functional/abc-nulldummy-activation.py
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
#!/usr/bin/env python3 | |||||
# Copyright (c) 2019 The Bitcoin developers | |||||
# Distributed under the MIT software license, see the accompanying | |||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | |||||
from test_framework.blocktools import create_coinbase, create_block | |||||
from test_framework.cdefs import GREAT_WALL_ACTIVATION_TIME | |||||
from test_framework.test_framework import BitcoinTestFramework | |||||
from test_framework.txtools import pad_raw_tx | |||||
from test_framework.util import sync_blocks, bytes_to_hex_str, assert_equal | |||||
import time | |||||
IN_THE_FUTURE = int(time.time()) * 2 | |||||
deadalnix: Please chose a fixed value so the test is repeatable. | |||||
""" | |||||
This tests the mempool behavior during 'great wall' activation with regards to | |||||
nulldummy enforcement. | |||||
This test can be removed after activation. | |||||
""" | |||||
class NullDummyActivation(BitcoinTestFramework): | |||||
def set_test_params(self): | |||||
self.num_nodes = 2 | |||||
self.setup_clean_chain = True | |||||
common_args = [ | |||||
'-greatwallactivationtime=%d' % GREAT_WALL_ACTIVATION_TIME, | |||||
FabienUnsubmitted Not Done Inline ActionsPlease use the format method (e.g. '-greatwallactivationtime={}'.format(GREAT_WALL_ACTIVATION_TIME)) instead of % for string formatting Fabien: Please use the format method (e.g. `'-greatwallactivationtime={}'.format… | |||||
deadalnixUnsubmitted Not Done Inline ActionsHaving a linter yelling at people for this would be beneficial. % syntax is so much nicer, idk why pything is deprecating it :( deadalnix: Having a linter yelling at people for this would be beneficial. % syntax is so much nicer, idk… | |||||
"-replayprotectionactivationtime=%d" % IN_THE_FUTURE] | |||||
jasonbcoxUnsubmitted Not Done Inline ActionsGREAT_WALL_ACTIVATION_TIME * 2 instead, then you can remove IN_THE_FUTURE, which is unnecessary to have a separate definition. jasonbcox: `GREAT_WALL_ACTIVATION_TIME * 2` instead, then you can remove IN_THE_FUTURE, which is… | |||||
dagurvalUnsubmitted Not Done Inline ActionsGREAT_WALL_ACTIVATION_TIME * 2 is a magic number that makes the intention unclear dagurval: `GREAT_WALL_ACTIVATION_TIME * 2` is a magic number that makes the intention unclear | |||||
deadalnixUnsubmitted Not Done Inline Actions@dagurval is correct. However, it indeed needs to be further in the future than GREAT_WALL_ACTIVATION_TIME is. deadalnix: @dagurval is correct. However, it indeed needs to be further in the future than… | |||||
self.extra_args = [ | |||||
common_args + ["-acceptnonstdtxn=0"], | |||||
common_args + ["-acceptnonstdtxn=1"]] | |||||
# 'Great wall' is NOT activated at the beginning of the test. | |||||
self.mocktime = GREAT_WALL_ACTIVATION_TIME - 1000 | |||||
def _create_tx(self, txid_in, n): | |||||
to_addr = self.nodes[0].getnewaddress() | |||||
rawtx = self.nodes[0].createrawtransaction([{ | |||||
'txid': txid_in, | |||||
'vout': 0}], {to_addr: 42}) | |||||
rawtx = pad_raw_tx(rawtx) | |||||
rawtx = self.nodes[0].signrawtransaction(rawtx)['hex'] | |||||
return rawtx | |||||
def _create_coinbase_utxo(self): | |||||
coinbase_block = self.nodes[0].generate(1) | |||||
coinbase_id = self.nodes[0].getblock(coinbase_block[0])['tx'][0] | |||||
return coinbase_id | |||||
def run_test(self): | |||||
coinbase_id = self._create_coinbase_utxo() | |||||
self.nodes[0].generate(101) | |||||
sync_blocks(self.nodes) | |||||
# Test that mempool is cleared after activation | |||||
rawtx = self._create_tx(coinbase_id, n=0) | |||||
for n in self.nodes: | |||||
n.sendrawtransaction(rawtx, True) | |||||
while True: | |||||
lastblock = self.nodes[0].getblockheader( | |||||
self.nodes[0].getbestblockhash()) | |||||
mtp = lastblock['mediantime'] | |||||
if mtp < GREAT_WALL_ACTIVATION_TIME: | |||||
# Not activated. Transaction should stay in mempool on both | |||||
# nodes. | |||||
assert_equal(1, self.nodes[0].getmempoolinfo()['size']) | |||||
assert_equal(1, self.nodes[1].getmempoolinfo()['size']) | |||||
else: | |||||
# New rules enforced. Nodes accepting non-standard transactions | |||||
# should clear its mempool, as it may have had a non-compliant | |||||
# NULLDUMMY transaction in it | |||||
# Node 0 did not accept non-standard | |||||
assert_equal(1, self.nodes[0].getmempoolinfo()['size']) | |||||
# Node 1 did accept non-standard | |||||
assert_equal(0, self.nodes[1].getmempoolinfo()['size']) | |||||
return | |||||
next_time = lastblock['time'] + 600 | |||||
next_height = lastblock['height'] + 1 | |||||
coinbase = create_coinbase(next_height) | |||||
block = create_block( | |||||
int("0x" + lastblock['hash'], 0), coinbase, next_time) | |||||
for n in self.nodes: | |||||
n.setmocktime(next_time) | |||||
n.submitblock(bytes_to_hex_str(block.serialize())) | |||||
deadalnixUnsubmitted Not Done Inline ActionsThe structure of this test is very confusing. Here is a good test plan:
You can use tests for the activation of the last fork as examples. Very tight testing is required to detect problem such as off by one errors. You probably want to have two nodes, one set to accept non standard txns, and one set to reject. You also want to check that node do nto ban each others when one activated teh fork and one did not. deadalnix: The structure of this test is very confusing.
Here is a good test plan:
# Check that the tx is… | |||||
dagurvalUnsubmitted Not Done Inline ActionsThis script is to simply test that the mempool is cleared on activation. Its here for completeness only as it affects most likely no one at all, as there are no miners accepting non-standard transactions. What you're looking for is in the other test. It's directly based on Core's activation of nulldummy and does no more, no less. It's not as extensive as what you're asking for though. dagurval: This script is to simply test that the mempool is cleared on activation. Its here for… | |||||
markblundebergUnsubmitted Not Done Inline ActionsTo be honest I'd suggest taking a look at abc-replay-activation.py and building off that instead. It uses more of the modern test equipment and it's closer to what Amaury wants to see. markblundeberg: To be honest I'd suggest taking a look at abc-replay-activation.py and building off that… | |||||
markblundebergUnsubmitted Not Done Inline Actions(you can take a look at D2483 to see how I adapted it to Schnorr, for instance) markblundeberg: (you can take a look at D2483 to see how I adapted it to Schnorr, for instance) | |||||
if __name__ == '__main__': | |||||
NullDummyActivation().main() |
Please chose a fixed value so the test is repeatable.