37
37
from test_framework .siphash import siphash256
38
38
from test_framework .util import hex_str_to_bytes , bytes_to_hex_str , wait_until
39
39
40
- BIP0031_VERSION = 60000
40
+ MIN_VERSION_SUPPORTED = 60001
41
41
MY_VERSION = 70014 # past bip-31 for ping/pong
42
42
MY_SUBVERSION = b"/python-mininode-tester:0.0.3/"
43
43
MY_RELAY = 1 # from version 70001 onwards, fRelay should be appended to version messages (BIP37)
@@ -666,81 +666,6 @@ def __repr__(self):
666
666
time .ctime (self .nTime ), self .nBits , self .nNonce , repr (self .vtx ))
667
667
668
668
669
- class CUnsignedAlert ():
670
- def __init__ (self ):
671
- self .nVersion = 1
672
- self .nRelayUntil = 0
673
- self .nExpiration = 0
674
- self .nID = 0
675
- self .nCancel = 0
676
- self .setCancel = []
677
- self .nMinVer = 0
678
- self .nMaxVer = 0
679
- self .setSubVer = []
680
- self .nPriority = 0
681
- self .strComment = b""
682
- self .strStatusBar = b""
683
- self .strReserved = b""
684
-
685
- def deserialize (self , f ):
686
- self .nVersion = struct .unpack ("<i" , f .read (4 ))[0 ]
687
- self .nRelayUntil = struct .unpack ("<q" , f .read (8 ))[0 ]
688
- self .nExpiration = struct .unpack ("<q" , f .read (8 ))[0 ]
689
- self .nID = struct .unpack ("<i" , f .read (4 ))[0 ]
690
- self .nCancel = struct .unpack ("<i" , f .read (4 ))[0 ]
691
- self .setCancel = deser_int_vector (f )
692
- self .nMinVer = struct .unpack ("<i" , f .read (4 ))[0 ]
693
- self .nMaxVer = struct .unpack ("<i" , f .read (4 ))[0 ]
694
- self .setSubVer = deser_string_vector (f )
695
- self .nPriority = struct .unpack ("<i" , f .read (4 ))[0 ]
696
- self .strComment = deser_string (f )
697
- self .strStatusBar = deser_string (f )
698
- self .strReserved = deser_string (f )
699
-
700
- def serialize (self ):
701
- r = b""
702
- r += struct .pack ("<i" , self .nVersion )
703
- r += struct .pack ("<q" , self .nRelayUntil )
704
- r += struct .pack ("<q" , self .nExpiration )
705
- r += struct .pack ("<i" , self .nID )
706
- r += struct .pack ("<i" , self .nCancel )
707
- r += ser_int_vector (self .setCancel )
708
- r += struct .pack ("<i" , self .nMinVer )
709
- r += struct .pack ("<i" , self .nMaxVer )
710
- r += ser_string_vector (self .setSubVer )
711
- r += struct .pack ("<i" , self .nPriority )
712
- r += ser_string (self .strComment )
713
- r += ser_string (self .strStatusBar )
714
- r += ser_string (self .strReserved )
715
- return r
716
-
717
- def __repr__ (self ):
718
- return "CUnsignedAlert(nVersion %d, nRelayUntil %d, nExpiration %d, nID %d, nCancel %d, nMinVer %d, nMaxVer %d, nPriority %d, strComment %s, strStatusBar %s, strReserved %s)" \
719
- % (self .nVersion , self .nRelayUntil , self .nExpiration , self .nID ,
720
- self .nCancel , self .nMinVer , self .nMaxVer , self .nPriority ,
721
- self .strComment , self .strStatusBar , self .strReserved )
722
-
723
-
724
- class CAlert ():
725
- def __init__ (self ):
726
- self .vchMsg = b""
727
- self .vchSig = b""
728
-
729
- def deserialize (self , f ):
730
- self .vchMsg = deser_string (f )
731
- self .vchSig = deser_string (f )
732
-
733
- def serialize (self ):
734
- r = b""
735
- r += ser_string (self .vchMsg )
736
- r += ser_string (self .vchSig )
737
- return r
738
-
739
- def __repr__ (self ):
740
- return "CAlert(vchMsg.sz %d, vchSig.sz %d)" \
741
- % (len (self .vchMsg ), len (self .vchSig ))
742
-
743
-
744
669
class PrefilledTransaction ():
745
670
def __init__ (self , index = 0 , tx = None ):
746
671
self .index = index
@@ -1044,25 +969,6 @@ def __repr__(self):
1044
969
return "msg_addr(addrs=%s)" % (repr (self .addrs ))
1045
970
1046
971
1047
- class msg_alert ():
1048
- command = b"alert"
1049
-
1050
- def __init__ (self ):
1051
- self .alert = CAlert ()
1052
-
1053
- def deserialize (self , f ):
1054
- self .alert = CAlert ()
1055
- self .alert .deserialize (f )
1056
-
1057
- def serialize (self ):
1058
- r = b""
1059
- r += self .alert .serialize ()
1060
- return r
1061
-
1062
- def __repr__ (self ):
1063
- return "msg_alert(alert=%s)" % (repr (self .alert ), )
1064
-
1065
-
1066
972
class msg_inv ():
1067
973
command = b"inv"
1068
974
@@ -1195,22 +1101,6 @@ def __repr__(self):
1195
1101
return "msg_getaddr()"
1196
1102
1197
1103
1198
- class msg_ping_prebip31 ():
1199
- command = b"ping"
1200
-
1201
- def __init__ (self ):
1202
- pass
1203
-
1204
- def deserialize (self , f ):
1205
- pass
1206
-
1207
- def serialize (self ):
1208
- return b""
1209
-
1210
- def __repr__ (self ):
1211
- return "msg_ping() (pre-bip31)"
1212
-
1213
-
1214
1104
class msg_ping ():
1215
1105
command = b"ping"
1216
1106
@@ -1458,9 +1348,7 @@ class NodeConnCB():
1458
1348
"""Callback and helper functions for P2P connection to a bitcoind node.
1459
1349
1460
1350
Individual testcases should subclass this and override the on_* methods
1461
- if they want to alter message handling behaviour.
1462
- """
1463
-
1351
+ if they want to alter message handling behaviour."""
1464
1352
def __init__ (self ):
1465
1353
# Track whether we have a P2P connection open to the node
1466
1354
self .connected = False
@@ -1474,25 +1362,13 @@ def __init__(self):
1474
1362
# A count of the number of ping messages we've sent to the node
1475
1363
self .ping_counter = 1
1476
1364
1477
- # deliver_sleep_time is helpful for debugging race conditions in p2p
1478
- # tests; it causes message delivery to sleep for the specified time
1479
- # before acquiring the global lock and delivering the next message.
1480
- self .deliver_sleep_time = None
1481
-
1482
1365
# Message receiving methods
1483
1366
1484
1367
def deliver (self , conn , message ):
1485
1368
"""Receive message and dispatch message to appropriate callback.
1486
1369
1487
1370
We keep a count of how many of each message type has been received
1488
- and the most recent message of each type.
1489
-
1490
- Optionally waits for deliver_sleep_time before dispatching message.
1491
- """
1492
-
1493
- deliver_sleep = self .get_deliver_sleep_time ()
1494
- if deliver_sleep is not None :
1495
- time .sleep (deliver_sleep )
1371
+ and the most recent message of each type."""
1496
1372
with mininode_lock :
1497
1373
try :
1498
1374
command = message .command .decode ('ascii' )
@@ -1504,10 +1380,6 @@ def deliver(self, conn, message):
1504
1380
sys .exc_info ()[0 ]))
1505
1381
raise
1506
1382
1507
- def get_deliver_sleep_time (self ):
1508
- with mininode_lock :
1509
- return self .deliver_sleep_time
1510
-
1511
1383
# Callback methods. Can be overridden by subclasses in individual test
1512
1384
# cases to provide custom message handling behaviour.
1513
1385
@@ -1519,7 +1391,6 @@ def on_close(self, conn):
1519
1391
self .connection = None
1520
1392
1521
1393
def on_addr (self , conn , message ): pass
1522
- def on_alert (self , conn , message ): pass
1523
1394
def on_block (self , conn , message ): pass
1524
1395
def on_blocktxn (self , conn , message ): pass
1525
1396
def on_cmpctblock (self , conn , message ): pass
@@ -1546,19 +1417,15 @@ def on_inv(self, conn, message):
1546
1417
conn .send_message (want )
1547
1418
1548
1419
def on_ping (self , conn , message ):
1549
- if conn .ver_send > BIP0031_VERSION :
1550
- conn .send_message (msg_pong (message .nonce ))
1420
+ conn .send_message (msg_pong (message .nonce ))
1551
1421
1552
1422
def on_verack (self , conn , message ):
1553
1423
conn .ver_recv = conn .ver_send
1554
1424
self .verack_received = True
1555
1425
1556
1426
def on_version (self , conn , message ):
1557
- if message .nVersion >= 209 :
1558
- conn .send_message (msg_verack ())
1559
- conn .ver_send = min (MY_VERSION , message .nVersion )
1560
- if message .nVersion < 209 :
1561
- conn .ver_recv = conn .ver_send
1427
+ assert message .nVersion >= MIN_VERSION_SUPPORTED , "Version {} received. Test framework only supports versions greater than {}" .format (message .nVersion , MIN_VERSION_SUPPORTED )
1428
+ conn .send_message (msg_verack ())
1562
1429
conn .nServices = message .nServices
1563
1430
1564
1431
# Connection helper methods
@@ -1616,14 +1483,14 @@ def sync_with_ping(self, timeout=60):
1616
1483
wait_until (test_function , timeout = timeout , lock = mininode_lock )
1617
1484
self .ping_counter += 1
1618
1485
1619
- # The actual NodeConn class
1620
- # This class provides an interface for a p2p connection to a specified node
1621
1486
class NodeConn (asyncore .dispatcher ):
1487
+ """The actual NodeConn class
1488
+
1489
+ This class provides an interface for a p2p connection to a specified node."""
1622
1490
messagemap = {
1623
1491
b"version" : msg_version ,
1624
1492
b"verack" : msg_verack ,
1625
1493
b"addr" : msg_addr ,
1626
- b"alert" : msg_alert ,
1627
1494
b"inv" : msg_inv ,
1628
1495
b"getdata" : msg_getdata ,
1629
1496
b"getblocks" : msg_getblocks ,
@@ -1740,40 +1607,27 @@ def got_data(self):
1740
1607
return
1741
1608
if self .recvbuf [:4 ] != self .MAGIC_BYTES [self .network ]:
1742
1609
raise ValueError ("got garbage %s" % repr (self .recvbuf ))
1743
- if self .ver_recv < 209 :
1744
- if len (self .recvbuf ) < 4 + 12 + 4 :
1745
- return
1746
- command = self .recvbuf [4 :4 + 12 ].split (b"\x00 " , 1 )[0 ]
1747
- msglen = struct .unpack ("<i" , self .recvbuf [4 + 12 :4 + 12 + 4 ])[0 ]
1748
- checksum = None
1749
- if len (self .recvbuf ) < 4 + 12 + 4 + msglen :
1750
- return
1751
- msg = self .recvbuf [4 + 12 + 4 :4 + 12 + 4 + msglen ]
1752
- self .recvbuf = self .recvbuf [4 + 12 + 4 + msglen :]
1753
- else :
1754
- if len (self .recvbuf ) < 4 + 12 + 4 + 4 :
1755
- return
1756
- command = self .recvbuf [4 :4 + 12 ].split (b"\x00 " , 1 )[0 ]
1757
- msglen = struct .unpack ("<i" , self .recvbuf [4 + 12 :4 + 12 + 4 ])[0 ]
1758
- checksum = self .recvbuf [4 + 12 + 4 :4 + 12 + 4 + 4 ]
1759
- if len (self .recvbuf ) < 4 + 12 + 4 + 4 + msglen :
1760
- return
1761
- msg = self .recvbuf [4 + 12 + 4 + 4 :4 + 12 + 4 + 4 + msglen ]
1762
- th = sha256 (msg )
1763
- h = sha256 (th )
1764
- if checksum != h [:4 ]:
1765
- raise ValueError ("got bad checksum " + repr (self .recvbuf ))
1766
- self .recvbuf = self .recvbuf [4 + 12 + 4 + 4 + msglen :]
1767
- if command in self .messagemap :
1768
- f = BytesIO (msg )
1769
- t = self .messagemap [command ]()
1770
- t .deserialize (f )
1771
- self .got_message (t )
1772
- else :
1773
- logger .warning ("Received unknown command from %s:%d: '%s' %s" % (self .dstaddr , self .dstport , command , repr (msg )))
1774
- raise ValueError ("Unknown command: '%s'" % (command ))
1610
+ if len (self .recvbuf ) < 4 + 12 + 4 + 4 :
1611
+ return
1612
+ command = self .recvbuf [4 :4 + 12 ].split (b"\x00 " , 1 )[0 ]
1613
+ msglen = struct .unpack ("<i" , self .recvbuf [4 + 12 :4 + 12 + 4 ])[0 ]
1614
+ checksum = self .recvbuf [4 + 12 + 4 :4 + 12 + 4 + 4 ]
1615
+ if len (self .recvbuf ) < 4 + 12 + 4 + 4 + msglen :
1616
+ return
1617
+ msg = self .recvbuf [4 + 12 + 4 + 4 :4 + 12 + 4 + 4 + msglen ]
1618
+ th = sha256 (msg )
1619
+ h = sha256 (th )
1620
+ if checksum != h [:4 ]:
1621
+ raise ValueError ("got bad checksum " + repr (self .recvbuf ))
1622
+ self .recvbuf = self .recvbuf [4 + 12 + 4 + 4 + msglen :]
1623
+ if command not in self .messagemap :
1624
+ raise ValueError ("Received unknown command from %s:%d: '%s' %s" % (self .dstaddr , self .dstport , command , repr (msg )))
1625
+ f = BytesIO (msg )
1626
+ t = self .messagemap [command ]()
1627
+ t .deserialize (f )
1628
+ self .got_message (t )
1775
1629
except Exception as e :
1776
- logger .exception ('got_data :' , repr (e ))
1630
+ logger .exception ('Error reading message :' , repr (e ))
1777
1631
raise
1778
1632
1779
1633
def send_message (self , message , pushbuf = False ):
@@ -1786,10 +1640,9 @@ def send_message(self, message, pushbuf=False):
1786
1640
tmsg += command
1787
1641
tmsg += b"\x00 " * (12 - len (command ))
1788
1642
tmsg += struct .pack ("<I" , len (data ))
1789
- if self .ver_send >= 209 :
1790
- th = sha256 (data )
1791
- h = sha256 (th )
1792
- tmsg += h [:4 ]
1643
+ th = sha256 (data )
1644
+ h = sha256 (th )
1645
+ tmsg += h [:4 ]
1793
1646
tmsg += data
1794
1647
with mininode_lock :
1795
1648
if (len (self .sendbuf ) == 0 and not pushbuf ):
@@ -1803,9 +1656,6 @@ def send_message(self, message, pushbuf=False):
1803
1656
self .last_sent = time .time ()
1804
1657
1805
1658
def got_message (self , message ):
1806
- if message .command == b"version" :
1807
- if message .nVersion <= BIP0031_VERSION :
1808
- self .messagemap [b'ping' ] = msg_ping_prebip31
1809
1659
if self .last_sent + 30 * 60 < time .time ():
1810
1660
self .send_message (self .messagemap [b'ping' ]())
1811
1661
self ._log_message ("receive" , message )
@@ -1838,13 +1688,3 @@ def run(self):
1838
1688
[ obj .handle_close () for obj in disconnected ]
1839
1689
asyncore .loop (0.1 , use_poll = True , map = mininode_socket_map , count = 1 )
1840
1690
logger .debug ("Network thread closing" )
1841
-
1842
-
1843
- # An exception we can raise if we detect a potential disconnect
1844
- # (p2p or rpc) before the test is complete
1845
- class EarlyDisconnectError (Exception ):
1846
- def __init__ (self , value ):
1847
- self .value = value
1848
-
1849
- def __str__ (self ):
1850
- return repr (self .value )
0 commit comments