mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-15 16:38:23 +01:00
test: add block 2016 to mock mainnet
The next commit requires an additional mainnet block which changes the difficulty. Also fix a few minor mistakes in the test (suite): - rename the create_coinbase retarger_period argument to halving_period. Before bitcoin#31583 this was hardcoded for regtest where these values are the same. - drop unused fees argument from mine helper Finally the CPU miner instructions for generating the alternative mainnet chain are expanded.
This commit is contained in:
@@ -11,9 +11,10 @@ The alternate mainnet chain was generated as follows:
|
|||||||
- restart node with a faketime 2 minutes later
|
- restart node with a faketime 2 minutes later
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
for i in {1..2015}
|
for i in {1..2016}
|
||||||
do
|
do
|
||||||
faketime "`date -d @"$(( 1231006505 + $i * 120 ))" +'%Y-%m-%d %H:%M:%S'`" \
|
t=$(( 1231006505 + $i * 120 ))
|
||||||
|
faketime "`date -d @$t +'%Y-%m-%d %H:%M:%S'`" \
|
||||||
bitcoind -connect=0 -nocheckpoints -stopatheight=$i
|
bitcoind -connect=0 -nocheckpoints -stopatheight=$i
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
@@ -21,7 +22,9 @@ done
|
|||||||
The CPU miner is kept running as follows:
|
The CPU miner is kept running as follows:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./minerd --coinbase-addr 1NQpH6Nf8QtR2HphLRcvuVqfhXBXsiWn8r --no-stratum --algo sha256d --no-longpoll --scantime 3 --retry-pause 1
|
./minerd -u ... -p ... -o http://127.0.0.1:8332 --no-stratum \
|
||||||
|
--coinbase-addr 1NQpH6Nf8QtR2HphLRcvuVqfhXBXsiWn8r \
|
||||||
|
--algo sha256d --no-longpoll --scantime 3 --retry-pause 1
|
||||||
```
|
```
|
||||||
|
|
||||||
The payout address is derived from first BIP32 test vector master key:
|
The payout address is derived from first BIP32 test vector master key:
|
||||||
@@ -40,3 +43,8 @@ The timestamp was not kept constant because at difficulty 1 it's not sufficient
|
|||||||
to only grind the nonce. Grinding the extra_nonce or version field instead
|
to only grind the nonce. Grinding the extra_nonce or version field instead
|
||||||
would have required additional (stratum) software. It would also make it more
|
would have required additional (stratum) software. It would also make it more
|
||||||
complicated to reconstruct the blocks in this test.
|
complicated to reconstruct the blocks in this test.
|
||||||
|
|
||||||
|
The `getblocktemplate` RPC code needs to be patched to ignore not being connected
|
||||||
|
to any peers, and to ignore the IBD status check.
|
||||||
|
|
||||||
|
On macOS use `faketime "@$t"` instead.
|
||||||
|
|||||||
@@ -2014,7 +2014,8 @@
|
|||||||
1231247971,
|
1231247971,
|
||||||
1231248071,
|
1231248071,
|
||||||
1231248198,
|
1231248198,
|
||||||
1231248322
|
1231248322,
|
||||||
|
1231248621
|
||||||
],
|
],
|
||||||
"nonces": [
|
"nonces": [
|
||||||
2345621585,
|
2345621585,
|
||||||
@@ -4031,6 +4032,7 @@
|
|||||||
3658502865,
|
3658502865,
|
||||||
2519048297,
|
2519048297,
|
||||||
1915965760,
|
1915965760,
|
||||||
1183846025
|
1183846025,
|
||||||
|
2713372123
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,15 +53,15 @@ class MiningMainnetTest(BitcoinTestFramework):
|
|||||||
help='Block data file (default: %(default)s)',
|
help='Block data file (default: %(default)s)',
|
||||||
)
|
)
|
||||||
|
|
||||||
def mine(self, height, prev_hash, blocks, node, fees=0):
|
def mine(self, height, prev_hash, blocks, node):
|
||||||
self.log.debug(f"height={height}")
|
self.log.debug(f"height={height}")
|
||||||
block = CBlock()
|
block = CBlock()
|
||||||
block.nVersion = 0x20000000
|
block.nVersion = 0x20000000
|
||||||
block.hashPrevBlock = int(prev_hash, 16)
|
block.hashPrevBlock = int(prev_hash, 16)
|
||||||
block.nTime = blocks['timestamps'][height - 1]
|
block.nTime = blocks['timestamps'][height - 1]
|
||||||
block.nBits = DIFF_1_N_BITS
|
block.nBits = DIFF_1_N_BITS if height < 2016 else DIFF_4_N_BITS
|
||||||
block.nNonce = blocks['nonces'][height - 1]
|
block.nNonce = blocks['nonces'][height - 1]
|
||||||
block.vtx = [create_coinbase(height=height, script_pubkey=bytes.fromhex(COINBASE_SCRIPT_PUBKEY), retarget_period=2016)]
|
block.vtx = [create_coinbase(height=height, script_pubkey=bytes.fromhex(COINBASE_SCRIPT_PUBKEY), halving_period=210000)]
|
||||||
# The alternate mainnet chain was mined with non-timelocked coinbase txs.
|
# The alternate mainnet chain was mined with non-timelocked coinbase txs.
|
||||||
block.vtx[0].nLockTime = 0
|
block.vtx[0].nLockTime = 0
|
||||||
block.vtx[0].vin[0].nSequence = SEQUENCE_FINAL
|
block.vtx[0].vin[0].nSequence = SEQUENCE_FINAL
|
||||||
@@ -82,12 +82,15 @@ class MiningMainnetTest(BitcoinTestFramework):
|
|||||||
self.log.info("Load alternative mainnet blocks")
|
self.log.info("Load alternative mainnet blocks")
|
||||||
path = os.path.join(os.path.dirname(os.path.realpath(__file__)), self.options.datafile)
|
path = os.path.join(os.path.dirname(os.path.realpath(__file__)), self.options.datafile)
|
||||||
prev_hash = node.getbestblockhash()
|
prev_hash = node.getbestblockhash()
|
||||||
|
blocks = None
|
||||||
with open(path, encoding='utf-8') as f:
|
with open(path, encoding='utf-8') as f:
|
||||||
blocks = json.load(f)
|
blocks = json.load(f)
|
||||||
n_blocks = len(blocks['timestamps'])
|
n_blocks = len(blocks['timestamps'])
|
||||||
assert_equal(n_blocks, 2015)
|
assert_equal(n_blocks, 2016)
|
||||||
for i in range(2015):
|
|
||||||
prev_hash = self.mine(i + 1, prev_hash, blocks, node)
|
# Mine up to the last block of the first retarget period
|
||||||
|
for i in range(2015):
|
||||||
|
prev_hash = self.mine(i + 1, prev_hash, blocks, node)
|
||||||
|
|
||||||
assert_equal(node.getblockcount(), 2015)
|
assert_equal(node.getblockcount(), 2015)
|
||||||
|
|
||||||
@@ -102,5 +105,9 @@ class MiningMainnetTest(BitcoinTestFramework):
|
|||||||
assert_equal(mining_info['next']['bits'], nbits_str(DIFF_4_N_BITS))
|
assert_equal(mining_info['next']['bits'], nbits_str(DIFF_4_N_BITS))
|
||||||
assert_equal(mining_info['next']['target'], target_str(DIFF_4_TARGET))
|
assert_equal(mining_info['next']['target'], target_str(DIFF_4_TARGET))
|
||||||
|
|
||||||
|
# Mine first block of the second retarget period
|
||||||
|
height = 2016
|
||||||
|
prev_hash = self.mine(height, prev_hash, blocks, node)
|
||||||
|
assert_equal(node.getblockcount(), height)
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
MiningMainnetTest(__file__).main()
|
MiningMainnetTest(__file__).main()
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ def script_BIP34_coinbase_height(height):
|
|||||||
return CScript([CScriptNum(height)])
|
return CScript([CScriptNum(height)])
|
||||||
|
|
||||||
|
|
||||||
def create_coinbase(height, pubkey=None, *, script_pubkey=None, extra_output_script=None, fees=0, nValue=50, retarget_period=REGTEST_RETARGET_PERIOD):
|
def create_coinbase(height, pubkey=None, *, script_pubkey=None, extra_output_script=None, fees=0, nValue=50, halving_period=REGTEST_RETARGET_PERIOD):
|
||||||
"""Create a coinbase transaction.
|
"""Create a coinbase transaction.
|
||||||
|
|
||||||
If pubkey is passed in, the coinbase output will be a P2PK output;
|
If pubkey is passed in, the coinbase output will be a P2PK output;
|
||||||
@@ -158,7 +158,7 @@ def create_coinbase(height, pubkey=None, *, script_pubkey=None, extra_output_scr
|
|||||||
coinbaseoutput = CTxOut()
|
coinbaseoutput = CTxOut()
|
||||||
coinbaseoutput.nValue = nValue * COIN
|
coinbaseoutput.nValue = nValue * COIN
|
||||||
if nValue == 50:
|
if nValue == 50:
|
||||||
halvings = int(height / retarget_period)
|
halvings = int(height / halving_period)
|
||||||
coinbaseoutput.nValue >>= halvings
|
coinbaseoutput.nValue >>= halvings
|
||||||
coinbaseoutput.nValue += fees
|
coinbaseoutput.nValue += fees
|
||||||
if pubkey is not None:
|
if pubkey is not None:
|
||||||
|
|||||||
Reference in New Issue
Block a user