A high-level P2P interface class for communicating with a Bitcoin node. This class provides high-level callbacks for processing P2P message payloads, as well as convenience methods for interacting with the node over P2P. Individual testcases should subclass this and override the on
| 454 | |
| 455 | |
| 456 | class P2PInterface(P2PConnection): |
| 457 | """A high-level P2P interface class for communicating with a Bitcoin node. |
| 458 | |
| 459 | This class provides high-level callbacks for processing P2P message |
| 460 | payloads, as well as convenience methods for interacting with the |
| 461 | node over P2P. |
| 462 | |
| 463 | Individual testcases should subclass this and override the on_* methods |
| 464 | if they want to alter message handling behaviour.""" |
| 465 | def __init__(self, support_addrv2=False, wtxidrelay=True): |
| 466 | super().__init__() |
| 467 | |
| 468 | # Track number of messages of each type received. |
| 469 | # Should be read-only in a test. |
| 470 | self.message_count = defaultdict(int) |
| 471 | |
| 472 | # Track the most recent message of each type. |
| 473 | # To wait for a message to be received, pop that message from |
| 474 | # this and use self.wait_until. |
| 475 | self.last_message = {} |
| 476 | |
| 477 | # A count of the number of ping messages we've sent to the node |
| 478 | self.ping_counter = 1 |
| 479 | |
| 480 | # The network services received from the peer |
| 481 | self.nServices = 0 |
| 482 | |
| 483 | self.support_addrv2 = support_addrv2 |
| 484 | |
| 485 | # If the peer supports wtxid-relay |
| 486 | self.wtxidrelay = wtxidrelay |
| 487 | |
| 488 | def peer_connect_send_version(self, services): |
| 489 | # Send a version msg |
| 490 | vt = msg_version() |
| 491 | vt.nVersion = P2P_VERSION |
| 492 | vt.strSubVer = P2P_SUBVERSION |
| 493 | vt.relay = P2P_VERSION_RELAY |
| 494 | vt.nServices = services |
| 495 | vt.addrTo.ip = self.dstaddr |
| 496 | vt.addrTo.port = self.dstport |
| 497 | vt.addrFrom.ip = "0.0.0.0" |
| 498 | vt.addrFrom.port = 0 |
| 499 | self.on_connection_send_msg = vt # Will be sent in connection_made callback |
| 500 | |
| 501 | def peer_connect(self, *, services=P2P_SERVICES, send_version, **kwargs): |
| 502 | create_conn = super().peer_connect(**kwargs) |
| 503 | |
| 504 | if send_version: |
| 505 | self.peer_connect_send_version(services) |
| 506 | |
| 507 | return create_conn |
| 508 | |
| 509 | def peer_accept_connection(self, *args, services=P2P_SERVICES, **kwargs): |
| 510 | create_conn = super().peer_accept_connection(*args, **kwargs) |
| 511 | self.peer_connect_send_version(services) |
| 512 | |
| 513 | return create_conn |
no outgoing calls