Changeset View
Changeset View
Standalone View
Standalone View
test/functional/feature_deterministic_chain_setup.py
Show All 15 Lines | |||||
def get_coinbase_scriptsig(height: int) -> bytes: | def get_coinbase_scriptsig(height: int) -> bytes: | ||||
OP_1 = 0x51 | OP_1 = 0x51 | ||||
if height <= 16: | if height <= 16: | ||||
bip34_coinbase_height = bytes([OP_1 + height - 1]) | bip34_coinbase_height = bytes([OP_1 + height - 1]) | ||||
else: | else: | ||||
bip34_coinbase_height = CScriptNum.encode(CScriptNum(height)) | bip34_coinbase_height = CScriptNum.encode(CScriptNum(height)) | ||||
extra_nonce = CScriptNum.encode(CScriptNum(1)) | extra_nonce = CScriptNum.encode(CScriptNum(1)) | ||||
excessive_blocksize_sig = CScriptOp.encode_op_pushdata(b'/EB32.0/') | excessive_blocksize_sig = CScriptOp.encode_op_pushdata(b"/EB32.0/") | ||||
return bip34_coinbase_height + extra_nonce + excessive_blocksize_sig | return bip34_coinbase_height + extra_nonce + excessive_blocksize_sig | ||||
def get_coinbase(height: int, pubkey: bytes) -> CTransaction: | def get_coinbase(height: int, pubkey: bytes) -> CTransaction: | ||||
coinbase = CTransaction() | coinbase = CTransaction() | ||||
coinbase.nVersion = 2 | coinbase.nVersion = 2 | ||||
coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff), | coinbase.vin.append( | ||||
get_coinbase_scriptsig(height), | CTxIn(COutPoint(0, 0xFFFFFFFF), get_coinbase_scriptsig(height), 0xFFFFFFFF) | ||||
0xffffffff)) | ) | ||||
coinbaseoutput = CTxOut() | coinbaseoutput = CTxOut() | ||||
coinbaseoutput.nValue = 50 * COIN | coinbaseoutput.nValue = 50 * COIN | ||||
regtest_halvings = int(height / 150) | regtest_halvings = int(height / 150) | ||||
coinbaseoutput.nValue >>= regtest_halvings | coinbaseoutput.nValue >>= regtest_halvings | ||||
coinbaseoutput.scriptPubKey = CScript([pubkey, OP_CHECKSIG]) | coinbaseoutput.scriptPubKey = CScript([pubkey, OP_CHECKSIG]) | ||||
coinbase.vout = [coinbaseoutput] | coinbase.vout = [coinbaseoutput] | ||||
coinbase.calc_sha256() | coinbase.calc_sha256() | ||||
return coinbase | return coinbase | ||||
def get_empty_block(height: int, base_block_hash: str, block_time: int, | def get_empty_block( | ||||
coinbase_pubkey: bytes) -> CBlock: | height: int, base_block_hash: str, block_time: int, coinbase_pubkey: bytes | ||||
) -> CBlock: | |||||
block = CBlock() | block = CBlock() | ||||
block.nVersion = 0x20000000 | block.nVersion = 0x20000000 | ||||
block.nTime = block_time | block.nTime = block_time | ||||
block.hashPrevBlock = int(base_block_hash, 16) | block.hashPrevBlock = int(base_block_hash, 16) | ||||
# difficulty retargeting is disabled in REGTEST chainparams | # difficulty retargeting is disabled in REGTEST chainparams | ||||
block.nBits = 0x207fffff | block.nBits = 0x207FFFFF | ||||
block.vtx.append(get_coinbase(height, coinbase_pubkey)) | block.vtx.append(get_coinbase(height, coinbase_pubkey)) | ||||
block.hashMerkleRoot = block.calc_merkle_root() | block.hashMerkleRoot = block.calc_merkle_root() | ||||
block.solve() | block.solve() | ||||
return block | return block | ||||
class DeterministicChainSetupTest(BitcoinTestFramework): | class DeterministicChainSetupTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
Show All 12 Lines | def run_test(self): | ||||
chain_height = 1 | chain_height = 1 | ||||
mock_time = INITIAL_MOCKTIME | mock_time = INITIAL_MOCKTIME | ||||
def mine_blocks(num_blocks: int): | def mine_blocks(num_blocks: int): | ||||
nonlocal tip | nonlocal tip | ||||
nonlocal chain_height | nonlocal chain_height | ||||
nonlocal mock_time | nonlocal mock_time | ||||
for _ in range(num_blocks): | for _ in range(num_blocks): | ||||
block = get_empty_block(chain_height, tip, mock_time, | block = get_empty_block(chain_height, tip, mock_time, coinbase_pubkey) | ||||
coinbase_pubkey) | |||||
assert node.submitblock(block.serialize().hex()) is None | assert node.submitblock(block.serialize().hex()) is None | ||||
tip = node.getbestblockhash() | tip = node.getbestblockhash() | ||||
chain_height += 1 | chain_height += 1 | ||||
mock_time += 1 | mock_time += 1 | ||||
self.log.info( | self.log.info("Reproduce the assertion in the TestChain100Setup constructor.") | ||||
"Reproduce the assertion in the TestChain100Setup constructor.") | |||||
mine_blocks(100) | mine_blocks(100) | ||||
assert_equal(tip, | assert_equal( | ||||
"7487ae41496da318b430ad04cc5039507a9365bdb26275d79b3fc148c6eea1e9") | tip, "7487ae41496da318b430ad04cc5039507a9365bdb26275d79b3fc148c6eea1e9" | ||||
) | |||||
self.log.info("Check m_assumeutxo_data at height 110.") | self.log.info("Check m_assumeutxo_data at height 110.") | ||||
mine_blocks(10) | mine_blocks(10) | ||||
assert_equal(node.getblockchaininfo()["blocks"], 110) | assert_equal(node.getblockchaininfo()["blocks"], 110) | ||||
assert_equal(node.gettxoutsetinfo()["hash_serialized"], | assert_equal( | ||||
"ff755939f6fd81bf966e2f347f5d3660d6239334050eb557a6f005d7d8184ea9") | node.gettxoutsetinfo()["hash_serialized"], | ||||
"ff755939f6fd81bf966e2f347f5d3660d6239334050eb557a6f005d7d8184ea9", | |||||
) | |||||
self.log.info("Check m_assumeutxo_data at height 210.") | self.log.info("Check m_assumeutxo_data at height 210.") | ||||
mine_blocks(100) | mine_blocks(100) | ||||
assert_equal(node.getblockchaininfo()["blocks"], 210) | assert_equal(node.getblockchaininfo()["blocks"], 210) | ||||
assert_equal(node.gettxoutsetinfo()["hash_serialized"], | assert_equal( | ||||
"d6089fa8d2100926326cacdd452231e30bb4e64f07aa5bfec96e055ac2a9a87a") | node.gettxoutsetinfo()["hash_serialized"], | ||||
"d6089fa8d2100926326cacdd452231e30bb4e64f07aa5bfec96e055ac2a9a87a", | |||||
) | |||||
if __name__ == '__main__': | if __name__ == "__main__": | ||||
DeterministicChainSetupTest().main() | DeterministicChainSetupTest().main() |