|
|
@ -1008,6 +1008,20 @@ class msg_reject(object): |
|
|
|
return "msg_reject: %s %d %s [%064x]" \ |
|
|
|
return "msg_reject: %s %d %s [%064x]" \ |
|
|
|
% (self.message, self.code, self.reason, self.data) |
|
|
|
% (self.message, self.code, self.reason, self.data) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Helper function |
|
|
|
|
|
|
|
def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): |
|
|
|
|
|
|
|
attempt = 0 |
|
|
|
|
|
|
|
elapsed = 0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while attempt < attempts and elapsed < timeout: |
|
|
|
|
|
|
|
with mininode_lock: |
|
|
|
|
|
|
|
if predicate(): |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
attempt += 1 |
|
|
|
|
|
|
|
elapsed += 0.05 |
|
|
|
|
|
|
|
time.sleep(0.05) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
# This is what a callback should look like for NodeConn |
|
|
|
# This is what a callback should look like for NodeConn |
|
|
|
# Reimplement the on_* functions to provide handling for events |
|
|
|
# Reimplement the on_* functions to provide handling for events |
|
|
@ -1085,6 +1099,32 @@ class NodeConnCB(object): |
|
|
|
def on_mempool(self, conn): pass |
|
|
|
def on_mempool(self, conn): pass |
|
|
|
def on_pong(self, conn, message): pass |
|
|
|
def on_pong(self, conn, message): pass |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# More useful callbacks and functions for NodeConnCB's which have a single NodeConn |
|
|
|
|
|
|
|
class SingleNodeConnCB(NodeConnCB): |
|
|
|
|
|
|
|
def __init__(self): |
|
|
|
|
|
|
|
NodeConnCB.__init__(self) |
|
|
|
|
|
|
|
self.connection = None |
|
|
|
|
|
|
|
self.ping_counter = 1 |
|
|
|
|
|
|
|
self.last_pong = msg_pong() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_connection(self, conn): |
|
|
|
|
|
|
|
self.connection = conn |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Wrapper for the NodeConn's send_message function |
|
|
|
|
|
|
|
def send_message(self, message): |
|
|
|
|
|
|
|
self.connection.send_message(message) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def on_pong(self, conn, message): |
|
|
|
|
|
|
|
self.last_pong = message |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Sync up with the node |
|
|
|
|
|
|
|
def sync_with_ping(self, timeout=30): |
|
|
|
|
|
|
|
def received_pong(): |
|
|
|
|
|
|
|
return (self.last_pong.nonce == self.ping_counter) |
|
|
|
|
|
|
|
self.send_message(msg_ping(nonce=self.ping_counter)) |
|
|
|
|
|
|
|
success = wait_until(received_pong, timeout) |
|
|
|
|
|
|
|
self.ping_counter += 1 |
|
|
|
|
|
|
|
return success |
|
|
|
|
|
|
|
|
|
|
|
# The actual NodeConn class |
|
|
|
# The actual NodeConn class |
|
|
|
# This class provides an interface for a p2p connection to a specified node |
|
|
|
# This class provides an interface for a p2p connection to a specified node |
|
|
|