test: Check for valid hashBlockCommitments construction post-NU5
This commit is contained in:
parent
bd4c0a8515
commit
2d0a8f1f3a
|
@ -116,6 +116,7 @@ BASE_SCRIPTS= [
|
||||||
'framework.py',
|
'framework.py',
|
||||||
'sapling_rewind_check.py',
|
'sapling_rewind_check.py',
|
||||||
'feature_zip221.py',
|
'feature_zip221.py',
|
||||||
|
'feature_zip244_blockcommitments.py',
|
||||||
'upgrade_golden.py',
|
'upgrade_golden.py',
|
||||||
'post_heartwood_rollback.py',
|
'post_heartwood_rollback.py',
|
||||||
'feature_logging.py',
|
'feature_logging.py',
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright (c) 2020 The Zcash developers
|
||||||
|
# Distributed under the MIT software license, see the accompanying
|
||||||
|
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||||
|
|
||||||
|
|
||||||
|
from test_framework.blocktools import derive_block_commitments_hash
|
||||||
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
|
from test_framework.util import (
|
||||||
|
assert_equal,
|
||||||
|
bytes_to_hex_str,
|
||||||
|
hex_str_to_bytes,
|
||||||
|
start_nodes,
|
||||||
|
)
|
||||||
|
|
||||||
|
TERMINATOR = b'\x00' * 32
|
||||||
|
|
||||||
|
# Verify block header field 'hashLightClientRoot' is set correctly for NU5 blocks.
|
||||||
|
class AuthDataRootTest(BitcoinTestFramework):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.num_nodes = 4
|
||||||
|
|
||||||
|
def setup_nodes(self):
|
||||||
|
return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[
|
||||||
|
'-nuparams=5ba81b19:1', # Overwinter
|
||||||
|
'-nuparams=76b809bb:1', # Sapling
|
||||||
|
'-nuparams=2bb40e60:201', # Blossom
|
||||||
|
'-nuparams=f5b9230b:201', # Heartwood
|
||||||
|
'-nuparams=e9ff75a6:201', # Canopy
|
||||||
|
'-nuparams=f919a198:205', # NU5
|
||||||
|
'-nurejectoldversions=false',
|
||||||
|
]] * self.num_nodes)
|
||||||
|
|
||||||
|
def run_test(self):
|
||||||
|
# Generate a block so we are on Canopy rules.
|
||||||
|
self.nodes[0].generate(2)
|
||||||
|
self.sync_all()
|
||||||
|
|
||||||
|
# Before NU5 activation, the hashBlockCommitments field of the block
|
||||||
|
# header contains the root of the ZIP 221 history tree.
|
||||||
|
block_before = self.nodes[0].getblock('202')
|
||||||
|
assert_equal(block_before['blockcommitments'], block_before['chainhistoryroot'])
|
||||||
|
|
||||||
|
# Generate blocks until we are on NU5 rules.
|
||||||
|
self.nodes[0].generate(3)
|
||||||
|
self.sync_all()
|
||||||
|
|
||||||
|
# From NU5 activation, the hashBlockCommitments field of the block
|
||||||
|
# header contains a hash of various block commitments (per ZIP 244).
|
||||||
|
block_after = self.nodes[0].getblock('205')
|
||||||
|
block_commitments = bytes_to_hex_str(derive_block_commitments_hash(
|
||||||
|
hex_str_to_bytes(block_after['chainhistoryroot'])[::-1],
|
||||||
|
hex_str_to_bytes(block_after['authdataroot'])[::-1],
|
||||||
|
)[::-1])
|
||||||
|
assert_equal(block_after['blockcommitments'], block_commitments)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
AuthDataRootTest().main()
|
|
@ -4,6 +4,8 @@
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||||
|
|
||||||
|
from pyblake2 import blake2b
|
||||||
|
|
||||||
from .mininode import CBlock, CTransaction, CTxIn, CTxOut, COutPoint
|
from .mininode import CBlock, CTransaction, CTxIn, CTxOut, COutPoint
|
||||||
from .script import CScript, OP_0, OP_EQUAL, OP_HASH160, OP_TRUE, OP_CHECKSIG
|
from .script import CScript, OP_0, OP_EQUAL, OP_HASH160, OP_TRUE, OP_CHECKSIG
|
||||||
|
|
||||||
|
@ -29,6 +31,15 @@ def create_block(hashprev, coinbase, nTime=None, nBits=None, hashFinalSaplingRoo
|
||||||
block.calc_sha256()
|
block.calc_sha256()
|
||||||
return block
|
return block
|
||||||
|
|
||||||
|
def derive_block_commitments_hash(chain_history_root, auth_data_root):
|
||||||
|
digest = blake2b(
|
||||||
|
digest_size=32,
|
||||||
|
person=b'ZcashBlockCommit')
|
||||||
|
digest.update(chain_history_root)
|
||||||
|
digest.update(auth_data_root)
|
||||||
|
digest.update(b'\x00' * 32)
|
||||||
|
return digest.digest()
|
||||||
|
|
||||||
def serialize_script_num(value):
|
def serialize_script_num(value):
|
||||||
r = bytearray(0)
|
r = bytearray(0)
|
||||||
if value == 0:
|
if value == 0:
|
||||||
|
|
|
@ -233,6 +233,8 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
|
||||||
result.pushKV("height", blockindex->nHeight);
|
result.pushKV("height", blockindex->nHeight);
|
||||||
result.pushKV("version", block.nVersion);
|
result.pushKV("version", block.nVersion);
|
||||||
result.pushKV("merkleroot", block.hashMerkleRoot.GetHex());
|
result.pushKV("merkleroot", block.hashMerkleRoot.GetHex());
|
||||||
|
result.pushKV("blockcommitments", blockindex->hashBlockCommitments.GetHex());
|
||||||
|
result.pushKV("authdataroot", blockindex->hashAuthDataRoot.GetHex());
|
||||||
result.pushKV("finalsaplingroot", blockindex->hashFinalSaplingRoot.GetHex());
|
result.pushKV("finalsaplingroot", blockindex->hashFinalSaplingRoot.GetHex());
|
||||||
result.pushKV("chainhistoryroot", blockindex->hashChainHistoryRoot.GetHex());
|
result.pushKV("chainhistoryroot", blockindex->hashChainHistoryRoot.GetHex());
|
||||||
UniValue txs(UniValue::VARR);
|
UniValue txs(UniValue::VARR);
|
||||||
|
|
Loading…
Reference in New Issue