Merge bitcoin/bitcoin#32868: test: refactor: overhaul block hash determination for CBlock{,Header} objects

5fa34951ea test: avoid unneeded block header hash -> integer conversions (Sebastian Falbesoner)
2118301d77 test: rename CBlockHeader `.hash` -> `.hash_hex` for consistency (Sebastian Falbesoner)
23be0ec2f0 test: rename CBlockHeader `.rehash()`/`.sha256` -> `.hash_int` for consistency (Sebastian Falbesoner)
8b09cc350a test: remove bare CBlockHeader `.rehash()`/`.calc_sha256()` calls (Sebastian Falbesoner)
0716382c20 test: remove header hash caching in CBlockHeader class (Sebastian Falbesoner)
0f044e82bd test: avoid direct block header modification in feature_block.py (Sebastian Falbesoner)
f3c791d2e3 test: refactor: dedup `CBlockHeader` serialization (Sebastian Falbesoner)

Pull request description:

  Similar to what #32421 did for `CTransaction` instances, this PR aims to improve the block hash determination of `CBlockHeader`/`CBlock` (the latter is a subclass of the former) instances by removing the block header caching mechanism and introducing consistent naming. Without the statefulness, sneaky testing bugs like #32742 and #32823 are less likely to happen in the future. Note that performance is even less of an issue here compared to `CTransaction`, as we only need to hash 80 bytes, which is less than typical standard transaction sizes [2].
  The only instance where the testing logic was relying on caching (i.e. we want to return an outdated value) is tackled in the second commit, the rest should be straight-forward to review, especially for contributors who already reviewed #32421.

  Summary table showing block hash determaination before/after this PR:
  | Task                               | master                   | PR           |
  |:-----------------------------------|:-------------------------|:-------------|
  | get block header hash (hex string) | `.hash`[1]               | `.hash_hex`  |
  | get block header hash (integer)    | `rehash()`, `.sha256`[1] | `.hash_int`  |

  [1] = returned value might be `None` or out-of-date, if rehashing function wasn't called after modification
  [2] = the only exception I could think of are transaction with pay-to-anchor (P2A) outputs

ACKs for top commit:
  rkrux:
    re-ACK 5fa34951ea modulo failing CI due to silent merge conflict.
  maflcko:
    re-ACK 5fa34951ea 🎩
  danielabrozzoni:
    reACK 5fa34951ea

Tree-SHA512: 3d13540012654effa063846958a3166d56c1bcb58e1321f52ca4d5c3bcb7abdea72c54d1fb566d04e636d84d06a41d293e16232dbe5d5e78a73c903bb6ffc80d
This commit is contained in:
merge-script committed 2025-07-18 14:24:24 +01:00
commit 672c85cb1e
39 files changed
+240 -277

No files matched your search

