Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251# this should be added:252now_hex + # time253'01' + # service flags, COMPACTSIZE(NODE_NETWORK)254'01' + # network type (IPv4)255'04' + # address length (COMPACTSIZE(4))256'09' * 4 + # address257'208d')) # port259def test_oversized_msg(self, msg, size):260msg_type = msg.msgtype.decode('ascii')261self.log.info("Test {} message of size {} is logged as misbehaving".format(msg_type, size))262with self.nodes[0].assert_debug_log(['Misbehaving', '{} message size = {}'.format(msg_type, size)]):263conn = self.nodes[0].add_p2p_connection(P2PInterface())264conn.send_without_ping(msg)265conn.wait_for_disconnect()266self.nodes[0].disconnect_p2ps()268def test_oversized_inv_msg(self):269size = MAX_INV_SIZE + 1270self.test_oversized_msg(msg_inv([CInv(MSG_TX, 1)] * size), size)272def test_oversized_getdata_msg(self):273size = MAX_INV_SIZE + 1274self.test_oversized_msg(msg_getdata([CInv(MSG_TX, 1)] * size), size)276def test_oversized_headers_msg(self):277size = MAX_HEADERS_RESULTS + 1278self.test_oversized_msg(msg_headers([CBlockHeader()] * size), size)280def test_invalid_pow_headers_msg(self):281self.log.info("Test headers message with invalid proof-of-work is logged as misbehaving and disconnects peer")282blockheader_tip_hash = self.nodes[0].getbestblockhash()283blockheader_tip = from_hex(CBlockHeader(), self.nodes[0].getblockheader(blockheader_tip_hash, False))285# send valid headers message first286assert_equal(self.nodes[0].getblockchaininfo()['headers'], 0)287blockheader = CBlockHeader()288blockheader.hashPrevBlock = int(blockheader_tip_hash, 16)289blockheader.nTime = int(time.time())290blockheader.nBits = blockheader_tip.nBits291while not blockheader.hash_hex.startswith('0'):292blockheader.nNonce += 1293peer = self.nodes[0].add_p2p_connection(P2PInterface())294peer.send_and_ping(msg_headers([blockheader]))295assert_equal(self.nodes[0].getblockchaininfo()['headers'], 1)296chaintips = self.nodes[0].getchaintips()297assert_equal(chaintips[0]['status'], 'headers-only')298assert_equal(chaintips[0]['hash'], blockheader.hash_hex)300# invalidate PoW301while not blockheader.hash_hex.startswith('f'):302blockheader.nNonce += 1303with self.nodes[0].assert_debug_log(['Misbehaving', 'header with invalid proof of work']):304peer.send_without_ping(msg_headers([blockheader]))305peer.wait_for_disconnect()307def test_noncontinuous_headers_msg(self):308self.log.info("Test headers message with non-continuous headers sequence is logged as misbehaving")309block_hashes = self.generate(self.nodes[0], 10)310block_headers = []311for block_hash in block_hashes:312block_headers.append(from_hex(CBlockHeader(), self.nodes[0].getblockheader(block_hash, False)))314# continuous headers sequence should be fine315MISBEHAVING_NONCONTINUOUS_HEADERS_MSGS = ['Misbehaving', 'non-continuous headers sequence']316peer = self.nodes[0].add_p2p_connection(P2PInterface())317with self.nodes[0].assert_debug_log([], unexpected_msgs=MISBEHAVING_NONCONTINUOUS_HEADERS_MSGS):318peer.send_and_ping(msg_headers(block_headers))320# delete arbitrary block header somewhere in the middle to break link321del block_headers[random.randrange(1, len(block_headers)-1)]322with self.nodes[0].assert_debug_log(expected_msgs=MISBEHAVING_NONCONTINUOUS_HEADERS_MSGS):323peer.send_without_ping(msg_headers(block_headers))324peer.wait_for_disconnect()325self.nodes[0].disconnect_p2ps()327def test_resource_exhaustion(self):328self.log.info("Test node stays up despite many large junk messages")329# Don't use v2 here - the non-optimised encryption would take too long to encrypt330# the large messages331conn = self.nodes[0].add_p2p_connection(P2PDataStore(), supports_v2_p2p=False)332conn2 = self.nodes[0].add_p2p_connection(P2PDataStore(), supports_v2_p2p=False)333msg_at_size = msg_unrecognized(str_data="b" * VALID_DATA_LIMIT)334assert_equal(len(msg_at_size.serialize()), MAX_PROTOCOL_MESSAGE_LENGTH)336self.log.info("(a) Send 80 messages, each of maximum valid data size (4MB)")337for _ in range(80):338conn.send_without_ping(msg_at_size)340# Check that, even though the node is being hammered by nonsense from one341# connection, it can still service other peers in a timely way.342self.log.info("(b) Check node still services peers in a timely way")343for _ in range(20):344conn2.sync_with_ping(timeout=2)346self.log.info("(c) Wait for node to drop junk messages, while remaining connected")347conn.sync_with_ping(timeout=400)349# Despite being served up a bunch of nonsense, the peers should still be connected.350assert conn.is_connected351assert conn2.is_connected352self.nodes[0].disconnect_p2ps()355if __name__ == '__main__':356InvalidMessagesTest(__file__).main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.