add functional test

This commit is contained in:
Larry Ruane 2023-08-14 23:59:54 -06:00
parent 1e80659010
commit 99396b2316
2 changed files with 84 additions and 0 deletions

View file

@ -0,0 +1,83 @@
#!/usr/bin/env python3
# Copyright (c) 2023 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php.
""" Test block announcement time tracking
The bitcoind client records, for each peer, the most recent time that
this peer announced a block that the client wasn't already aware of. This
timestamp, CNodeStateStats::m_last_block_announcement, is available in the
`last_block_announcement` field of each peer's `getpeerinfo` result. The
value zero means that this peer has never been the first to announce
a block to us. Blocks are announced using either the "headers" or
"cmpctblock" messages.
This timestamp is used when the "potential stale tip" condition occurs:
When a new block hasn't been seen for a longer-than-expected amount of
time (currently 30 minutes, see TipMayBeStale()), the client, suspecting
that there may be new blocks that its peers are not announcing, will
add an extra outbound peer and disconnect (evict) the peer that has
least recently been the first to announced a new block to us. (If there
is a tie, it will disconnect the most recently-added of those peers.)
This test verifies that this timestamp is being set correctly.
(This tests PR 26172.)
"""
import time
from test_framework.blocktools import (
create_block,
create_coinbase,
)
from test_framework.messages import (
CBlockHeader,
msg_headers,
)
from test_framework.p2p import P2PDataStore
from test_framework.test_framework import BitcoinTestFramework
class P2PBlockTimes(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
self.disable_autoconnect = False
def run_test(self):
node = self.nodes[0]
cur_time = int(time.time())
node.setmocktime(cur_time)
# Generate one block to exit IBD
self.generate(node, 1)
self.log.info("Create a full-outbound test framework peer")
node.add_outbound_p2p_connection(P2PDataStore(), p2p_idx=0)
self.log.info("Test framework peer generates a new block")
tip = int(node.getbestblockhash(), 16)
block = create_block(tip, create_coinbase(2))
block.solve()
self.log.info("Test framework peer sends node the new block")
node.p2ps[0].send_blocks_and_test([block], node, success=True)
self.log.info("Verify peerinfo block timestamps")
peerinfo = node.getpeerinfo()[0]
assert peerinfo['last_block'] == cur_time
assert peerinfo['last_block_announcement'] == cur_time
self.log.info("Sending a block announcement with no new blocks")
node.setmocktime(cur_time+1)
headers_message = msg_headers()
headers_message.headers = [CBlockHeader(block)]
node.p2ps[0].send_message(headers_message)
node.p2ps[0].sync_with_ping()
self.log.info("Verify that block announcement time isn't updated")
peerinfo = node.getpeerinfo()[0]
assert peerinfo['last_block_announcement'] == cur_time
if __name__ == '__main__':
P2PBlockTimes(__file__).main()

View file

@ -206,6 +206,7 @@ BASE_SCRIPTS = [
'mempool_reorg.py', 'mempool_reorg.py',
'p2p_block_sync.py --v1transport', 'p2p_block_sync.py --v1transport',
'p2p_block_sync.py --v2transport', 'p2p_block_sync.py --v2transport',
'p2p_block_times.py',
'wallet_createwallet.py --legacy-wallet', 'wallet_createwallet.py --legacy-wallet',
'wallet_createwallet.py --usecli', 'wallet_createwallet.py --usecli',
'wallet_createwallet.py --descriptors', 'wallet_createwallet.py --descriptors',