+5 -6
View File
@@ -95,7 +95,6 @@ def finish_block(block, signet_solution, grind_cmd):
newheadhex = subprocess.run(cmd, stdout=subprocess.PIPE, input=b"", check=True).stdout.strip() newheadhex = subprocess.run(cmd, stdout=subprocess.PIPE, input=b"", check=True).stdout.strip()
newhead = from_hex(CBlockHeader(), newheadhex.decode('utf8')) newhead = from_hex(CBlockHeader(), newheadhex.decode('utf8'))
block.nNonce = newhead.nNonce block.nNonce = newhead.nNonce
block.rehash()
return block return block
def new_block(tmpl, reward_spk, *, blocktime=None, poolid=None): def new_block(tmpl, reward_spk, *, blocktime=None, poolid=None):
@@ -482,15 +481,15 @@ def do_generate(args):
# report # report
bstr = "block" if gen.is_mine else "backup block" bstr = "block" if gen.is_mine else "backup block"
next_delta = gen.next_block_delta(block.nBits, block.hash) next_delta = gen.next_block_delta(block.nBits, block.hash_hex)
next_delta += block.nTime - time.time() next_delta += block.nTime - time.time()
next_is_mine = gen.next_block_is_mine(block.hash) next_is_mine = gen.next_block_is_mine(block.hash_hex)
logging.debug("Block hash %s payout to %s", block.hash, reward_addr) logging.debug("Block hash %s payout to %s", block.hash_hex, reward_addr)
logging.info("Mined %s at height %d; next in %s (%s)", bstr, tmpl["height"], seconds_to_hms(next_delta), ("mine" if next_is_mine else "backup")) logging.info("Mined %s at height %d; next in %s (%s)", bstr, tmpl["height"], seconds_to_hms(next_delta), ("mine" if next_is_mine else "backup"))
if r != "": if r != "":
logging.warning("submitblock returned %s for height %d hash %s", r, tmpl["height"], block.hash) logging.warning("submitblock returned %s for height %d hash %s", r, tmpl["height"], block.hash_hex)
lastheader = block.hash lastheader = block.hash_hex
def do_calibrate(args): def do_calibrate(args):
if args.nbits is not None and args.seconds is not None: if args.nbits is not None and args.seconds is not None:
+2 -3
View File
@@ -57,8 +57,7 @@ class BaseNode(P2PInterface):
"""Override the standard on_block callback """Override the standard on_block callback
Store the hash of a received block in the dictionary.""" Store the hash of a received block in the dictionary."""
message.block.calc_sha256() self.block_receive_map[message.block.hash_int] += 1
self.block_receive_map[message.block.sha256] += 1
def on_inv(self, message): def on_inv(self, message):
"""Override the standard on_inv callback""" """Override the standard on_inv callback"""
@@ -182,7 +181,7 @@ class ExampleTest(BitcoinTestFramework):
block_message = msg_block(block) block_message = msg_block(block)
# Send message is used to send a P2P message to the node over our P2PInterface # Send message is used to send a P2P message to the node over our P2PInterface
peer_messaging.send_without_ping(block_message) peer_messaging.send_without_ping(block_message)
self.tip = block.sha256 self.tip = block.hash_int
blocks.append(self.tip) blocks.append(self.tip)
self.block_time += 1 self.block_time += 1
height += 1 height += 1
+1 -1
View File
@@ -272,7 +272,7 @@ class AssumeutxoTest(BitcoinTestFramework):
block_time = node0.getblock(node0.getbestblockhash())['time'] + 1 block_time = node0.getblock(node0.getbestblockhash())['time'] + 1
fork_block1 = create_block(int(parent_block_hash, 16), create_coinbase(SNAPSHOT_BASE_HEIGHT), block_time) fork_block1 = create_block(int(parent_block_hash, 16), create_coinbase(SNAPSHOT_BASE_HEIGHT), block_time)
fork_block1.solve() fork_block1.solve()
fork_block2 = create_block(fork_block1.sha256, create_coinbase(SNAPSHOT_BASE_HEIGHT + 1), block_time + 1) fork_block2 = create_block(fork_block1.hash_int, create_coinbase(SNAPSHOT_BASE_HEIGHT + 1), block_time + 1)
fork_block2.solve() fork_block2.solve()
node1.submitheader(fork_block1.serialize().hex()) node1.submitheader(fork_block1.serialize().hex())
node1.submitheader(fork_block2.serialize().hex()) node1.submitheader(fork_block2.serialize().hex())
+6 -6
View File
@@ -103,7 +103,7 @@ class AssumeValidTest(BitcoinTestFramework):
block.solve() block.solve()
# Save the coinbase for later # Save the coinbase for later
self.block1 = block self.block1 = block
self.tip = block.sha256 self.tip = block.hash_int
height += 1 height += 1
# Bury the block 100 deep so the coinbase output is spendable # Bury the block 100 deep so the coinbase output is spendable
@@ -111,7 +111,7 @@ class AssumeValidTest(BitcoinTestFramework):
block = create_block(self.tip, create_coinbase(height), self.block_time) block = create_block(self.tip, create_coinbase(height), self.block_time)
block.solve() block.solve()
self.blocks.append(block) self.blocks.append(block)
self.tip = block.sha256 self.tip = block.hash_int
self.block_time += 1 self.block_time += 1
height += 1 height += 1
@@ -124,7 +124,7 @@ class AssumeValidTest(BitcoinTestFramework):
self.block_time += 1 self.block_time += 1
block102.solve() block102.solve()
self.blocks.append(block102) self.blocks.append(block102)
self.tip = block102.sha256 self.tip = block102.hash_int
self.block_time += 1 self.block_time += 1
height += 1 height += 1
@@ -133,13 +133,13 @@ class AssumeValidTest(BitcoinTestFramework):
block = create_block(self.tip, create_coinbase(height), self.block_time) block = create_block(self.tip, create_coinbase(height), self.block_time)
block.solve() block.solve()
self.blocks.append(block) self.blocks.append(block)
self.tip = block.sha256 self.tip = block.hash_int
self.block_time += 1 self.block_time += 1
height += 1 height += 1
# Start node1 and node2 with assumevalid so they accept a block with a bad signature. # Start node1 and node2 with assumevalid so they accept a block with a bad signature.
self.start_node(1, extra_args=["-assumevalid=" + block102.hash]) self.start_node(1, extra_args=["-assumevalid=" + block102.hash_hex])
self.start_node(2, extra_args=["-assumevalid=" + block102.hash]) self.start_node(2, extra_args=["-assumevalid=" + block102.hash_hex])
p2p0 = self.nodes[0].add_p2p_connection(BaseNode()) p2p0 = self.nodes[0].add_p2p_connection(BaseNode())
p2p0.send_header_for_blocks(self.blocks[0:2000]) p2p0.send_header_for_blocks(self.blocks[0:2000])
+2 -2
View File
@@ -327,7 +327,7 @@ class BIP68Test(BitcoinTestFramework):
for i in range(2): for i in range(2):
block = create_block(tmpl=tmpl, ntime=cur_time) block = create_block(tmpl=tmpl, ntime=cur_time)
block.solve() block.solve()
tip = block.sha256 tip = block.hash_int
assert_equal(None if i == 1 else 'inconclusive', self.nodes[0].submitblock(block.serialize().hex())) assert_equal(None if i == 1 else 'inconclusive', self.nodes[0].submitblock(block.serialize().hex()))
tmpl = self.nodes[0].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS) tmpl = self.nodes[0].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)
tmpl['previousblockhash'] = '%x' % tip tmpl['previousblockhash'] = '%x' % tip
@@ -383,7 +383,7 @@ class BIP68Test(BitcoinTestFramework):
block.solve() block.solve()
assert_equal(None, self.nodes[0].submitblock(block.serialize().hex())) assert_equal(None, self.nodes[0].submitblock(block.serialize().hex()))
assert_equal(self.nodes[0].getbestblockhash(), block.hash) assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
def activateCSV(self): def activateCSV(self):
# activation should happen at block height 432 (3 periods) # activation should happen at block height 432 (3 periods)
+26 -26
View File
@@ -280,7 +280,7 @@ class FullBlockTest(BitcoinTestFramework):
self.send_blocks([b12, b13, b14], success=False, reject_reason='bad-cb-amount', reconnect=True) self.send_blocks([b12, b13, b14], success=False, reject_reason='bad-cb-amount', reconnect=True)
# New tip should be b13. # New tip should be b13.
assert_equal(node.getbestblockhash(), b13.hash) assert_equal(node.getbestblockhash(), b13.hash_hex)
# Add a block with MAX_BLOCK_SIGOPS and one with one more sigop # Add a block with MAX_BLOCK_SIGOPS and one with one more sigop
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
@@ -609,11 +609,11 @@ class FullBlockTest(BitcoinTestFramework):
# The next few blocks are going to be created "by hand" since they'll do funky things, such as having # The next few blocks are going to be created "by hand" since they'll do funky things, such as having
# the first transaction be non-coinbase, etc. The purpose of b44 is to make sure this works. # the first transaction be non-coinbase, etc. The purpose of b44 is to make sure this works.
self.log.info("Build block 44 manually") self.log.info("Build block 44 manually")
height = self.block_heights[self.tip.sha256] + 1 height = self.block_heights[self.tip.hash_int] + 1
coinbase = create_coinbase(height, self.coinbase_pubkey) coinbase = create_coinbase(height, self.coinbase_pubkey)
b44 = CBlock() b44 = CBlock()
b44.nTime = self.tip.nTime + 1 b44.nTime = self.tip.nTime + 1
b44.hashPrevBlock = self.tip.sha256 b44.hashPrevBlock = self.tip.hash_int
b44.nBits = REGTEST_N_BITS b44.nBits = REGTEST_N_BITS
b44.vtx.append(coinbase) b44.vtx.append(coinbase)
tx = self.create_and_sign_transaction(out[14], 1) tx = self.create_and_sign_transaction(out[14], 1)
@@ -621,7 +621,7 @@ class FullBlockTest(BitcoinTestFramework):
b44.hashMerkleRoot = b44.calc_merkle_root() b44.hashMerkleRoot = b44.calc_merkle_root()
b44.solve() b44.solve()
self.tip = b44 self.tip = b44
self.block_heights[b44.sha256] = height self.block_heights[b44.hash_int] = height
self.blocks[44] = b44 self.blocks[44] = b44
self.send_blocks([b44], True) self.send_blocks([b44], True)
@@ -629,12 +629,12 @@ class FullBlockTest(BitcoinTestFramework):
non_coinbase = self.create_tx(out[15], 0, 1) non_coinbase = self.create_tx(out[15], 0, 1)
b45 = CBlock() b45 = CBlock()
b45.nTime = self.tip.nTime + 1 b45.nTime = self.tip.nTime + 1
b45.hashPrevBlock = self.tip.sha256 b45.hashPrevBlock = self.tip.hash_int
b45.nBits = REGTEST_N_BITS b45.nBits = REGTEST_N_BITS
b45.vtx.append(non_coinbase) b45.vtx.append(non_coinbase)
b45.hashMerkleRoot = b45.calc_merkle_root() b45.hashMerkleRoot = b45.calc_merkle_root()
b45.solve() b45.solve()
self.block_heights[b45.sha256] = self.block_heights[self.tip.sha256] + 1 self.block_heights[b45.hash_int] = self.block_heights[self.tip.hash_int] + 1
self.tip = b45 self.tip = b45
self.blocks[45] = b45 self.blocks[45] = b45
self.send_blocks([b45], success=False, reject_reason='bad-cb-missing', reconnect=True) self.send_blocks([b45], success=False, reject_reason='bad-cb-missing', reconnect=True)
@@ -643,12 +643,12 @@ class FullBlockTest(BitcoinTestFramework):
self.move_tip(44) self.move_tip(44)
b46 = CBlock() b46 = CBlock()
b46.nTime = b44.nTime + 1 b46.nTime = b44.nTime + 1
b46.hashPrevBlock = b44.sha256 b46.hashPrevBlock = b44.hash_int
b46.nBits = REGTEST_N_BITS b46.nBits = REGTEST_N_BITS
b46.vtx = [] b46.vtx = []
b46.hashMerkleRoot = 0 b46.hashMerkleRoot = 0
b46.solve() b46.solve()
self.block_heights[b46.sha256] = self.block_heights[b44.sha256] + 1 self.block_heights[b46.hash_int] = self.block_heights[b44.hash_int] + 1
self.tip = b46 self.tip = b46
assert 46 not in self.blocks assert 46 not in self.blocks
self.blocks[46] = b46 self.blocks[46] = b46
@@ -658,10 +658,9 @@ class FullBlockTest(BitcoinTestFramework):
self.move_tip(44) self.move_tip(44)
b47 = self.next_block(47) b47 = self.next_block(47)
target = uint256_from_compact(b47.nBits) target = uint256_from_compact(b47.nBits)
while b47.sha256 <= target: while b47.hash_int <= target:
# Rehash nonces until an invalid too-high-hash block is found. # Rehash nonces until an invalid too-high-hash block is found.
b47.nNonce += 1 b47.nNonce += 1
b47.rehash()
self.send_blocks([b47], False, force_send=True, reject_reason='high-hash', reconnect=True) self.send_blocks([b47], False, force_send=True, reject_reason='high-hash', reconnect=True)
self.log.info("Reject a block with a timestamp >2 hours in the future") self.log.info("Reject a block with a timestamp >2 hours in the future")
@@ -719,8 +718,7 @@ class FullBlockTest(BitcoinTestFramework):
# valid timestamp # valid timestamp
self.move_tip(53) self.move_tip(53)
b55 = self.next_block(55, spend=out[15]) b55 = self.next_block(55, spend=out[15])
b55.nTime = b35.nTime self.update_block(55, [], nTime=b35.nTime)
self.update_block(55, [])
self.send_blocks([b55], True) self.send_blocks([b55], True)
self.save_spendable_output() self.save_spendable_output()
@@ -733,10 +731,10 @@ class FullBlockTest(BitcoinTestFramework):
self.log.info("Accept a previously rejected future block at a later time") self.log.info("Accept a previously rejected future block at a later time")
node.setmocktime(int(time.time()) + 2*60*60) node.setmocktime(int(time.time()) + 2*60*60)
self.move_tip(48) self.move_tip(48)
self.block_heights[b48.sha256] = self.block_heights[b44.sha256] + 1 # b48 is a parent of b44 self.block_heights[b48.hash_int] = self.block_heights[b44.hash_int] + 1 # b48 is a parent of b44
b48p = self.next_block("48p") b48p = self.next_block("48p")
self.send_blocks([b48, b48p], success=True) # Reorg to the longer chain self.send_blocks([b48, b48p], success=True) # Reorg to the longer chain
node.invalidateblock(b48p.hash) # mark b48p as invalid node.invalidateblock(b48p.hash_hex) # mark b48p as invalid
node.setmocktime(0) node.setmocktime(0)
# Test Merkle tree malleability # Test Merkle tree malleability
@@ -780,7 +778,7 @@ class FullBlockTest(BitcoinTestFramework):
self.blocks[56] = b56 self.blocks[56] = b56
assert_equal(len(b56.vtx), 3) assert_equal(len(b56.vtx), 3)
b56 = self.update_block(56, [tx1]) b56 = self.update_block(56, [tx1])
assert_equal(b56.hash, b57.hash) assert_equal(b56.hash_hex, b57.hash_hex)
self.send_blocks([b56], success=False, reject_reason='bad-txns-duplicate', reconnect=True) self.send_blocks([b56], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
# b57p2 - a good block with 6 tx'es, don't submit until end # b57p2 - a good block with 6 tx'es, don't submit until end
@@ -798,7 +796,7 @@ class FullBlockTest(BitcoinTestFramework):
self.move_tip(55) self.move_tip(55)
b56p2 = copy.deepcopy(b57p2) b56p2 = copy.deepcopy(b57p2)
self.blocks["b56p2"] = b56p2 self.blocks["b56p2"] = b56p2
assert_equal(b56p2.hash, b57p2.hash) assert_equal(b56p2.hash_hex, b57p2.hash_hex)
assert_equal(len(b56p2.vtx), 6) assert_equal(len(b56p2.vtx), 6)
b56p2 = self.update_block("b56p2", [tx3, tx4]) b56p2 = self.update_block("b56p2", [tx3, tx4])
self.send_blocks([b56p2], success=False, reject_reason='bad-txns-duplicate', reconnect=True) self.send_blocks([b56p2], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
@@ -956,7 +954,7 @@ class FullBlockTest(BitcoinTestFramework):
self.move_tip('dup_2') self.move_tip('dup_2')
b64 = CBlock(b64a) b64 = CBlock(b64a)
b64.vtx = copy.deepcopy(b64a.vtx) b64.vtx = copy.deepcopy(b64a.vtx)
assert_equal(b64.hash, b64a.hash) assert_equal(b64.hash_hex, b64a.hash_hex)
assert_equal(b64.get_weight(), MAX_BLOCK_WEIGHT) assert_equal(b64.get_weight(), MAX_BLOCK_WEIGHT)
self.blocks[64] = b64 self.blocks[64] = b64
b64 = self.update_block(64, []) b64 = self.update_block(64, [])
@@ -1060,12 +1058,12 @@ class FullBlockTest(BitcoinTestFramework):
b72 = self.update_block(72, [tx1, tx2]) # now tip is 72 b72 = self.update_block(72, [tx1, tx2]) # now tip is 72
b71 = copy.deepcopy(b72) b71 = copy.deepcopy(b72)
b71.vtx.append(tx2) # add duplicate tx2 b71.vtx.append(tx2) # add duplicate tx2
self.block_heights[b71.sha256] = self.block_heights[b69.sha256] + 1 # b71 builds off b69 self.block_heights[b71.hash_int] = self.block_heights[b69.hash_int] + 1 # b71 builds off b69
self.blocks[71] = b71 self.blocks[71] = b71
assert_equal(len(b71.vtx), 4) assert_equal(len(b71.vtx), 4)
assert_equal(len(b72.vtx), 3) assert_equal(len(b72.vtx), 3)
assert_equal(b72.sha256, b71.sha256) assert_equal(b72.hash_int, b71.hash_int)
self.move_tip(71) self.move_tip(71)
self.send_blocks([b71], success=False, reject_reason='bad-txns-duplicate', reconnect=True) self.send_blocks([b71], success=False, reject_reason='bad-txns-duplicate', reconnect=True)
@@ -1370,7 +1368,7 @@ class FullBlockTest(BitcoinTestFramework):
base_block_hash = self.genesis_hash base_block_hash = self.genesis_hash
block_time = int(time.time()) + 1 block_time = int(time.time()) + 1
else: else:
base_block_hash = self.tip.sha256 base_block_hash = self.tip.hash_int
block_time = self.tip.nTime + 1 block_time = self.tip.nTime + 1
# First create the coinbase # First create the coinbase
height = self.block_heights[base_block_hash] + 1 height = self.block_heights[base_block_hash] + 1
@@ -1388,7 +1386,7 @@ class FullBlockTest(BitcoinTestFramework):
# Block is created. Find a valid nonce. # Block is created. Find a valid nonce.
block.solve() block.solve()
self.tip = block self.tip = block
self.block_heights[block.sha256] = height self.block_heights[block.hash_int] = height
assert number not in self.blocks assert number not in self.blocks
self.blocks[number] = block self.blocks[number] = block
return block return block
@@ -1408,17 +1406,19 @@ class FullBlockTest(BitcoinTestFramework):
self.tip = self.blocks[number] self.tip = self.blocks[number]
# adds transactions to the block and updates state # adds transactions to the block and updates state
def update_block(self, block_number, new_transactions): def update_block(self, block_number, new_transactions, *, nTime=None):
block = self.blocks[block_number] block = self.blocks[block_number]
self.add_transactions_to_block(block, new_transactions) self.add_transactions_to_block(block, new_transactions)
old_sha256 = block.sha256 old_hash_int = block.hash_int
if nTime is not None:
block.nTime = nTime
block.hashMerkleRoot = block.calc_merkle_root() block.hashMerkleRoot = block.calc_merkle_root()
block.solve() block.solve()
# Update the internal state just like in next_block # Update the internal state just like in next_block
self.tip = block self.tip = block
if block.sha256 != old_sha256: if block.hash_int != old_hash_int:
self.block_heights[block.sha256] = self.block_heights[old_sha256] self.block_heights[block.hash_int] = self.block_heights[old_hash_int]
del self.block_heights[old_sha256] del self.block_heights[old_hash_int]
self.blocks[block_number] = block self.blocks[block_number] = block
return block return block
+4 -4
View File
@@ -127,15 +127,15 @@ class BIP65Test(BitcoinTestFramework):
self.test_cltv_info(is_active=False) # Not active as of current tip and next block does not need to obey rules self.test_cltv_info(is_active=False) # Not active as of current tip and next block does not need to obey rules
peer.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
self.test_cltv_info(is_active=True) # Not active as of current tip, but next block must obey rules self.test_cltv_info(is_active=True) # Not active as of current tip, but next block must obey rules
assert_equal(self.nodes[0].getbestblockhash(), block.hash) assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
self.log.info("Test that blocks must now be at least version 4") self.log.info("Test that blocks must now be at least version 4")
tip = block.sha256 tip = block.hash_int
block_time += 1 block_time += 1
block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time, version=3) block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time, version=3)
block.solve() block.solve()
with self.nodes[0].assert_debug_log(expected_msgs=[f'{block.hash}, bad-version(0x00000003)']): with self.nodes[0].assert_debug_log(expected_msgs=[f'{block.hash_hex}, bad-version(0x00000003)']):
peer.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
peer.sync_with_ping() peer.sync_with_ping()
@@ -196,7 +196,7 @@ class BIP65Test(BitcoinTestFramework):
self.test_cltv_info(is_active=True) # Not active as of current tip, but next block must obey rules self.test_cltv_info(is_active=True) # Not active as of current tip, but next block must obey rules
peer.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
self.test_cltv_info(is_active=True) # Active as of current tip self.test_cltv_info(is_active=True) # Active as of current tip
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
if __name__ == '__main__': if __name__ == '__main__':
+1 -1
View File
@@ -165,7 +165,7 @@ class BIP68_112_113Test(BitcoinTestFramework):
block = self.create_test_block([]) block = self.create_test_block([])
test_blocks.append(block) test_blocks.append(block)
self.last_block_time += 600 self.last_block_time += 600
self.tip = block.sha256 self.tip = block.hash_int
self.tipheight += 1 self.tipheight += 1
return test_blocks return test_blocks
+4 -4
View File
@@ -92,15 +92,15 @@ class BIP66Test(BitcoinTestFramework):
peer.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
assert_equal(self.nodes[0].getblockcount(), DERSIG_HEIGHT - 1) assert_equal(self.nodes[0].getblockcount(), DERSIG_HEIGHT - 1)
self.test_dersig_info(is_active=True) # Not active as of current tip, but next block must obey rules self.test_dersig_info(is_active=True) # Not active as of current tip, but next block must obey rules
assert_equal(self.nodes[0].getbestblockhash(), block.hash) assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
self.log.info("Test that blocks must now be at least version 3") self.log.info("Test that blocks must now be at least version 3")
tip = block.sha256 tip = block.hash_int
block_time += 1 block_time += 1
block = create_block(tip, create_coinbase(DERSIG_HEIGHT), block_time, version=2) block = create_block(tip, create_coinbase(DERSIG_HEIGHT), block_time, version=2)
block.solve() block.solve()
with self.nodes[0].assert_debug_log(expected_msgs=[f'{block.hash}, bad-version(0x00000002)']): with self.nodes[0].assert_debug_log(expected_msgs=[f'{block.hash_hex}, bad-version(0x00000002)']):
peer.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
peer.sync_with_ping() peer.sync_with_ping()
@@ -146,7 +146,7 @@ class BIP66Test(BitcoinTestFramework):
self.test_dersig_info(is_active=True) # Not active as of current tip, but next block must obey rules self.test_dersig_info(is_active=True) # Not active as of current tip, but next block must obey rules
peer.send_and_ping(msg_block(block)) peer.send_and_ping(msg_block(block))
self.test_dersig_info(is_active=True) # Active as of current tip self.test_dersig_info(is_active=True) # Active as of current tip
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
if __name__ == '__main__': if __name__ == '__main__':
+1 -2
View File
@@ -41,8 +41,7 @@ class TestP2PConn(P2PInterface):
pass pass
def on_block(self, message): def on_block(self, message):
message.block.calc_sha256() self.block_receive_map[message.block.hash_int] += 1
self.block_receive_map[message.block.sha256] += 1
class MaxUploadTest(BitcoinTestFramework): class MaxUploadTest(BitcoinTestFramework):
+2 -2
View File
@@ -143,8 +143,8 @@ class NULLDUMMYTest(BitcoinTestFramework):
block.solve() block.solve()
assert_equal(None if accept else NULLDUMMY_ERROR, node.submitblock(block.serialize().hex())) assert_equal(None if accept else NULLDUMMY_ERROR, node.submitblock(block.serialize().hex()))
if accept: if accept:
assert_equal(node.getbestblockhash(), block.hash) assert_equal(node.getbestblockhash(), block.hash_hex)
self.lastblockhash = block.hash self.lastblockhash = block.hash_hex
self.lastblocktime += 1 self.lastblocktime += 1
self.lastblockheight += 1 self.lastblockheight += 1
else: else:
+1 -1
View File
@@ -58,7 +58,7 @@ def mine_large_blocks(node, n):
# Submit to the node # Submit to the node
node.submitblock(block.serialize().hex()) node.submitblock(block.serialize().hex())
previousblockhash = block.sha256 previousblockhash = block.hash_int
height += 1 height += 1
mine_large_blocks.nTime += 1 mine_large_blocks.nTime += 1
+3 -4
View File
@@ -1341,9 +1341,9 @@ class TaprootTest(BitcoinTestFramework):
if err_msg is not None: if err_msg is not None:
assert block_response is not None and err_msg in block_response, "Missing error message '%s' from block response '%s': %s" % (err_msg, "(None)" if block_response is None else block_response, msg) assert block_response is not None and err_msg in block_response, "Missing error message '%s' from block response '%s': %s" % (err_msg, "(None)" if block_response is None else block_response, msg)
if accept: if accept:
assert node.getbestblockhash() == block.hash, "Failed to accept: %s (response: %s)" % (msg, block_response) assert node.getbestblockhash() == block.hash_hex, "Failed to accept: %s (response: %s)" % (msg, block_response)
self.tip = block.sha256 self.tip = block.hash_int
self.lastblockhash = block.hash self.lastblockhash = block.hash_hex
self.lastblocktime += 1 self.lastblocktime += 1
self.lastblockheight += 1 self.lastblockheight += 1
else: else:
@@ -1574,7 +1574,6 @@ class TaprootTest(BitcoinTestFramework):
assert coinbase.txid_hex == "f60c73405d499a956d3162e3483c395526ef78286458a4cb17b125aa92e49b20" assert coinbase.txid_hex == "f60c73405d499a956d3162e3483c395526ef78286458a4cb17b125aa92e49b20"
# Mine it # Mine it
block = create_block(hashprev=int(self.nodes[0].getbestblockhash(), 16), coinbase=coinbase) block = create_block(hashprev=int(self.nodes[0].getbestblockhash(), 16), coinbase=coinbase)
block.rehash()
block.solve() block.solve()
self.nodes[0].submitblock(block.serialize().hex()) self.nodes[0].submitblock(block.serialize().hex())
assert_equal(self.nodes[0].getblockcount(), 1) assert_equal(self.nodes[0].getblockcount(), 1)
@@ -50,7 +50,7 @@ class VersionBitsWarningTest(BitcoinTestFramework):
peer.send_without_ping(msg_block(block)) peer.send_without_ping(msg_block(block))
block_time += 1 block_time += 1
height += 1 height += 1
tip = block.sha256 tip = block.hash_int
peer.sync_with_ping() peer.sync_with_ping()
def versionbits_in_alert_file(self): def versionbits_in_alert_file(self):
+1 -1
View File
@@ -424,7 +424,7 @@ class ZMQTest (BitcoinTestFramework):
block.solve() block.solve()
assert_equal(self.nodes[0].submitblock(block.serialize().hex()), None) assert_equal(self.nodes[0].submitblock(block.serialize().hex()), None)
tip = self.nodes[0].getbestblockhash() tip = self.nodes[0].getbestblockhash()
assert_equal(int(tip, 16), block.sha256) assert_equal(int(tip, 16), block.hash_int)
orig_txid_2 = self.wallet.send_self_transfer(from_node=self.nodes[0])['txid'] orig_txid_2 = self.wallet.send_self_transfer(from_node=self.nodes[0])['txid']
# Flush old notifications until evicted tx original entry # Flush old notifications until evicted tx original entry
+1 -1
View File
@@ -44,7 +44,7 @@ class MempoolUpdateFromBlockTest(BitcoinTestFramework):
block = create_block(tip, create_coinbase(height + 1), block_time) block = create_block(tip, create_coinbase(height + 1), block_time)
block.solve() block.solve()
blocks.append(block) blocks.append(block)
tip = block.sha256 tip = block.hash_int
block_time += 1 block_time += 1
height += 1 height += 1
+9 -9
View File
@@ -445,25 +445,25 @@ class MiningTest(BitcoinTestFramework):
def chain_tip(b_hash, *, status='headers-only', branchlen=1): def chain_tip(b_hash, *, status='headers-only', branchlen=1):
return {'hash': b_hash, 'height': 202, 'branchlen': branchlen, 'status': status} return {'hash': b_hash, 'height': 202, 'branchlen': branchlen, 'status': status}
assert chain_tip(block.hash) not in node.getchaintips() assert chain_tip(block.hash_hex) not in node.getchaintips()
node.submitheader(hexdata=block.serialize().hex()) node.submitheader(hexdata=block.serialize().hex())
assert chain_tip(block.hash) in node.getchaintips() assert chain_tip(block.hash_hex) in node.getchaintips()
node.submitheader(hexdata=CBlockHeader(block).serialize().hex()) # Noop node.submitheader(hexdata=CBlockHeader(block).serialize().hex()) # Noop
assert chain_tip(block.hash) in node.getchaintips() assert chain_tip(block.hash_hex) in node.getchaintips()
bad_block_root = copy.deepcopy(block) bad_block_root = copy.deepcopy(block)
bad_block_root.hashMerkleRoot += 2 bad_block_root.hashMerkleRoot += 2
bad_block_root.solve() bad_block_root.solve()
assert chain_tip(bad_block_root.hash) not in node.getchaintips() assert chain_tip(bad_block_root.hash_hex) not in node.getchaintips()
node.submitheader(hexdata=CBlockHeader(bad_block_root).serialize().hex()) node.submitheader(hexdata=CBlockHeader(bad_block_root).serialize().hex())
assert chain_tip(bad_block_root.hash) in node.getchaintips() assert chain_tip(bad_block_root.hash_hex) in node.getchaintips()
# Should still reject invalid blocks, even if we have the header: # Should still reject invalid blocks, even if we have the header:
assert_equal(node.submitblock(hexdata=bad_block_root.serialize().hex()), 'bad-txnmrklroot') assert_equal(node.submitblock(hexdata=bad_block_root.serialize().hex()), 'bad-txnmrklroot')
assert_equal(node.submitblock(hexdata=bad_block_root.serialize().hex()), 'bad-txnmrklroot') assert_equal(node.submitblock(hexdata=bad_block_root.serialize().hex()), 'bad-txnmrklroot')
assert chain_tip(bad_block_root.hash) in node.getchaintips() assert chain_tip(bad_block_root.hash_hex) in node.getchaintips()
# We know the header for this invalid block, so should just return early without error: # We know the header for this invalid block, so should just return early without error:
node.submitheader(hexdata=CBlockHeader(bad_block_root).serialize().hex()) node.submitheader(hexdata=CBlockHeader(bad_block_root).serialize().hex())
assert chain_tip(bad_block_root.hash) in node.getchaintips() assert chain_tip(bad_block_root.hash_hex) in node.getchaintips()
bad_block_lock = copy.deepcopy(block) bad_block_lock = copy.deepcopy(block)
bad_block_lock.vtx[0].nLockTime = 2**32 - 1 bad_block_lock.vtx[0].nLockTime = 2**32 - 1
@@ -473,7 +473,7 @@ class MiningTest(BitcoinTestFramework):
assert_equal(node.submitblock(hexdata=bad_block_lock.serialize().hex()), 'duplicate-invalid') assert_equal(node.submitblock(hexdata=bad_block_lock.serialize().hex()), 'duplicate-invalid')
# Build a "good" block on top of the submitted bad block # Build a "good" block on top of the submitted bad block
bad_block2 = copy.deepcopy(block) bad_block2 = copy.deepcopy(block)
bad_block2.hashPrevBlock = bad_block_lock.sha256 bad_block2.hashPrevBlock = bad_block_lock.hash_int
bad_block2.solve() bad_block2.solve()
assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=CBlockHeader(bad_block2).serialize().hex())) assert_raises_rpc_error(-25, 'bad-prevblk', lambda: node.submitheader(hexdata=CBlockHeader(bad_block2).serialize().hex()))
@@ -488,7 +488,7 @@ class MiningTest(BitcoinTestFramework):
peer.wait_for_getheaders(timeout=5, block_hash=block.hashPrevBlock) peer.wait_for_getheaders(timeout=5, block_hash=block.hashPrevBlock)
peer.send_blocks_and_test(blocks=[block], node=node) peer.send_blocks_and_test(blocks=[block], node=node)
# Must be active now: # Must be active now:
assert chain_tip(block.hash, status='active', branchlen=0) in node.getchaintips() assert chain_tip(block.hash_hex, status='active', branchlen=0) in node.getchaintips()
# Building a few blocks should give the same results # Building a few blocks should give the same results
self.generatetoaddress(node, 10, node.get_deterministic_priv_key().address) self.generatetoaddress(node, 10, node.get_deterministic_priv_key().address)
+1 -2
View File
@@ -66,12 +66,11 @@ class MiningMainnetTest(BitcoinTestFramework):
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
block.hashMerkleRoot = block.calc_merkle_root() block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block_hex = block.serialize(with_witness=False).hex() block_hex = block.serialize(with_witness=False).hex()
self.log.debug(block_hex) self.log.debug(block_hex)
assert_equal(node.submitblock(block_hex), None) assert_equal(node.submitblock(block_hex), None)
prev_hash = node.getbestblockhash() prev_hash = node.getbestblockhash()
assert_equal(prev_hash, block.hash) assert_equal(prev_hash, block.hash_hex)
return prev_hash return prev_hash
@@ -156,9 +156,8 @@ class MiningTemplateVerificationTest(BitcoinTestFramework):
self.log.info("Generate a block") self.log.info("Generate a block")
target = uint256_from_compact(block.nBits) target = uint256_from_compact(block.nBits)
# Ensure that it doesn't meet the target by coincidence # Ensure that it doesn't meet the target by coincidence
while block.sha256 <= target: while block.hash_int <= target:
block.nNonce += 1 block.nNonce += 1
block.rehash()
self.log.debug("Found a nonce") self.log.debug("Found a nonce")
self.log.info("A block template doesn't need PoW") self.log.info("A block template doesn't need PoW")
+37 -44
View File
@@ -80,14 +80,12 @@ class TestP2PConn(P2PInterface):
def on_cmpctblock(self, message): def on_cmpctblock(self, message):
self.block_announced = True self.block_announced = True
self.last_message["cmpctblock"].header_and_shortids.header.calc_sha256() self.announced_blockhashes.add(self.last_message["cmpctblock"].header_and_shortids.header.hash_int)
self.announced_blockhashes.add(self.last_message["cmpctblock"].header_and_shortids.header.sha256)
def on_headers(self, message): def on_headers(self, message):
self.block_announced = True self.block_announced = True
for x in self.last_message["headers"].headers: for x in self.last_message["headers"].headers:
x.calc_sha256() self.announced_blockhashes.add(x.hash_int)
self.announced_blockhashes.add(x.sha256)
def on_inv(self, message): def on_inv(self, message):
for x in self.last_message["inv"].inv: for x in self.last_message["inv"].inv:
@@ -160,7 +158,7 @@ class CompactBlocksTest(BitcoinTestFramework):
def make_utxos(self): def make_utxos(self):
block = self.build_block_on_tip(self.nodes[0]) block = self.build_block_on_tip(self.nodes[0])
self.segwit_node.send_and_ping(msg_no_witness_block(block)) self.segwit_node.send_and_ping(msg_no_witness_block(block))
assert int(self.nodes[0].getbestblockhash(), 16) == block.sha256 assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
self.generate(self.wallet, COINBASE_MATURITY) self.generate(self.wallet, COINBASE_MATURITY)
total_value = block.vtx[0].vout[0].nValue total_value = block.vtx[0].vout[0].nValue
@@ -175,7 +173,7 @@ class CompactBlocksTest(BitcoinTestFramework):
block2.hashMerkleRoot = block2.calc_merkle_root() block2.hashMerkleRoot = block2.calc_merkle_root()
block2.solve() block2.solve()
self.segwit_node.send_and_ping(msg_no_witness_block(block2)) self.segwit_node.send_and_ping(msg_no_witness_block(block2))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block2.sha256) assert_equal(self.nodes[0].getbestblockhash(), block2.hash_hex)
self.utxos.extend([[tx.txid_int, i, out_value] for i in range(10)]) self.utxos.extend([[tx.txid_int, i, out_value] for i in range(10)])
@@ -308,7 +306,6 @@ class CompactBlocksTest(BitcoinTestFramework):
# Store the raw block in our internal format. # Store the raw block in our internal format.
block = from_hex(CBlock(), node.getblock("%064x" % block_hash, False)) block = from_hex(CBlock(), node.getblock("%064x" % block_hash, False))
block.rehash()
# Wait until the block was announced (via compact blocks) # Wait until the block was announced (via compact blocks)
test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30) test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30)
@@ -336,8 +333,7 @@ class CompactBlocksTest(BitcoinTestFramework):
def check_compactblock_construction_from_block(self, header_and_shortids, block_hash, block): def check_compactblock_construction_from_block(self, header_and_shortids, block_hash, block):
# Check that we got the right block! # Check that we got the right block!
header_and_shortids.header.calc_sha256() assert_equal(header_and_shortids.header.hash_int, block_hash)
assert_equal(header_and_shortids.header.sha256, block_hash)
# Make sure the prefilled_txn appears to have included the coinbase # Make sure the prefilled_txn appears to have included the coinbase
assert len(header_and_shortids.prefilled_txn) >= 1 assert len(header_and_shortids.prefilled_txn) >= 1
@@ -382,12 +378,12 @@ class CompactBlocksTest(BitcoinTestFramework):
block = self.build_block_on_tip(node) block = self.build_block_on_tip(node)
if announce == "inv": if announce == "inv":
test_node.send_without_ping(msg_inv([CInv(MSG_BLOCK, block.sha256)])) test_node.send_without_ping(msg_inv([CInv(MSG_BLOCK, block.hash_int)]))
test_node.wait_for_getheaders(timeout=30) test_node.wait_for_getheaders(timeout=30)
test_node.send_header_for_blocks([block]) test_node.send_header_for_blocks([block])
else: else:
test_node.send_header_for_blocks([block]) test_node.send_header_for_blocks([block])
test_node.wait_for_getdata([block.sha256], timeout=30) test_node.wait_for_getdata([block.hash_int], timeout=30)
assert_equal(test_node.last_message["getdata"].inv[0].type, 4) assert_equal(test_node.last_message["getdata"].inv[0].type, 4)
# Send back a compactblock message that omits the coinbase # Send back a compactblock message that omits the coinbase
@@ -407,10 +403,10 @@ class CompactBlocksTest(BitcoinTestFramework):
# Send the coinbase, and verify that the tip advances. # Send the coinbase, and verify that the tip advances.
msg = msg_blocktxn() msg = msg_blocktxn()
msg.block_transactions.blockhash = block.sha256 msg.block_transactions.blockhash = block.hash_int
msg.block_transactions.transactions = [block.vtx[0]] msg.block_transactions.transactions = [block.vtx[0]]
test_node.send_and_ping(msg) test_node.send_and_ping(msg)
assert_equal(int(node.getbestblockhash(), 16), block.sha256) assert_equal(node.getbestblockhash(), block.hash_hex)
# Create a chain of transactions from given utxo, and add to a new block. # Create a chain of transactions from given utxo, and add to a new block.
def build_block_with_transactions(self, node, utxo, num_transactions): def build_block_with_transactions(self, node, utxo, num_transactions):
@@ -458,8 +454,8 @@ class CompactBlocksTest(BitcoinTestFramework):
msg_bt = msg_no_witness_blocktxn() msg_bt = msg_no_witness_blocktxn()
msg_bt = msg_blocktxn() # serialize with witnesses msg_bt = msg_blocktxn() # serialize with witnesses
msg_bt.block_transactions = BlockTransactions(block.sha256, block.vtx[1:]) msg_bt.block_transactions = BlockTransactions(block.hash_int, block.vtx[1:])
test_tip_after_message(node, test_node, msg_bt, block.sha256) test_tip_after_message(node, test_node, msg_bt, block.hash_int)
utxo = self.utxos.pop(0) utxo = self.utxos.pop(0)
block = self.build_block_with_transactions(node, utxo, 5) block = self.build_block_with_transactions(node, utxo, 5)
@@ -468,8 +464,8 @@ class CompactBlocksTest(BitcoinTestFramework):
# Now try interspersing the prefilled transactions # Now try interspersing the prefilled transactions
comp_block.initialize_from_block(block, prefill_list=[0, 1, 5], use_witness=True) comp_block.initialize_from_block(block, prefill_list=[0, 1, 5], use_witness=True)
test_getblocktxn_response(comp_block, test_node, [2, 3, 4]) test_getblocktxn_response(comp_block, test_node, [2, 3, 4])
msg_bt.block_transactions = BlockTransactions(block.sha256, block.vtx[2:5]) msg_bt.block_transactions = BlockTransactions(block.hash_int, block.vtx[2:5])
test_tip_after_message(node, test_node, msg_bt, block.sha256) test_tip_after_message(node, test_node, msg_bt, block.hash_int)
# Now try giving one transaction ahead of time. # Now try giving one transaction ahead of time.
utxo = self.utxos.pop(0) utxo = self.utxos.pop(0)
@@ -483,8 +479,8 @@ class CompactBlocksTest(BitcoinTestFramework):
comp_block.initialize_from_block(block, prefill_list=[0, 2, 3, 4], use_witness=True) comp_block.initialize_from_block(block, prefill_list=[0, 2, 3, 4], use_witness=True)
test_getblocktxn_response(comp_block, test_node, [5]) test_getblocktxn_response(comp_block, test_node, [5])
msg_bt.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]]) msg_bt.block_transactions = BlockTransactions(block.hash_int, [block.vtx[5]])
test_tip_after_message(node, test_node, msg_bt, block.sha256) test_tip_after_message(node, test_node, msg_bt, block.hash_int)
# Now provide all transactions to the node before the block is # Now provide all transactions to the node before the block is
# announced and verify reconstruction happens immediately. # announced and verify reconstruction happens immediately.
@@ -505,7 +501,7 @@ class CompactBlocksTest(BitcoinTestFramework):
# Send compact block # Send compact block
comp_block.initialize_from_block(block, prefill_list=[0], use_witness=True) comp_block.initialize_from_block(block, prefill_list=[0], use_witness=True)
test_tip_after_message(node, test_node, msg_cmpctblock(comp_block.to_p2p()), block.sha256) test_tip_after_message(node, test_node, msg_cmpctblock(comp_block.to_p2p()), block.hash_int)
with p2p_lock: with p2p_lock:
# Shouldn't have gotten a request for any transaction # Shouldn't have gotten a request for any transaction
assert "getblocktxn" not in test_node.last_message assert "getblocktxn" not in test_node.last_message
@@ -546,20 +542,20 @@ class CompactBlocksTest(BitcoinTestFramework):
# verifying that the block isn't marked bad permanently. This is good # verifying that the block isn't marked bad permanently. This is good
# enough for now. # enough for now.
msg = msg_blocktxn() msg = msg_blocktxn()
msg.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]] + block.vtx[7:]) msg.block_transactions = BlockTransactions(block.hash_int, [block.vtx[5]] + block.vtx[7:])
test_node.send_and_ping(msg) test_node.send_and_ping(msg)
# Tip should not have updated # Tip should not have updated
assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock)
# We should receive a getdata request # We should receive a getdata request
test_node.wait_for_getdata([block.sha256], timeout=10) test_node.wait_for_getdata([block.hash_int], timeout=10)
assert test_node.last_message["getdata"].inv[0].type == MSG_BLOCK or \ assert test_node.last_message["getdata"].inv[0].type == MSG_BLOCK or \
test_node.last_message["getdata"].inv[0].type == MSG_BLOCK | MSG_WITNESS_FLAG test_node.last_message["getdata"].inv[0].type == MSG_BLOCK | MSG_WITNESS_FLAG
# Deliver the block # Deliver the block
test_node.send_and_ping(msg_block(block)) test_node.send_and_ping(msg_block(block))
assert_equal(int(node.getbestblockhash(), 16), block.sha256) assert_equal(node.getbestblockhash(), block.hash_hex)
def test_getblocktxn_handler(self, test_node): def test_getblocktxn_handler(self, test_node):
node = self.nodes[0] node = self.nodes[0]
@@ -599,8 +595,7 @@ class CompactBlocksTest(BitcoinTestFramework):
test_node.last_message.pop("blocktxn", None) test_node.last_message.pop("blocktxn", None)
test_node.send_and_ping(msg) test_node.send_and_ping(msg)
with p2p_lock: with p2p_lock:
test_node.last_message["block"].block.calc_sha256() assert_equal(test_node.last_message["block"].block.hash_hex, block_hash)
assert_equal(test_node.last_message["block"].block.sha256, int(block_hash, 16))
assert "blocktxn" not in test_node.last_message assert "blocktxn" not in test_node.last_message
# Request with out-of-bounds tx index results in disconnect # Request with out-of-bounds tx index results in disconnect
@@ -628,7 +623,7 @@ class CompactBlocksTest(BitcoinTestFramework):
tips = node.getchaintips() tips = node.getchaintips()
found = False found = False
for x in tips: for x in tips:
if x["hash"] == block.hash: if x["hash"] == block.hash_hex:
found = True found = True
break break
assert not found assert not found
@@ -656,8 +651,7 @@ class CompactBlocksTest(BitcoinTestFramework):
test_node.send_without_ping(msg_getdata([CInv(MSG_CMPCT_BLOCK, int(new_blocks[0], 16))])) test_node.send_without_ping(msg_getdata([CInv(MSG_CMPCT_BLOCK, int(new_blocks[0], 16))]))
test_node.wait_until(lambda: "block" in test_node.last_message, timeout=30) test_node.wait_until(lambda: "block" in test_node.last_message, timeout=30)
with p2p_lock: with p2p_lock:
test_node.last_message["block"].block.calc_sha256() assert_equal(test_node.last_message["block"].block.hash_hex, new_blocks[0])
assert_equal(test_node.last_message["block"].block.sha256, int(new_blocks[0], 16))
# Generate an old compactblock, and verify that it's not accepted. # Generate an old compactblock, and verify that it's not accepted.
cur_height = node.getblockcount() cur_height = node.getblockcount()
@@ -673,7 +667,7 @@ class CompactBlocksTest(BitcoinTestFramework):
tips = node.getchaintips() tips = node.getchaintips()
found = False found = False
for x in tips: for x in tips:
if x["hash"] == block.hash: if x["hash"] == block.hash_hex:
assert_equal(x["status"], "headers-only") assert_equal(x["status"], "headers-only")
found = True found = True
break break
@@ -682,7 +676,7 @@ class CompactBlocksTest(BitcoinTestFramework):
# Requesting this block via getblocktxn should silently fail # Requesting this block via getblocktxn should silently fail
# (to avoid fingerprinting attacks). # (to avoid fingerprinting attacks).
msg = msg_getblocktxn() msg = msg_getblocktxn()
msg.block_txn_request = BlockTransactionsRequest(block.sha256, [0]) msg.block_txn_request = BlockTransactionsRequest(block.hash_int, [0])
with p2p_lock: with p2p_lock:
test_node.last_message.pop("blocktxn", None) test_node.last_message.pop("blocktxn", None)
test_node.send_and_ping(msg) test_node.send_and_ping(msg)
@@ -705,8 +699,7 @@ class CompactBlocksTest(BitcoinTestFramework):
l.wait_until(lambda: "cmpctblock" in l.last_message, timeout=30) l.wait_until(lambda: "cmpctblock" in l.last_message, timeout=30)
with p2p_lock: with p2p_lock:
for l in listeners: for l in listeners:
l.last_message["cmpctblock"].header_and_shortids.header.calc_sha256() assert_equal(l.last_message["cmpctblock"].header_and_shortids.header.hash_int, block.hash_int)
assert_equal(l.last_message["cmpctblock"].header_and_shortids.header.sha256, block.sha256)
# Test that we don't get disconnected if we relay a compact block with valid header, # Test that we don't get disconnected if we relay a compact block with valid header,
# but invalid transactions. # but invalid transactions.
@@ -731,7 +724,7 @@ class CompactBlocksTest(BitcoinTestFramework):
test_node.send_and_ping(msg) test_node.send_and_ping(msg)
# Check that the tip didn't advance # Check that the tip didn't advance
assert_not_equal(int(node.getbestblockhash(), 16), block.sha256) assert_not_equal(node.getbestblockhash(), block.hash_hex)
test_node.sync_with_ping() test_node.sync_with_ping()
# Helper for enabling cb announcements # Helper for enabling cb announcements
@@ -768,7 +761,7 @@ class CompactBlocksTest(BitcoinTestFramework):
assert tx.txid_hex in mempool assert tx.txid_hex in mempool
delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p()))
assert_equal(int(node.getbestblockhash(), 16), block.sha256) assert_equal(node.getbestblockhash(), block.hash_hex)
self.utxos.append([block.vtx[-1].txid_int, 0, block.vtx[-1].vout[0].nValue]) self.utxos.append([block.vtx[-1].txid_int, 0, block.vtx[-1].vout[0].nValue])
@@ -784,13 +777,13 @@ class CompactBlocksTest(BitcoinTestFramework):
cmpct_block.use_witness = True cmpct_block.use_witness = True
delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p()))
assert_not_equal(int(node.getbestblockhash(), 16), block.sha256) assert_not_equal(node.getbestblockhash(), block.hash_hex)
msg = msg_no_witness_blocktxn() msg = msg_no_witness_blocktxn()
msg.block_transactions.blockhash = block.sha256 msg.block_transactions.blockhash = block.hash_int
msg.block_transactions.transactions = block.vtx[1:] msg.block_transactions.transactions = block.vtx[1:]
stalling_peer.send_and_ping(msg) stalling_peer.send_and_ping(msg)
assert_equal(int(node.getbestblockhash(), 16), block.sha256) assert_equal(node.getbestblockhash(), block.hash_hex)
def test_highbandwidth_mode_states_via_getpeerinfo(self): def test_highbandwidth_mode_states_via_getpeerinfo(self):
# create new p2p connection for a fresh state w/o any prior sendcmpct messages sent # create new p2p connection for a fresh state w/o any prior sendcmpct messages sent
@@ -843,10 +836,10 @@ class CompactBlocksTest(BitcoinTestFramework):
self.log.info(f"Setting {name} as high bandwidth peer") self.log.info(f"Setting {name} as high bandwidth peer")
block, cmpct_block = announce_cmpct_block(node, peer, 1) block, cmpct_block = announce_cmpct_block(node, peer, 1)
msg = msg_blocktxn() msg = msg_blocktxn()
msg.block_transactions.blockhash = block.sha256 msg.block_transactions.blockhash = block.hash_int
msg.block_transactions.transactions = block.vtx[1:] msg.block_transactions.transactions = block.vtx[1:]
peer.send_and_ping(msg) peer.send_and_ping(msg)
assert_equal(int(node.getbestblockhash(), 16), block.sha256) assert_equal(node.getbestblockhash(), block.hash_hex)
peer.clear_getblocktxn() peer.clear_getblocktxn()
# Test the simple parallel download case... # Test the simple parallel download case...
@@ -861,26 +854,26 @@ class CompactBlocksTest(BitcoinTestFramework):
with p2p_lock: with p2p_lock:
# The second peer to announce should still get a getblocktxn # The second peer to announce should still get a getblocktxn
assert "getblocktxn" in delivery_peer.last_message assert "getblocktxn" in delivery_peer.last_message
assert_not_equal(int(node.getbestblockhash(), 16), block.sha256) assert_not_equal(node.getbestblockhash(), block.hash_hex)
inbound_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) inbound_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p()))
with p2p_lock: with p2p_lock:
# The third inbound peer to announce should *not* get a getblocktxn # The third inbound peer to announce should *not* get a getblocktxn
assert "getblocktxn" not in inbound_peer.last_message assert "getblocktxn" not in inbound_peer.last_message
assert_not_equal(int(node.getbestblockhash(), 16), block.sha256) assert_not_equal(node.getbestblockhash(), block.hash_hex)
outbound_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) outbound_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p()))
with p2p_lock: with p2p_lock:
# The third peer to announce should get a getblocktxn if outbound # The third peer to announce should get a getblocktxn if outbound
assert "getblocktxn" in outbound_peer.last_message assert "getblocktxn" in outbound_peer.last_message
assert_not_equal(int(node.getbestblockhash(), 16), block.sha256) assert_not_equal(node.getbestblockhash(), block.hash_hex)
# Second peer completes the compact block first # Second peer completes the compact block first
msg = msg_blocktxn() msg = msg_blocktxn()
msg.block_transactions.blockhash = block.sha256 msg.block_transactions.blockhash = block.hash_int
msg.block_transactions.transactions = block.vtx[1:] msg.block_transactions.transactions = block.vtx[1:]
delivery_peer.send_and_ping(msg) delivery_peer.send_and_ping(msg)
assert_equal(int(node.getbestblockhash(), 16), block.sha256) assert_equal(node.getbestblockhash(), block.hash_hex)
# Nothing bad should happen if we get a late fill from the first peer... # Nothing bad should happen if we get a late fill from the first peer...
stalling_peer.send_and_ping(msg) stalling_peer.send_and_ping(msg)
@@ -36,7 +36,6 @@ class P2PCompactBlocksBlocksOnly(BitcoinTestFramework):
blockhash = self.generate(self.nodes[2], 1, sync_fun=self.no_op)[0] blockhash = self.generate(self.nodes[2], 1, sync_fun=self.no_op)[0]
block_hex = self.nodes[2].getblock(blockhash=blockhash, verbosity=0) block_hex = self.nodes[2].getblock(blockhash=blockhash, verbosity=0)
block = from_hex(CBlock(), block_hex) block = from_hex(CBlock(), block_hex)
block.rehash()
return block return block
def run_test(self): def run_test(self):
@@ -73,14 +72,14 @@ class P2PCompactBlocksBlocksOnly(BitcoinTestFramework):
# A -blocksonly node should not request BIP152 high bandwidth mode upon # A -blocksonly node should not request BIP152 high bandwidth mode upon
# receiving a new valid block at the tip. # receiving a new valid block at the tip.
p2p_conn_blocksonly.send_and_ping(msg_block(block0)) p2p_conn_blocksonly.send_and_ping(msg_block(block0))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block0.sha256) assert_equal(self.nodes[0].getbestblockhash(), block0.hash_hex)
assert_equal(p2p_conn_blocksonly.message_count['sendcmpct'], 1) assert_equal(p2p_conn_blocksonly.message_count['sendcmpct'], 1)
assert_equal(p2p_conn_blocksonly.last_message['sendcmpct'].announce, False) assert_equal(p2p_conn_blocksonly.last_message['sendcmpct'].announce, False)
# A normal node participating in transaction relay should request BIP152 # A normal node participating in transaction relay should request BIP152
# high bandwidth mode upon receiving a new valid block at the tip. # high bandwidth mode upon receiving a new valid block at the tip.
p2p_conn_high_bw.send_and_ping(msg_block(block0)) p2p_conn_high_bw.send_and_ping(msg_block(block0))
assert_equal(int(self.nodes[1].getbestblockhash(), 16), block0.sha256) assert_equal(self.nodes[1].getbestblockhash(), block0.hash_hex)
p2p_conn_high_bw.wait_until(lambda: p2p_conn_high_bw.message_count['sendcmpct'] == 2) p2p_conn_high_bw.wait_until(lambda: p2p_conn_high_bw.message_count['sendcmpct'] == 2)
assert_equal(p2p_conn_high_bw.last_message['sendcmpct'].announce, True) assert_equal(p2p_conn_high_bw.last_message['sendcmpct'].announce, True)
@@ -94,25 +93,25 @@ class P2PCompactBlocksBlocksOnly(BitcoinTestFramework):
block1 = self.build_block_on_tip() block1 = self.build_block_on_tip()
p2p_conn_blocksonly.send_and_ping(msg_headers(headers=[CBlockHeader(block1)])) p2p_conn_blocksonly.send_and_ping(msg_headers(headers=[CBlockHeader(block1)]))
assert_equal(p2p_conn_blocksonly.last_message['getdata'].inv, [CInv(MSG_BLOCK | MSG_WITNESS_FLAG, block1.sha256)]) assert_equal(p2p_conn_blocksonly.last_message['getdata'].inv, [CInv(MSG_BLOCK | MSG_WITNESS_FLAG, block1.hash_int)])
p2p_conn_high_bw.send_and_ping(msg_headers(headers=[CBlockHeader(block1)])) p2p_conn_high_bw.send_and_ping(msg_headers(headers=[CBlockHeader(block1)]))
assert_equal(p2p_conn_high_bw.last_message['getdata'].inv, [CInv(MSG_CMPCT_BLOCK, block1.sha256)]) assert_equal(p2p_conn_high_bw.last_message['getdata'].inv, [CInv(MSG_CMPCT_BLOCK, block1.hash_int)])
self.log.info("Test that getdata(CMPCT) is still sent on BIP152 low bandwidth connections" self.log.info("Test that getdata(CMPCT) is still sent on BIP152 low bandwidth connections"
" when no -blocksonly nodes are involved") " when no -blocksonly nodes are involved")
p2p_conn_low_bw.send_and_ping(msg_headers(headers=[CBlockHeader(block1)])) p2p_conn_low_bw.send_and_ping(msg_headers(headers=[CBlockHeader(block1)]))
assert_equal(p2p_conn_low_bw.last_message['getdata'].inv, [CInv(MSG_CMPCT_BLOCK, block1.sha256)]) assert_equal(p2p_conn_low_bw.last_message['getdata'].inv, [CInv(MSG_CMPCT_BLOCK, block1.hash_int)])
self.log.info("Test that -blocksonly nodes still serve compact blocks") self.log.info("Test that -blocksonly nodes still serve compact blocks")
def test_for_cmpctblock(block): def test_for_cmpctblock(block):
if 'cmpctblock' not in p2p_conn_blocksonly.last_message: if 'cmpctblock' not in p2p_conn_blocksonly.last_message:
return False return False
return p2p_conn_blocksonly.last_message['cmpctblock'].header_and_shortids.header.rehash() == block.sha256 return p2p_conn_blocksonly.last_message['cmpctblock'].header_and_shortids.header.hash_int == block.hash_int
p2p_conn_blocksonly.send_without_ping(msg_getdata([CInv(MSG_CMPCT_BLOCK, block0.sha256)])) p2p_conn_blocksonly.send_without_ping(msg_getdata([CInv(MSG_CMPCT_BLOCK, block0.hash_int)]))
p2p_conn_blocksonly.wait_until(lambda: test_for_cmpctblock(block0)) p2p_conn_blocksonly.wait_until(lambda: test_for_cmpctblock(block0))
# Request BIP152 high bandwidth mode from the -blocksonly node. # Request BIP152 high bandwidth mode from the -blocksonly node.
+2 -2
View File
@@ -41,7 +41,7 @@ class P2PFingerprintTest(BitcoinTestFramework):
block.solve() block.solve()
blocks.append(block) blocks.append(block)
prev_hash = block.hash prev_hash = block.hash_hex
prev_height += 1 prev_height += 1
prev_median_time = block_time prev_median_time = block_time
return blocks return blocks
@@ -79,7 +79,7 @@ class P2PFingerprintTest(BitcoinTestFramework):
# Force reorg to a longer chain # Force reorg to a longer chain
node0.send_without_ping(msg_headers(new_blocks)) node0.send_without_ping(msg_headers(new_blocks))
node0.wait_for_getdata([x.sha256 for x in new_blocks]) node0.wait_for_getdata([x.hash_int for x in new_blocks])
for block in new_blocks: for block in new_blocks:
node0.send_and_ping(msg_block(block)) node0.send_and_ping(msg_block(block))
+1 -2
View File
@@ -19,8 +19,7 @@ class P2PStoreBlock(P2PInterface):
self.blocks = defaultdict(int) self.blocks = defaultdict(int)
def on_block(self, message): def on_block(self, message):
message.block.calc_sha256() self.blocks[message.block.hash_int] += 1
self.blocks[message.block.sha256] += 1
class GetdataTest(BitcoinTestFramework): class GetdataTest(BitcoinTestFramework):
@@ -129,7 +129,7 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework):
block = create_block(hashprev = hashPrevBlock, tmpl=node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)) block = create_block(hashprev = hashPrevBlock, tmpl=node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS))
block.solve() block.solve()
new_blocks.append(block) new_blocks.append(block)
hashPrevBlock = block.sha256 hashPrevBlock = block.hash_int
headers_message = msg_headers(headers=new_blocks) headers_message = msg_headers(headers=new_blocks)
p2p.send_and_ping(headers_message) p2p.send_and_ping(headers_message)
+3 -3
View File
@@ -62,11 +62,11 @@ class P2PIBDStallingTest(BitcoinTestFramework):
for _ in range(NUM_BLOCKS): for _ in range(NUM_BLOCKS):
blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve() blocks[-1].solve()
tip = blocks[-1].sha256 tip = blocks[-1].hash_int
block_time += 1 block_time += 1
height += 1 height += 1
block_dict[blocks[-1].sha256] = blocks[-1] block_dict[blocks[-1].hash_int] = blocks[-1]
stall_block = blocks[0].sha256 stall_block = blocks[0].hash_int
headers_message = msg_headers() headers_message = msg_headers()
headers_message.headers = [CBlockHeader(b) for b in blocks[:NUM_BLOCKS-1]] headers_message.headers = [CBlockHeader(b) for b in blocks[:NUM_BLOCKS-1]]
+3 -3
View File
@@ -77,13 +77,13 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
block2 = create_block(tip, create_coinbase(height), block_time, txlist=[tx1, tx2]) block2 = create_block(tip, create_coinbase(height), block_time, txlist=[tx1, tx2])
block_time += 1 block_time += 1
block2.solve() block2.solve()
orig_hash = block2.sha256 orig_hash = block2.hash_int
block2_orig = copy.deepcopy(block2) block2_orig = copy.deepcopy(block2)
# Mutate block 2 # Mutate block 2
block2.vtx.append(tx2) block2.vtx.append(tx2)
assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root()) assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root())
assert_equal(orig_hash, block2.rehash()) assert_equal(orig_hash, block2.hash_int)
assert_not_equal(block2_orig.vtx, block2.vtx) assert_not_equal(block2_orig.vtx, block2.vtx)
peer.send_blocks_and_test([block2], node, success=False, reject_reason='bad-txns-duplicate') peer.send_blocks_and_test([block2], node, success=False, reject_reason='bad-txns-duplicate')
@@ -115,7 +115,7 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
# Update tip info # Update tip info
height += 1 height += 1
block_time += 1 block_time += 1
tip = int(block2_orig.hash, 16) tip = block2_orig.hash_int
# Complete testing of CVE-2018-17144, by checking for the inflation bug. # Complete testing of CVE-2018-17144, by checking for the inflation bug.
# Create a block that spends the output of a tx in a previous block. # Create a block that spends the output of a tx in a previous block.
+3 -6
View File
@@ -288,21 +288,18 @@ class InvalidMessagesTest(BitcoinTestFramework):
blockheader.hashPrevBlock = int(blockheader_tip_hash, 16) blockheader.hashPrevBlock = int(blockheader_tip_hash, 16)
blockheader.nTime = int(time.time()) blockheader.nTime = int(time.time())
blockheader.nBits = blockheader_tip.nBits blockheader.nBits = blockheader_tip.nBits
blockheader.rehash() while not blockheader.hash_hex.startswith('0'):
while not blockheader.hash.startswith('0'):
blockheader.nNonce += 1 blockheader.nNonce += 1
blockheader.rehash()
peer = self.nodes[0].add_p2p_connection(P2PInterface()) peer = self.nodes[0].add_p2p_connection(P2PInterface())
peer.send_and_ping(msg_headers([blockheader])) peer.send_and_ping(msg_headers([blockheader]))
assert_equal(self.nodes[0].getblockchaininfo()['headers'], 1) assert_equal(self.nodes[0].getblockchaininfo()['headers'], 1)
chaintips = self.nodes[0].getchaintips() chaintips = self.nodes[0].getchaintips()
assert_equal(chaintips[0]['status'], 'headers-only') assert_equal(chaintips[0]['status'], 'headers-only')
assert_equal(chaintips[0]['hash'], blockheader.hash) assert_equal(chaintips[0]['hash'], blockheader.hash_hex)
# invalidate PoW # invalidate PoW
while not blockheader.hash.startswith('f'): while not blockheader.hash_hex.startswith('f'):
blockheader.nNonce += 1 blockheader.nNonce += 1
blockheader.rehash()
with self.nodes[0].assert_debug_log(['Misbehaving', 'header with invalid proof of work']): with self.nodes[0].assert_debug_log(['Misbehaving', 'header with invalid proof of work']):
peer.send_without_ping(msg_headers([blockheader])) peer.send_without_ping(msg_headers([blockheader]))
peer.wait_for_disconnect() peer.wait_for_disconnect()
+3 -3
View File
@@ -68,7 +68,7 @@ class MutatedBlocksTest(BitcoinTestFramework):
return False return False
get_block_txn = honest_relayer.last_message['getblocktxn'] get_block_txn = honest_relayer.last_message['getblocktxn']
return get_block_txn.block_txn_request.blockhash == block.sha256 and \ return get_block_txn.block_txn_request.blockhash == block.hash_int and \
get_block_txn.block_txn_request.indexes == [1] get_block_txn.block_txn_request.indexes == [1]
honest_relayer.wait_until(self_transfer_requested, timeout=5) honest_relayer.wait_until(self_transfer_requested, timeout=5)
@@ -93,9 +93,9 @@ class MutatedBlocksTest(BitcoinTestFramework):
# The honest relayer should be able to complete relaying the block by # The honest relayer should be able to complete relaying the block by
# sending the blocktxn that was requested. # sending the blocktxn that was requested.
block_txn = msg_blocktxn() block_txn = msg_blocktxn()
block_txn.block_transactions = BlockTransactions(blockhash=block.sha256, transactions=[tx]) block_txn.block_transactions = BlockTransactions(blockhash=block.hash_int, transactions=[tx])
honest_relayer.send_and_ping(block_txn) honest_relayer.send_and_ping(block_txn)
assert_equal(self.nodes[0].getbestblockhash(), block.hash) assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
# Check that unexpected-witness mutation check doesn't trigger on a header that doesn't connect to anything # Check that unexpected-witness mutation check doesn't trigger on a header that doesn't connect to anything
assert_equal(len(self.nodes[0].getpeerinfo()), 1) assert_equal(len(self.nodes[0].getpeerinfo()), 1)
+2 -2
View File
@@ -190,7 +190,7 @@ class P2POutEvict(BitcoinTestFramework):
self.log.info("Mine a new block and keep the unprotected honest peer on sync, all the rest off-sync") self.log.info("Mine a new block and keep the unprotected honest peer on sync, all the rest off-sync")
# Mine a block so all peers become outdated # Mine a block so all peers become outdated
target_hash = prev_header.rehash() target_hash = prev_header.hash_int
tip_hash = self.generateblock(node, output="raw(42)", transactions=[])["hash"] tip_hash = self.generateblock(node, output="raw(42)", transactions=[])["hash"]
tip_header = from_hex(CBlockHeader(), node.getblockheader(tip_hash, False)) tip_header = from_hex(CBlockHeader(), node.getblockheader(tip_hash, False))
tip_headers_message = msg_headers([tip_header]) tip_headers_message = msg_headers([tip_header])
@@ -235,7 +235,7 @@ class P2POutEvict(BitcoinTestFramework):
cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1)
node.setmocktime(cur_mock_time) node.setmocktime(cur_mock_time)
peer.sync_with_ping() peer.sync_with_ping()
peer.wait_for_getheaders(block_hash=tip_header.rehash()) peer.wait_for_getheaders(block_hash=tip_header.hash_int)
cur_mock_time += (HEADERS_RESPONSE_TIME + 1) cur_mock_time += (HEADERS_RESPONSE_TIME + 1)
node.setmocktime(cur_mock_time) node.setmocktime(cur_mock_time)
self.log.info("Test that the peer gets evicted") self.log.info("Test that the peer gets evicted")
+15 -16
View File
@@ -143,7 +143,7 @@ def test_witness_block(node, p2p, block, accepted, with_witness=True, reason=Non
reason = [reason] if reason else [] reason = [reason] if reason else []
with node.assert_debug_log(expected_msgs=reason): with node.assert_debug_log(expected_msgs=reason):
p2p.send_and_ping(msg_block(block) if with_witness else msg_no_witness_block(block)) p2p.send_and_ping(msg_block(block) if with_witness else msg_no_witness_block(block))
assert_equal(node.getbestblockhash() == block.hash, accepted) assert_equal(node.getbestblockhash() == block.hash_hex, accepted)
class TestP2PConn(P2PInterface): class TestP2PConn(P2PInterface):
@@ -195,10 +195,10 @@ class TestP2PConn(P2PInterface):
if use_header: if use_header:
self.send_without_ping(msg) self.send_without_ping(msg)
else: else:
self.send_without_ping(msg_inv(inv=[CInv(MSG_BLOCK, block.sha256)])) self.send_without_ping(msg_inv(inv=[CInv(MSG_BLOCK, block.hash_int)]))
self.wait_for_getheaders(block_hash=block.hashPrevBlock, timeout=timeout) self.wait_for_getheaders(block_hash=block.hashPrevBlock, timeout=timeout)
self.send_without_ping(msg) self.send_without_ping(msg)
self.wait_for_getdata([block.sha256], timeout=timeout) self.wait_for_getdata([block.hash_int], timeout=timeout)
def request_block(self, blockhash, inv_type, timeout=60): def request_block(self, blockhash, inv_type, timeout=60):
with p2p_lock: with p2p_lock:
@@ -230,7 +230,6 @@ class SegWitTest(BitcoinTestFramework):
height = self.nodes[0].getblockcount() + 1 height = self.nodes[0].getblockcount() + 1
block_time = self.nodes[0].getblockheader(tip)["mediantime"] + 1 block_time = self.nodes[0].getblockheader(tip)["mediantime"] + 1
block = create_block(int(tip, 16), create_coinbase(height), block_time) block = create_block(int(tip, 16), create_coinbase(height), block_time)
block.rehash()
return block return block
def update_witness_block_with_transactions(self, block, tx_list, nonce=0): def update_witness_block_with_transactions(self, block, tx_list, nonce=0):
@@ -347,7 +346,7 @@ class SegWitTest(BitcoinTestFramework):
# But it should not be permanently marked bad... # But it should not be permanently marked bad...
# Resend without witness information. # Resend without witness information.
self.test_node.send_and_ping(msg_no_witness_block(block)) # make sure the block was processed self.test_node.send_and_ping(msg_no_witness_block(block)) # make sure the block was processed
assert_equal(self.nodes[0].getbestblockhash(), block.hash) assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
# Update our utxo list; we spent the first entry. # Update our utxo list; we spent the first entry.
self.utxo.pop(0) self.utxo.pop(0)
@@ -414,15 +413,15 @@ class SegWitTest(BitcoinTestFramework):
assert len(block.vtx[0].wit.vtxinwit[0].scriptWitness.stack) == 1 assert len(block.vtx[0].wit.vtxinwit[0].scriptWitness.stack) == 1
test_witness_block(self.nodes[0], self.test_node, block, accepted=True) test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
# Now try to retrieve it... # Now try to retrieve it...
rpc_block = self.nodes[0].getblock(block.hash, False) rpc_block = self.nodes[0].getblock(block.hash_hex, False)
non_wit_block = self.test_node.request_block(block.sha256, 2) non_wit_block = self.test_node.request_block(block.hash_int, 2)
wit_block = self.test_node.request_block(block.sha256, 2 | MSG_WITNESS_FLAG) wit_block = self.test_node.request_block(block.hash_int, 2 | MSG_WITNESS_FLAG)
assert_equal(wit_block.serialize(), bytes.fromhex(rpc_block)) assert_equal(wit_block.serialize(), bytes.fromhex(rpc_block))
assert_equal(wit_block.serialize(False), non_wit_block.serialize()) assert_equal(wit_block.serialize(False), non_wit_block.serialize())
assert_equal(wit_block.serialize(), block.serialize()) assert_equal(wit_block.serialize(), block.serialize())
# Test size, vsize, weight # Test size, vsize, weight
rpc_details = self.nodes[0].getblock(block.hash, True) rpc_details = self.nodes[0].getblock(block.hash_hex, True)
assert_equal(rpc_details["size"], len(block.serialize())) assert_equal(rpc_details["size"], len(block.serialize()))
assert_equal(rpc_details["strippedsize"], len(block.serialize(False))) assert_equal(rpc_details["strippedsize"], len(block.serialize(False)))
assert_equal(rpc_details["weight"], block.get_weight()) assert_equal(rpc_details["weight"], block.get_weight())
@@ -444,7 +443,7 @@ class SegWitTest(BitcoinTestFramework):
msg.headers = [CBlockHeader(block4)] msg.headers = [CBlockHeader(block4)]
self.old_node.send_without_ping(msg) self.old_node.send_without_ping(msg)
self.old_node.announce_tx_and_wait_for_getdata(block4.vtx[0]) self.old_node.announce_tx_and_wait_for_getdata(block4.vtx[0])
assert block4.sha256 not in self.old_node.getdataset assert block4.hash_int not in self.old_node.getdataset
@subtest @subtest
def test_v0_outputs_arent_spendable(self): def test_v0_outputs_arent_spendable(self):
@@ -820,13 +819,13 @@ class SegWitTest(BitcoinTestFramework):
# TODO: repeat this test with a block that can be relayed # TODO: repeat this test with a block that can be relayed
assert_equal('bad-witness-nonce-size', self.nodes[0].submitblock(block.serialize().hex())) assert_equal('bad-witness-nonce-size', self.nodes[0].submitblock(block.serialize().hex()))
assert_not_equal(self.nodes[0].getbestblockhash(), block.hash) assert_not_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.pop() block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.pop()
assert block.get_weight() < MAX_BLOCK_WEIGHT assert block.get_weight() < MAX_BLOCK_WEIGHT
assert_equal(None, self.nodes[0].submitblock(block.serialize().hex())) assert_equal(None, self.nodes[0].submitblock(block.serialize().hex()))
assert self.nodes[0].getbestblockhash() == block.hash assert self.nodes[0].getbestblockhash() == block.hash_hex
# Now make sure that malleating the witness reserved value doesn't # Now make sure that malleating the witness reserved value doesn't
# result in a block permanently marked bad. # result in a block permanently marked bad.
@@ -927,14 +926,14 @@ class SegWitTest(BitcoinTestFramework):
block.vtx[0].wit = CTxWitness() # drop the nonce block.vtx[0].wit = CTxWitness() # drop the nonce
block.solve() block.solve()
assert_equal('bad-witness-merkle-match', self.nodes[0].submitblock(block.serialize().hex())) assert_equal('bad-witness-merkle-match', self.nodes[0].submitblock(block.serialize().hex()))
assert_not_equal(self.nodes[0].getbestblockhash(), block.hash) assert_not_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
# Now redo commitment with the standard nonce, but let bitcoind fill it in. # Now redo commitment with the standard nonce, but let bitcoind fill it in.
add_witness_commitment(block, nonce=0) add_witness_commitment(block, nonce=0)
block.vtx[0].wit = CTxWitness() block.vtx[0].wit = CTxWitness()
block.solve() block.solve()
assert_equal(None, self.nodes[0].submitblock(block.serialize().hex())) assert_equal(None, self.nodes[0].submitblock(block.serialize().hex()))
assert_equal(self.nodes[0].getbestblockhash(), block.hash) assert_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
# This time, add a tx with non-empty witness, but don't supply # This time, add a tx with non-empty witness, but don't supply
# the commitment. # the commitment.
@@ -950,7 +949,7 @@ class SegWitTest(BitcoinTestFramework):
assert_equal('bad-txnmrklroot', self.nodes[0].submitblock(block_2.serialize().hex())) assert_equal('bad-txnmrklroot', self.nodes[0].submitblock(block_2.serialize().hex()))
# Tip should not advance! # Tip should not advance!
assert_not_equal(self.nodes[0].getbestblockhash(), block_2.hash) assert_not_equal(self.nodes[0].getbestblockhash(), block_2.hash_hex)
@subtest @subtest
def test_extra_witness_data(self): def test_extra_witness_data(self):
@@ -1892,7 +1891,7 @@ class SegWitTest(BitcoinTestFramework):
# Reset the tip back down for the next test # Reset the tip back down for the next test
self.sync_blocks() self.sync_blocks()
for x in self.nodes: for x in self.nodes:
x.invalidateblock(block_4.hash) x.invalidateblock(block_4.hash_hex)
# Try replacing the last input of tx2 to be spending the last # Try replacing the last input of tx2 to be spending the last
# output of tx # output of tx
+21 -22
View File
@@ -150,10 +150,9 @@ class BaseNode(P2PInterface):
if len(message.headers): if len(message.headers):
self.block_announced = True self.block_announced = True
for x in message.headers: for x in message.headers:
x.calc_sha256()
# append because headers may be announced over multiple messages. # append because headers may be announced over multiple messages.
self.recent_headers_announced.append(x.sha256) self.recent_headers_announced.append(x.hash_int)
self.last_blockhash_announced = message.headers[-1].sha256 self.last_blockhash_announced = message.headers[-1].hash_int
def clear_block_announcements(self): def clear_block_announcements(self):
with p2p_lock: with p2p_lock:
@@ -248,12 +247,12 @@ class SendHeadersTest(BitcoinTestFramework):
block.solve() block.solve()
test_node.send_header_for_blocks([block]) test_node.send_header_for_blocks([block])
test_node.clear_block_announcements() test_node.clear_block_announcements()
test_node.send_get_headers(locator=[], hashstop=int(block.hash, 16)) test_node.send_get_headers(locator=[], hashstop=block.hash_int)
test_node.sync_with_ping() test_node.sync_with_ping()
assert_equal(test_node.block_announced, False) assert_equal(test_node.block_announced, False)
inv_node.clear_block_announcements() inv_node.clear_block_announcements()
test_node.send_without_ping(msg_block(block)) test_node.send_without_ping(msg_block(block))
inv_node.check_last_inv_announcement(inv=[int(block.hash, 16)]) inv_node.check_last_inv_announcement(inv=[block.hash_int])
def test_nonnull_locators(self, test_node, inv_node): def test_nonnull_locators(self, test_node, inv_node):
tip = int(self.nodes[0].getbestblockhash(), 16) tip = int(self.nodes[0].getbestblockhash(), 16)
@@ -287,7 +286,7 @@ class SendHeadersTest(BitcoinTestFramework):
new_block = create_block(tip, create_coinbase(height + 1), block_time) new_block = create_block(tip, create_coinbase(height + 1), block_time)
new_block.solve() new_block.solve()
test_node.send_header_for_blocks([new_block]) test_node.send_header_for_blocks([new_block])
test_node.wait_for_getdata([new_block.sha256]) test_node.wait_for_getdata([new_block.hash_int])
test_node.send_and_ping(msg_block(new_block)) # make sure this block is processed test_node.send_and_ping(msg_block(new_block)) # make sure this block is processed
inv_node.wait_until(lambda: inv_node.block_announced) inv_node.wait_until(lambda: inv_node.block_announced)
inv_node.clear_block_announcements() inv_node.clear_block_announcements()
@@ -323,7 +322,7 @@ class SendHeadersTest(BitcoinTestFramework):
for _ in range(i + 1): for _ in range(i + 1):
blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve() blocks[-1].solve()
tip = blocks[-1].sha256 tip = blocks[-1].hash_int
block_time += 1 block_time += 1
height += 1 height += 1
if j == 0: if j == 0:
@@ -337,13 +336,13 @@ class SendHeadersTest(BitcoinTestFramework):
test_node.send_header_for_blocks(blocks) test_node.send_header_for_blocks(blocks)
# Test that duplicate inv's won't result in duplicate # Test that duplicate inv's won't result in duplicate
# getdata requests, or duplicate headers announcements # getdata requests, or duplicate headers announcements
[inv_node.send_block_inv(x.sha256) for x in blocks] [inv_node.send_block_inv(x.hash_int) for x in blocks]
test_node.wait_for_getdata([x.sha256 for x in blocks]) test_node.wait_for_getdata([x.hash_int for x in blocks])
inv_node.sync_with_ping() inv_node.sync_with_ping()
else: else:
# Announce via headers # Announce via headers
test_node.send_header_for_blocks(blocks) test_node.send_header_for_blocks(blocks)
test_node.wait_for_getdata([x.sha256 for x in blocks]) test_node.wait_for_getdata([x.hash_int for x in blocks])
# Test that duplicate headers won't result in duplicate # Test that duplicate headers won't result in duplicate
# getdata requests (the check is further down) # getdata requests (the check is further down)
inv_node.send_header_for_blocks(blocks) inv_node.send_header_for_blocks(blocks)
@@ -441,7 +440,7 @@ class SendHeadersTest(BitcoinTestFramework):
for _ in range(2): for _ in range(2):
blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve() blocks[-1].solve()
tip = blocks[-1].sha256 tip = blocks[-1].hash_int
block_time += 1 block_time += 1
height += 1 height += 1
inv_node.send_without_ping(msg_block(blocks[-1])) inv_node.send_without_ping(msg_block(blocks[-1]))
@@ -459,20 +458,20 @@ class SendHeadersTest(BitcoinTestFramework):
for _ in range(3): for _ in range(3):
blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve() blocks[-1].solve()
tip = blocks[-1].sha256 tip = blocks[-1].hash_int
block_time += 1 block_time += 1
height += 1 height += 1
test_node.send_header_for_blocks(blocks) test_node.send_header_for_blocks(blocks)
test_node.sync_with_ping() test_node.sync_with_ping()
test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=DIRECT_FETCH_RESPONSE_TIME) test_node.wait_for_getdata([x.hash_int for x in blocks], timeout=DIRECT_FETCH_RESPONSE_TIME)
[test_node.send_without_ping(msg_block(x)) for x in blocks] [test_node.send_without_ping(msg_block(x)) for x in blocks]
test_node.sync_with_ping() test_node.sync_with_ping()
# Now announce a header that forks the last two blocks # Now announce a header that forks the last two blocks
tip = blocks[0].sha256 tip = blocks[0].hash_int
height -= 2 height -= 2
blocks = [] blocks = []
@@ -480,7 +479,7 @@ class SendHeadersTest(BitcoinTestFramework):
for _ in range(20): for _ in range(20):
blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve() blocks[-1].solve()
tip = blocks[-1].sha256 tip = blocks[-1].hash_int
block_time += 1 block_time += 1
height += 1 height += 1
@@ -496,13 +495,13 @@ class SendHeadersTest(BitcoinTestFramework):
# both blocks (same work as tip) # both blocks (same work as tip)
test_node.send_header_for_blocks(blocks[1:2]) test_node.send_header_for_blocks(blocks[1:2])
test_node.sync_with_ping() test_node.sync_with_ping()
test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=DIRECT_FETCH_RESPONSE_TIME) test_node.wait_for_getdata([x.hash_int for x in blocks[0:2]], timeout=DIRECT_FETCH_RESPONSE_TIME)
# Announcing 16 more headers should trigger direct fetch for 14 more # Announcing 16 more headers should trigger direct fetch for 14 more
# blocks # blocks
test_node.send_header_for_blocks(blocks[2:18]) test_node.send_header_for_blocks(blocks[2:18])
test_node.sync_with_ping() test_node.sync_with_ping()
test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=DIRECT_FETCH_RESPONSE_TIME) test_node.wait_for_getdata([x.hash_int for x in blocks[2:16]], timeout=DIRECT_FETCH_RESPONSE_TIME)
# Announcing 1 more header should not trigger any response # Announcing 1 more header should not trigger any response
test_node.last_message.pop("getdata", None) test_node.last_message.pop("getdata", None)
@@ -529,18 +528,18 @@ class SendHeadersTest(BitcoinTestFramework):
for _ in range(2): for _ in range(2):
blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve() blocks[-1].solve()
tip = blocks[-1].sha256 tip = blocks[-1].hash_int
block_time += 1 block_time += 1
height += 1 height += 1
# Send the header of the second block -> this won't connect. # Send the header of the second block -> this won't connect.
test_node.send_header_for_blocks([blocks[1]]) test_node.send_header_for_blocks([blocks[1]])
test_node.wait_for_getheaders(block_hash=expected_hash) test_node.wait_for_getheaders(block_hash=expected_hash)
test_node.send_header_for_blocks(blocks) test_node.send_header_for_blocks(blocks)
test_node.wait_for_getdata([x.sha256 for x in blocks]) test_node.wait_for_getdata([x.hash_int for x in blocks])
[test_node.send_without_ping(msg_block(x)) for x in blocks] [test_node.send_without_ping(msg_block(x)) for x in blocks]
test_node.sync_with_ping() test_node.sync_with_ping()
assert_equal(int(self.nodes[0].getbestblockhash(), 16), blocks[1].sha256) assert_equal(self.nodes[0].getbestblockhash(), blocks[1].hash_hex)
expected_hash = blocks[1].sha256 expected_hash = blocks[1].hash_int
blocks = [] blocks = []
# Now we test that if we repeatedly don't send connecting headers, we # Now we test that if we repeatedly don't send connecting headers, we
@@ -548,7 +547,7 @@ class SendHeadersTest(BitcoinTestFramework):
for _ in range(NUM_HEADERS + 1): for _ in range(NUM_HEADERS + 1):
blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve() blocks[-1].solve()
tip = blocks[-1].sha256 tip = blocks[-1].hash_int
block_time += 1 block_time += 1
height += 1 height += 1
+33 -33
View File
@@ -97,14 +97,14 @@ class AcceptBlockTest(BitcoinTestFramework):
block_time += 1 block_time += 1
test_node.send_and_ping(msg_block(blocks_h2[0])) test_node.send_and_ping(msg_block(blocks_h2[0]))
with self.nodes[1].assert_debug_log(expected_msgs=[f"AcceptBlockHeader: not adding new block header {blocks_h2[1].hash}, missing anti-dos proof-of-work validation"]): with self.nodes[1].assert_debug_log(expected_msgs=[f"AcceptBlockHeader: not adding new block header {blocks_h2[1].hash_hex}, missing anti-dos proof-of-work validation"]):
min_work_node.send_and_ping(msg_block(blocks_h2[1])) min_work_node.send_and_ping(msg_block(blocks_h2[1]))
assert_equal(self.nodes[0].getblockcount(), 2) assert_equal(self.nodes[0].getblockcount(), 2)
assert_equal(self.nodes[1].getblockcount(), 1) assert_equal(self.nodes[1].getblockcount(), 1)
# Ensure that the header of the second block was also not accepted by node1 # Ensure that the header of the second block was also not accepted by node1
assert_equal(self.check_hash_in_chaintips(self.nodes[1], blocks_h2[1].hash), False) assert_equal(self.check_hash_in_chaintips(self.nodes[1], blocks_h2[1].hash_hex), False)
self.log.info("First height 2 block accepted by node0; correctly rejected by node1") self.log.info("First height 2 block accepted by node0; correctly rejected by node1")
# 3. Send another block that builds on genesis. # 3. Send another block that builds on genesis.
@@ -115,14 +115,14 @@ class AcceptBlockTest(BitcoinTestFramework):
tip_entry_found = False tip_entry_found = False
for x in self.nodes[0].getchaintips(): for x in self.nodes[0].getchaintips():
if x['hash'] == block_h1f.hash: if x['hash'] == block_h1f.hash_hex:
assert_equal(x['status'], "headers-only") assert_equal(x['status'], "headers-only")
tip_entry_found = True tip_entry_found = True
assert tip_entry_found assert tip_entry_found
assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", self.nodes[0].getblock, block_h1f.hash) assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", self.nodes[0].getblock, block_h1f.hash_hex)
# 4. Send another two block that build on the fork. # 4. Send another two block that build on the fork.
block_h2f = create_block(block_h1f.sha256, create_coinbase(2), block_time) block_h2f = create_block(block_h1f.hash_int, create_coinbase(2), block_time)
block_time += 1 block_time += 1
block_h2f.solve() block_h2f.solve()
test_node.send_and_ping(msg_block(block_h2f)) test_node.send_and_ping(msg_block(block_h2f))
@@ -131,17 +131,17 @@ class AcceptBlockTest(BitcoinTestFramework):
# can't be fully validated. # can't be fully validated.
tip_entry_found = False tip_entry_found = False
for x in self.nodes[0].getchaintips(): for x in self.nodes[0].getchaintips():
if x['hash'] == block_h2f.hash: if x['hash'] == block_h2f.hash_hex:
assert_equal(x['status'], "headers-only") assert_equal(x['status'], "headers-only")
tip_entry_found = True tip_entry_found = True
assert tip_entry_found assert tip_entry_found
# But this block should be accepted by node since it has equal work. # But this block should be accepted by node since it has equal work.
self.nodes[0].getblock(block_h2f.hash) self.nodes[0].getblock(block_h2f.hash_hex)
self.log.info("Second height 2 block accepted, but not reorg'ed to") self.log.info("Second height 2 block accepted, but not reorg'ed to")
# 4b. Now send another block that builds on the forking chain. # 4b. Now send another block that builds on the forking chain.
block_h3 = create_block(block_h2f.sha256, create_coinbase(3), block_h2f.nTime+1) block_h3 = create_block(block_h2f.hash_int, create_coinbase(3), block_h2f.nTime+1)
block_h3.solve() block_h3.solve()
test_node.send_and_ping(msg_block(block_h3)) test_node.send_and_ping(msg_block(block_h3))
@@ -149,14 +149,14 @@ class AcceptBlockTest(BitcoinTestFramework):
# can't be fully validated. # can't be fully validated.
tip_entry_found = False tip_entry_found = False
for x in self.nodes[0].getchaintips(): for x in self.nodes[0].getchaintips():
if x['hash'] == block_h3.hash: if x['hash'] == block_h3.hash_hex:
assert_equal(x['status'], "headers-only") assert_equal(x['status'], "headers-only")
tip_entry_found = True tip_entry_found = True
assert tip_entry_found assert tip_entry_found
self.nodes[0].getblock(block_h3.hash) self.nodes[0].getblock(block_h3.hash_hex)
# But this block should be accepted by node since it has more work. # But this block should be accepted by node since it has more work.
self.nodes[0].getblock(block_h3.hash) self.nodes[0].getblock(block_h3.hash_hex)
self.log.info("Unrequested more-work block accepted") self.log.info("Unrequested more-work block accepted")
# 4c. Now mine 288 more blocks and deliver; all should be processed but # 4c. Now mine 288 more blocks and deliver; all should be processed but
@@ -164,7 +164,7 @@ class AcceptBlockTest(BitcoinTestFramework):
tip = block_h3 tip = block_h3
all_blocks = [] all_blocks = []
for i in range(288): for i in range(288):
next_block = create_block(tip.sha256, create_coinbase(i + 4), tip.nTime+1) next_block = create_block(tip.hash_int, create_coinbase(i + 4), tip.nTime+1)
next_block.solve() next_block.solve()
all_blocks.append(next_block) all_blocks.append(next_block)
tip = next_block tip = next_block
@@ -172,8 +172,8 @@ class AcceptBlockTest(BitcoinTestFramework):
# Now send the block at height 5 and check that it wasn't accepted (missing header) # Now send the block at height 5 and check that it wasn't accepted (missing header)
test_node.send_without_ping(msg_block(all_blocks[1])) test_node.send_without_ping(msg_block(all_blocks[1]))
test_node.wait_for_disconnect() test_node.wait_for_disconnect()
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getblock, all_blocks[1].hash) assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getblock, all_blocks[1].hash_hex)
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getblockheader, all_blocks[1].hash) assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getblockheader, all_blocks[1].hash_hex)
test_node = self.nodes[0].add_p2p_connection(P2PInterface()) test_node = self.nodes[0].add_p2p_connection(P2PInterface())
# The block at height 5 should be accepted if we provide the missing header, though # The block at height 5 should be accepted if we provide the missing header, though
@@ -181,7 +181,7 @@ class AcceptBlockTest(BitcoinTestFramework):
headers_message.headers.append(CBlockHeader(all_blocks[0])) headers_message.headers.append(CBlockHeader(all_blocks[0]))
test_node.send_without_ping(headers_message) test_node.send_without_ping(headers_message)
test_node.send_and_ping(msg_block(all_blocks[1])) test_node.send_and_ping(msg_block(all_blocks[1]))
self.nodes[0].getblock(all_blocks[1].hash) self.nodes[0].getblock(all_blocks[1].hash_hex)
# Now send the blocks in all_blocks # Now send the blocks in all_blocks
for i in range(288): for i in range(288):
@@ -190,8 +190,8 @@ class AcceptBlockTest(BitcoinTestFramework):
# Blocks 1-287 should be accepted, block 288 should be ignored because it's too far ahead # Blocks 1-287 should be accepted, block 288 should be ignored because it's too far ahead
for x in all_blocks[:-1]: for x in all_blocks[:-1]:
self.nodes[0].getblock(x.hash) self.nodes[0].getblock(x.hash_hex)
assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", self.nodes[0].getblock, all_blocks[-1].hash) assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", self.nodes[0].getblock, all_blocks[-1].hash_hex)
# 5. Test handling of unrequested block on the node that didn't process # 5. Test handling of unrequested block on the node that didn't process
# Should still not be processed (even though it has a child that has more # Should still not be processed (even though it has a child that has more
@@ -215,35 +215,35 @@ class AcceptBlockTest(BitcoinTestFramework):
with p2p_lock: with p2p_lock:
# Clear state so we can check the getdata request # Clear state so we can check the getdata request
test_node.last_message.pop("getdata", None) test_node.last_message.pop("getdata", None)
test_node.send_without_ping(msg_inv([CInv(MSG_BLOCK, block_h3.sha256)])) test_node.send_without_ping(msg_inv([CInv(MSG_BLOCK, block_h3.hash_int)]))
test_node.sync_with_ping() test_node.sync_with_ping()
with p2p_lock: with p2p_lock:
getdata = test_node.last_message["getdata"] getdata = test_node.last_message["getdata"]
# Check that the getdata includes the right block # Check that the getdata includes the right block
assert_equal(getdata.inv[0].hash, block_h1f.sha256) assert_equal(getdata.inv[0].hash, block_h1f.hash_int)
self.log.info("Inv at tip triggered getdata for unprocessed block") self.log.info("Inv at tip triggered getdata for unprocessed block")
# 7. Send the missing block for the third time (now it is requested) # 7. Send the missing block for the third time (now it is requested)
test_node.send_and_ping(msg_block(block_h1f)) test_node.send_and_ping(msg_block(block_h1f))
assert_equal(self.nodes[0].getblockcount(), 290) assert_equal(self.nodes[0].getblockcount(), 290)
self.nodes[0].getblock(all_blocks[286].hash) self.nodes[0].getblock(all_blocks[286].hash_hex)
assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash) assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash_hex)
assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", self.nodes[0].getblock, all_blocks[287].hash) assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", self.nodes[0].getblock, all_blocks[287].hash_hex)
self.log.info("Successfully reorged to longer chain") self.log.info("Successfully reorged to longer chain")
# 8. Create a chain which is invalid at a height longer than the # 8. Create a chain which is invalid at a height longer than the
# current chain, but which has more blocks on top of that # current chain, but which has more blocks on top of that
block_289f = create_block(all_blocks[284].sha256, create_coinbase(289), all_blocks[284].nTime+1) block_289f = create_block(all_blocks[284].hash_int, create_coinbase(289), all_blocks[284].nTime+1)
block_289f.solve() block_289f.solve()
block_290f = create_block(block_289f.sha256, create_coinbase(290), block_289f.nTime+1) block_290f = create_block(block_289f.hash_int, create_coinbase(290), block_289f.nTime+1)
block_290f.solve() block_290f.solve()
# block_291 spends a coinbase below maturity! # block_291 spends a coinbase below maturity!
tx_to_add = create_tx_with_script(block_290f.vtx[0], 0, script_sig=b"42", amount=1) tx_to_add = create_tx_with_script(block_290f.vtx[0], 0, script_sig=b"42", amount=1)
block_291 = create_block(block_290f.sha256, create_coinbase(291), block_290f.nTime+1, txlist=[tx_to_add]) block_291 = create_block(block_290f.hash_int, create_coinbase(291), block_290f.nTime+1, txlist=[tx_to_add])
block_291.solve() block_291.solve()
block_292 = create_block(block_291.sha256, create_coinbase(292), block_291.nTime+1) block_292 = create_block(block_291.hash_int, create_coinbase(292), block_291.nTime+1)
block_292.solve() block_292.solve()
# Now send all the headers on the chain and enough blocks to trigger reorg # Now send all the headers on the chain and enough blocks to trigger reorg
@@ -256,17 +256,17 @@ class AcceptBlockTest(BitcoinTestFramework):
tip_entry_found = False tip_entry_found = False
for x in self.nodes[0].getchaintips(): for x in self.nodes[0].getchaintips():
if x['hash'] == block_292.hash: if x['hash'] == block_292.hash_hex:
assert_equal(x['status'], "headers-only") assert_equal(x['status'], "headers-only")
tip_entry_found = True tip_entry_found = True
assert tip_entry_found assert tip_entry_found
assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", self.nodes[0].getblock, block_292.hash) assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", self.nodes[0].getblock, block_292.hash_hex)
test_node.send_without_ping(msg_block(block_289f)) test_node.send_without_ping(msg_block(block_289f))
test_node.send_and_ping(msg_block(block_290f)) test_node.send_and_ping(msg_block(block_290f))
self.nodes[0].getblock(block_289f.hash) self.nodes[0].getblock(block_289f.hash_hex)
self.nodes[0].getblock(block_290f.hash) self.nodes[0].getblock(block_290f.hash_hex)
test_node.send_without_ping(msg_block(block_291)) test_node.send_without_ping(msg_block(block_291))
@@ -279,11 +279,11 @@ class AcceptBlockTest(BitcoinTestFramework):
# We should have failed reorg and switched back to 290 (but have block 291) # We should have failed reorg and switched back to 290 (but have block 291)
assert_equal(self.nodes[0].getblockcount(), 290) assert_equal(self.nodes[0].getblockcount(), 290)
assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash) assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash_hex)
assert_equal(self.nodes[0].getblock(block_291.hash)["confirmations"], -1) assert_equal(self.nodes[0].getblock(block_291.hash_hex)["confirmations"], -1)
# Now send a new header on the invalid chain, indicating we're forked off, and expect to get disconnected # Now send a new header on the invalid chain, indicating we're forked off, and expect to get disconnected
block_293 = create_block(block_292.sha256, create_coinbase(293), block_292.nTime+1) block_293 = create_block(block_292.hash_int, create_coinbase(293), block_292.nTime+1)
block_293.solve() block_293.solve()
headers_message = msg_headers() headers_message = msg_headers()
headers_message.headers.append(CBlockHeader(block_293)) headers_message.headers.append(CBlockHeader(block_293))
+1 -1
View File
@@ -41,7 +41,7 @@ class P2PEncrypted(BitcoinTestFramework):
block = create_block(tip, create_coinbase(tipheight + 1), last_block_time + 1) block = create_block(tip, create_coinbase(tipheight + 1), last_block_time + 1)
block.solve() block.solve()
test_blocks.append(block) test_blocks.append(block)
tip = block.sha256 tip = block.hash_int
tipheight += 1 tipheight += 1
last_block_time += 1 last_block_time += 1
return test_blocks return test_blocks
+9 -10
View File
@@ -480,8 +480,7 @@ class BlockchainTest(BitcoinTestFramework):
assert_is_hex_string(header_hex) assert_is_hex_string(header_hex)
header = from_hex(CBlockHeader(), header_hex) header = from_hex(CBlockHeader(), header_hex)
header.calc_sha256() assert_equal(header.hash_hex, besthash)
assert_equal(header.hash, besthash)
assert 'previousblockhash' not in node.getblockheader(node.getblockhash(0)) assert 'previousblockhash' not in node.getblockheader(node.getblockhash(0))
assert 'nextblockhash' not in node.getblockheader(node.getbestblockhash()) assert 'nextblockhash' not in node.getblockheader(node.getbestblockhash())
@@ -622,9 +621,9 @@ class BlockchainTest(BitcoinTestFramework):
return b return b
b1 = solve_and_send_block(int(fork_hash, 16), fork_height+1, fork_block['time'] + 1) b1 = solve_and_send_block(int(fork_hash, 16), fork_height+1, fork_block['time'] + 1)
b2 = solve_and_send_block(b1.sha256, fork_height+2, b1.nTime + 1) b2 = solve_and_send_block(b1.hash_int, fork_height+2, b1.nTime + 1)
node.invalidateblock(b2.hash) node.invalidateblock(b2.hash_hex)
def assert_waitforheight(height, timeout=2): def assert_waitforheight(height, timeout=2):
assert_equal( assert_equal(
@@ -730,19 +729,19 @@ class BlockchainTest(BitcoinTestFramework):
block = create_block(int(blockhash, 16), create_coinbase(current_height + 1, nValue=100), block_time) block = create_block(int(blockhash, 16), create_coinbase(current_height + 1, nValue=100), block_time)
block.solve() block.solve()
node.submitheader(block.serialize().hex()) node.submitheader(block.serialize().hex())
assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", lambda: node.getblock(block.hash)) assert_raises_rpc_error(-1, "Block not available (not fully downloaded)", lambda: node.getblock(block.hash_hex))
self.log.info("Test getblock when block data is available but undo data isn't") self.log.info("Test getblock when block data is available but undo data isn't")
# Submits a block building on the header-only block, so it can't be connected and has no undo data # Submits a block building on the header-only block, so it can't be connected and has no undo data
tx = create_tx_with_script(block.vtx[0], 0, script_sig=bytes([OP_TRUE]), amount=50 * COIN) tx = create_tx_with_script(block.vtx[0], 0, script_sig=bytes([OP_TRUE]), amount=50 * COIN)
block_noundo = create_block(block.sha256, create_coinbase(current_height + 2, nValue=100), block_time + 1, txlist=[tx]) block_noundo = create_block(block.hash_int, create_coinbase(current_height + 2, nValue=100), block_time + 1, txlist=[tx])
block_noundo.solve() block_noundo.solve()
node.submitblock(block_noundo.serialize().hex()) node.submitblock(block_noundo.serialize().hex())
assert_fee_not_in_block(block_noundo.hash, 2) assert_fee_not_in_block(block_noundo.hash_hex, 2)
assert_fee_not_in_block(block_noundo.hash, 3) assert_fee_not_in_block(block_noundo.hash_hex, 3)
assert_vin_does_not_contain_prevout(block_noundo.hash, 2) assert_vin_does_not_contain_prevout(block_noundo.hash_hex, 2)
assert_vin_does_not_contain_prevout(block_noundo.hash, 3) assert_vin_does_not_contain_prevout(block_noundo.hash_hex, 3)
self.log.info("Test getblock when block is missing") self.log.info("Test getblock when block is missing")
move_block_file('blk00000.dat', 'blk00000.dat.bak') move_block_file('blk00000.dat', 'blk00000.dat.bak')
+1 -1
View File
@@ -73,7 +73,7 @@ class GetChainTipsTest (BitcoinTestFramework):
invalid_block.solve() invalid_block.solve()
block_time += 1 block_time += 1
block2 = create_block(invalid_block.sha256, create_coinbase(2), block_time, version=4) block2 = create_block(invalid_block.hash_int, create_coinbase(2), block_time, version=4)
block2.solve() block2.solve()
self.log.info("Submit headers-only chain") self.log.info("Submit headers-only chain")
+1 -1
View File
@@ -103,7 +103,7 @@ class InvalidateTest(BitcoinTestFramework):
assert_equal(self.nodes[0].getblockchaininfo()['headers'], 3) assert_equal(self.nodes[0].getblockchaininfo()['headers'], 3)
# Reconsider the header # Reconsider the header
self.nodes[0].reconsiderblock(block.hash) self.nodes[0].reconsiderblock(block.hash_hex)
# Since header doesn't have block data, it can't be chain tip # Since header doesn't have block data, it can't be chain tip
# Check if it's possible for an ancestor (with block data) to be the chain tip # Check if it's possible for an ancestor (with block data) to be the chain tip
assert_equal(self.nodes[0].getbestblockhash(), blockhash_6) assert_equal(self.nodes[0].getbestblockhash(), blockhash_6)
@@ -111,7 +111,6 @@ def create_block(hashprev=None, coinbase=None, ntime=None, *, version=None, tmpl
tx = tx_from_hex(tx) tx = tx_from_hex(tx)
block.vtx.append(tx) block.vtx.append(tx)
block.hashMerkleRoot = block.calc_merkle_root() block.hashMerkleRoot = block.calc_merkle_root()
block.calc_sha256()
return block return block
def get_witness_script(witness_root, witness_nonce): def get_witness_script(witness_root, witness_nonce):
@@ -135,7 +134,6 @@ def add_witness_commitment(block, nonce=0):
# witness commitment is the last OP_RETURN output in coinbase # witness commitment is the last OP_RETURN output in coinbase
block.vtx[0].vout.append(CTxOut(0, get_witness_script(witness_root, witness_nonce))) block.vtx[0].vout.append(CTxOut(0, get_witness_script(witness_root, witness_nonce)))
block.hashMerkleRoot = block.calc_merkle_root() block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
def script_BIP34_coinbase_height(height): def script_BIP34_coinbase_height(height):
+15 -29
View File
@@ -704,8 +704,8 @@ class CTransaction:
class CBlockHeader: class CBlockHeader:
__slots__ = ("hash", "hashMerkleRoot", "hashPrevBlock", "nBits", "nNonce", __slots__ = ("hashMerkleRoot", "hashPrevBlock", "nBits", "nNonce",
"nTime", "nVersion", "sha256") "nTime", "nVersion")
def __init__(self, header=None): def __init__(self, header=None):
if header is None: if header is None:
@@ -717,9 +717,6 @@ class CBlockHeader:
self.nTime = header.nTime self.nTime = header.nTime
self.nBits = header.nBits self.nBits = header.nBits
self.nNonce = header.nNonce self.nNonce = header.nNonce
self.sha256 = header.sha256
self.hash = header.hash
self.calc_sha256()
def set_null(self): def set_null(self):
self.nVersion = 4 self.nVersion = 4
@@ -728,8 +725,6 @@ class CBlockHeader:
self.nTime = 0 self.nTime = 0
self.nBits = 0 self.nBits = 0
self.nNonce = 0 self.nNonce = 0
self.sha256 = None
self.hash = None
def deserialize(self, f): def deserialize(self, f):
self.nVersion = int.from_bytes(f.read(4), "little", signed=True) self.nVersion = int.from_bytes(f.read(4), "little", signed=True)
@@ -738,10 +733,11 @@ class CBlockHeader:
self.nTime = int.from_bytes(f.read(4), "little") self.nTime = int.from_bytes(f.read(4), "little")
self.nBits = int.from_bytes(f.read(4), "little") self.nBits = int.from_bytes(f.read(4), "little")
self.nNonce = int.from_bytes(f.read(4), "little") self.nNonce = int.from_bytes(f.read(4), "little")
self.sha256 = None
self.hash = None
def serialize(self): def serialize(self):
return self._serialize_header()
def _serialize_header(self):
r = b"" r = b""
r += self.nVersion.to_bytes(4, "little", signed=True) r += self.nVersion.to_bytes(4, "little", signed=True)
r += ser_uint256(self.hashPrevBlock) r += ser_uint256(self.hashPrevBlock)
@@ -751,22 +747,15 @@ class CBlockHeader:
r += self.nNonce.to_bytes(4, "little") r += self.nNonce.to_bytes(4, "little")
return r return r
def calc_sha256(self): @property
if self.sha256 is None: def hash_hex(self):
r = b"" """Return block header hash as hex string."""
r += self.nVersion.to_bytes(4, "little", signed=True) return hash256(self._serialize_header())[::-1].hex()
r += ser_uint256(self.hashPrevBlock)
r += ser_uint256(self.hashMerkleRoot)
r += self.nTime.to_bytes(4, "little")
r += self.nBits.to_bytes(4, "little")
r += self.nNonce.to_bytes(4, "little")
self.sha256 = uint256_from_str(hash256(r))
self.hash = hash256(r)[::-1].hex()
def rehash(self): @property
self.sha256 = None def hash_int(self):
self.calc_sha256() """Return block header hash as integer."""
return self.sha256 return uint256_from_str(hash256(self._serialize_header()))
def __repr__(self): def __repr__(self):
return "CBlockHeader(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x)" \ return "CBlockHeader(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x)" \
@@ -825,9 +814,8 @@ class CBlock(CBlockHeader):
return self.get_merkle_root(hashes) return self.get_merkle_root(hashes)
def is_valid(self): def is_valid(self):
self.calc_sha256()
target = uint256_from_compact(self.nBits) target = uint256_from_compact(self.nBits)
if self.sha256 > target: if self.hash_int > target:
return False return False
for tx in self.vtx: for tx in self.vtx:
if not tx.is_valid(): if not tx.is_valid():
@@ -837,11 +825,9 @@ class CBlock(CBlockHeader):
return True return True
def solve(self): def solve(self):
self.rehash()
target = uint256_from_compact(self.nBits) target = uint256_from_compact(self.nBits)
while self.sha256 > target: while self.hash_int > target:
self.nNonce += 1 self.nNonce += 1
self.rehash()
# Calculate the block weight using witness and non-witness # Calculate the block weight using witness and non-witness
# serialization size (does NOT use sigops). # serialization size (does NOT use sigops).
+10 -10
View File
@@ -625,7 +625,7 @@ class P2PInterface(P2PConnection):
def wait_for_block(self, blockhash, *, timeout=60): def wait_for_block(self, blockhash, *, timeout=60):
def test_function(): def test_function():
return self.last_message.get("block") and self.last_message["block"].block.rehash() == blockhash return self.last_message.get("block") and self.last_message["block"].block.hash_int == blockhash
self.wait_until(test_function, timeout=timeout) self.wait_until(test_function, timeout=timeout)
@@ -634,7 +634,7 @@ class P2PInterface(P2PConnection):
last_headers = self.last_message.get('headers') last_headers = self.last_message.get('headers')
if not last_headers: if not last_headers:
return False return False
return last_headers.headers[0].rehash() == int(blockhash, 16) return last_headers.headers[0].hash_int == int(blockhash, 16)
self.wait_until(test_function, timeout=timeout) self.wait_until(test_function, timeout=timeout)
@@ -643,7 +643,7 @@ class P2PInterface(P2PConnection):
last_filtered_block = self.last_message.get('merkleblock') last_filtered_block = self.last_message.get('merkleblock')
if not last_filtered_block: if not last_filtered_block:
return False return False
return last_filtered_block.merkleblock.header.rehash() == int(blockhash, 16) return last_filtered_block.merkleblock.header.hash_int == int(blockhash, 16)
self.wait_until(test_function, timeout=timeout) self.wait_until(test_function, timeout=timeout)
@@ -837,14 +837,14 @@ class P2PDataStore(P2PInterface):
return return
headers_list = [self.block_store[self.last_block_hash]] headers_list = [self.block_store[self.last_block_hash]]
while headers_list[-1].sha256 not in locator.vHave: while headers_list[-1].hash_int not in locator.vHave:
# Walk back through the block store, adding headers to headers_list # Walk back through the block store, adding headers to headers_list
# as we go. # as we go.
prev_block_hash = headers_list[-1].hashPrevBlock prev_block_hash = headers_list[-1].hashPrevBlock
if prev_block_hash in self.block_store: if prev_block_hash in self.block_store:
prev_block_header = CBlockHeader(self.block_store[prev_block_hash]) prev_block_header = CBlockHeader(self.block_store[prev_block_hash])
headers_list.append(prev_block_header) headers_list.append(prev_block_header)
if prev_block_header.sha256 == hash_stop: if prev_block_header.hash_int == hash_stop:
# if this is the hashstop header, stop here # if this is the hashstop header, stop here
break break
else: else:
@@ -872,8 +872,8 @@ class P2PDataStore(P2PInterface):
with p2p_lock: with p2p_lock:
for block in blocks: for block in blocks:
self.block_store[block.sha256] = block self.block_store[block.hash_int] = block
self.last_block_hash = block.sha256 self.last_block_hash = block.hash_int
reject_reason = [reject_reason] if reject_reason else [] reject_reason = [reject_reason] if reject_reason else []
with node.assert_debug_log(expected_msgs=reject_reason): with node.assert_debug_log(expected_msgs=reject_reason):
@@ -885,7 +885,7 @@ class P2PDataStore(P2PInterface):
else: else:
self.send_without_ping(msg_headers([CBlockHeader(block) for block in blocks])) self.send_without_ping(msg_headers([CBlockHeader(block) for block in blocks]))
self.wait_until( self.wait_until(
lambda: blocks[-1].sha256 in self.getdata_requests, lambda: blocks[-1].hash_int in self.getdata_requests,
timeout=timeout, timeout=timeout,
check_connected=success, check_connected=success,
) )
@@ -896,9 +896,9 @@ class P2PDataStore(P2PInterface):
self.sync_with_ping(timeout=timeout) self.sync_with_ping(timeout=timeout)
if success: if success:
self.wait_until(lambda: node.getbestblockhash() == blocks[-1].hash, timeout=timeout) self.wait_until(lambda: node.getbestblockhash() == blocks[-1].hash_hex, timeout=timeout)
else: else:
assert_not_equal(node.getbestblockhash(), blocks[-1].hash) assert_not_equal(node.getbestblockhash(), blocks[-1].hash_hex)
def send_txs_and_test(self, txs, node, *, success=True, expect_disconnect=False, reject_reason=None): def send_txs_and_test(self, txs, node, *, success=True, expect_disconnect=False, reject_reason=None):
"""Send txs to test node and test whether they're accepted to the mempool. """Send txs to test node and test whether they're accepted to the mempool.