26 from binascii
import hexlify, unhexlify
27 from io
import BytesIO
28 from codecs
import encode
30 from threading
import RLock
31 from threading
import Thread
37 BIP0031_VERSION = 60000
39 MY_SUBVERSION = b
"/python-mininode-tester:0.0.2/" 42 MAX_BLOCK_SIZE = 1000000
49 mininode_socket_map = dict()
57 mininode_lock = RLock()
61 return hashlib.new(
'sha256', s).digest()
68 return dash_hash.getPoWHash(s)
71 nit = struct.unpack(
"<B", f.read(1))[0]
73 nit = struct.unpack(
"<H", f.read(2))[0]
75 nit = struct.unpack(
"<I", f.read(4))[0]
77 nit = struct.unpack(
"<Q", f.read(8))[0]
83 return struct.pack(
"B", len(s)) + s
84 elif len(s) < 0x10000:
85 return struct.pack(
"<BH", 253, len(s)) + s
86 elif len(s) < 0x100000000L:
87 return struct.pack(
"<BI", 254, len(s)) + s
88 return struct.pack(
"<BQ", 255, len(s)) + s
94 t = struct.unpack(
"<I", f.read(4))[0]
102 rs += struct.pack(
"<I", u & 0xFFFFFFFFL)
109 t = struct.unpack(
"<IIIIIIII", s[:32])
111 r += t[i] << (i * 32)
116 nbytes = (c >> 24) & 0xFF
117 v = (c & 0xFFFFFFL) << (8 * (nbytes - 3))
122 nit = struct.unpack(
"<B", f.read(1))[0]
124 nit = struct.unpack(
"<H", f.read(2))[0]
126 nit = struct.unpack(
"<I", f.read(4))[0]
128 nit = struct.unpack(
"<Q", f.read(8))[0]
130 for i
in xrange(nit):
140 r = struct.pack(
"B", len(l))
141 elif len(l) < 0x10000:
142 r = struct.pack(
"<BH", 253, len(l))
143 elif len(l) < 0x100000000L:
144 r = struct.pack(
"<BI", 254, len(l))
146 r = struct.pack(
"<BQ", 255, len(l))
153 nit = struct.unpack(
"<B", f.read(1))[0]
155 nit = struct.unpack(
"<H", f.read(2))[0]
157 nit = struct.unpack(
"<I", f.read(4))[0]
159 nit = struct.unpack(
"<Q", f.read(8))[0]
161 for i
in xrange(nit):
170 r = struct.pack(
"B", len(l))
171 elif len(l) < 0x10000:
172 r = struct.pack(
"<BH", 253, len(l))
173 elif len(l) < 0x100000000L:
174 r = struct.pack(
"<BI", 254, len(l))
176 r = struct.pack(
"<BQ", 255, len(l))
183 nit = struct.unpack(
"<B", f.read(1))[0]
185 nit = struct.unpack(
"<H", f.read(2))[0]
187 nit = struct.unpack(
"<I", f.read(4))[0]
189 nit = struct.unpack(
"<Q", f.read(8))[0]
191 for i
in xrange(nit):
200 r = struct.pack(
"B", len(l))
201 elif len(l) < 0x10000:
202 r = struct.pack(
"<BH", 253, len(l))
203 elif len(l) < 0x100000000L:
204 r = struct.pack(
"<BI", 254, len(l))
206 r = struct.pack(
"<BQ", 255, len(l))
213 nit = struct.unpack(
"<B", f.read(1))[0]
215 nit = struct.unpack(
"<H", f.read(2))[0]
217 nit = struct.unpack(
"<I", f.read(4))[0]
219 nit = struct.unpack(
"<Q", f.read(8))[0]
221 for i
in xrange(nit):
222 t = struct.unpack(
"<i", f.read(4))[0]
230 r = struct.pack(
"B", len(l))
231 elif len(l) < 0x10000:
232 r = struct.pack(
"<BH", 253, len(l))
233 elif len(l) < 0x100000000L:
234 r = struct.pack(
"<BI", 254, len(l))
236 r = struct.pack(
"<BQ", 255, len(l))
238 r += struct.pack(
"<i", i)
243 obj.deserialize(BytesIO(unhexlify(hex_string.encode(
'ascii'))))
248 return hexlify(obj.serialize()).decode(
'ascii')
260 self.
nServices = struct.unpack(
"<Q", f.read(8))[0]
262 self.
ip = socket.inet_ntoa(f.read(4))
263 self.
port = struct.unpack(
">H", f.read(2))[0]
269 r += socket.inet_aton(self.
ip)
270 r += struct.pack(
">H", self.
port)
274 return "CAddress(nServices=%i ip=%s port=%i)" % (self.
nServices,
289 self.
type = struct.unpack(
"<i", f.read(4))[0]
294 r += struct.pack(
"<i", self.
type)
299 return "CInv(type=%s hash=%064x)" \
309 self.
nVersion = struct.unpack(
"<i", f.read(4))[0]
314 r += struct.pack(
"<i", self.
nVersion)
319 return "CBlockLocator(nVersion=%i vHave=%s)" \
330 self.
n = struct.unpack(
"<I", f.read(4))[0]
335 r += struct.pack(
"<I", self.
n)
339 return "COutPoint(hash=%064x n=%i)" % (self.
hash, self.
n)
343 def __init__(self, outpoint=None, scriptSig=b"", nSequence=0):
355 self.
nSequence = struct.unpack(
"<I", f.read(4))[0]
365 return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \
376 self.
nValue = struct.unpack(
"<q", f.read(8))[0]
381 r += struct.pack(
"<q", self.
nValue)
386 return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \
402 self.
vin = copy.deepcopy(tx.vin)
403 self.
vout = copy.deepcopy(tx.vout)
409 self.
nVersion = struct.unpack(
"<i", f.read(4))[0]
412 self.
nLockTime = struct.unpack(
"<I", f.read(4))[0]
418 r += struct.pack(
"<i", self.
nVersion)
435 for tout
in self.
vout:
436 if tout.nValue < 0
or tout.nValue > 21000000 * COIN:
441 return "CTransaction(nVersion=%i vin=%s vout=%s nLockTime=%i)" \
471 self.
nVersion = struct.unpack(
"<i", f.read(4))[0]
474 self.
nTime = struct.unpack(
"<I", f.read(4))[0]
475 self.
nBits = struct.unpack(
"<I", f.read(4))[0]
476 self.
nNonce = struct.unpack(
"<I", f.read(4))[0]
482 r += struct.pack(
"<i", self.
nVersion)
485 r += struct.pack(
"<I", self.
nTime)
486 r += struct.pack(
"<I", self.
nBits)
487 r += struct.pack(
"<I", self.
nNonce)
493 r += struct.pack(
"<i", self.
nVersion)
496 r += struct.pack(
"<I", self.
nTime)
497 r += struct.pack(
"<I", self.
nBits)
498 r += struct.pack(
"<I", self.
nNonce)
500 self.
hash = encode(
dashhash(r)[::-1],
'hex_codec').decode(
'ascii')
508 return "CBlockHeader(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x)" \
515 super(CBlock, self).
__init__(header)
533 while len(hashes) > 1:
535 for i
in xrange(0, len(hashes), 2):
536 i2 = min(i+1, len(hashes)-1)
537 newhashes.append(
hash256(hashes[i] + hashes[i2]))
547 if not tx.is_valid():
556 while self.
sha256 > target:
561 return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \
583 self.
nVersion = struct.unpack(
"<i", f.read(4))[0]
584 self.
nRelayUntil = struct.unpack(
"<q", f.read(8))[0]
585 self.
nExpiration = struct.unpack(
"<q", f.read(8))[0]
586 self.
nID = struct.unpack(
"<i", f.read(4))[0]
587 self.
nCancel = struct.unpack(
"<i", f.read(4))[0]
589 self.
nMinVer = struct.unpack(
"<i", f.read(4))[0]
590 self.
nMaxVer = struct.unpack(
"<i", f.read(4))[0]
592 self.
nPriority = struct.unpack(
"<i", f.read(4))[0]
599 r += struct.pack(
"<i", self.
nVersion)
602 r += struct.pack(
"<i", self.
nID)
603 r += struct.pack(
"<i", self.
nCancel)
605 r += struct.pack(
"<i", self.
nMinVer)
606 r += struct.pack(
"<i", self.
nMaxVer)
615 return "CUnsignedAlert(nVersion %d, nRelayUntil %d, nExpiration %d, nID %d, nCancel %d, nMinVer %d, nMaxVer %d, nPriority %d, strComment %s, strStatusBar %s, strReserved %s)" \
637 return "CAlert(vchMsg.sz %d, vchSig.sz %d)" \
656 self.
nVersion = struct.unpack(
"<i", f.read(4))[0]
659 self.
nServices = struct.unpack(
"<Q", f.read(8))[0]
660 self.
nTime = struct.unpack(
"<q", f.read(8))[0]
666 self.
nNonce = struct.unpack(
"<Q", f.read(8))[0]
680 r += struct.pack(
"<i", self.
nVersion)
682 r += struct.pack(
"<q", self.
nTime)
685 r += struct.pack(
"<Q", self.
nNonce)
691 return 'msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i)' \
710 return "msg_verack()" 726 return "msg_addr(addrs=%s)" % (repr(self.
addrs))
745 return "msg_alert(alert=%s)" % (repr(self.
alert), )
764 return "msg_inv(inv=%s)" % (repr(self.
inv))
771 self.
inv = inv
if inv !=
None else []
780 return "msg_getdata(inv=%s)" % (repr(self.
inv))
784 command = b
"getblocks" 802 return "msg_getblocks(locator=%s hashstop=%064x)" \
819 return "msg_tx(tx=%s)" % (repr(self.
tx))
838 return "msg_block(block=%s)" % (repr(self.
block))
854 return "msg_getaddr()" 870 return "msg_ping() (pre-bip31)" 880 self.
nonce = struct.unpack(
"<Q", f.read(8))[0]
884 r += struct.pack(
"<Q", self.
nonce)
888 return "msg_ping(nonce=%08x)" % self.
nonce 898 self.
nonce = struct.unpack(
"<Q", f.read(8))[0]
902 r += struct.pack(
"<Q", self.
nonce)
906 return "msg_pong(nonce=%08x)" % self.
nonce 922 return "msg_mempool()" 925 command = b
"sendheaders" 937 return "msg_sendheaders()" 944 command = b
"getheaders" 962 return "msg_getheaders(locator=%s, stop=%064x)" \
985 return "msg_headers(headers=%s)" % repr(self.
headers)
1000 self.
code = struct.unpack(
"<B", f.read(1))[0]
1008 r += struct.pack(
"<B", self.
code)
1016 return "msg_reject: %s %d %s [%064x]" \
1020 def wait_until(predicate, attempts=float(
'inf'), timeout=float(
'inf')):
1024 while attempt < attempts
and elapsed < timeout:
1065 if deliver_sleep
is not None:
1066 time.sleep(deliver_sleep)
1069 getattr(self,
'on_' + message.command)(conn, message)
1071 print "ERROR delivering %s (%s)" % (repr(message),
1075 if message.nVersion >= 209:
1077 conn.ver_send = min(MY_VERSION, message.nVersion)
1078 if message.nVersion < 209:
1079 conn.ver_recv = conn.ver_send
1082 conn.ver_recv = conn.ver_send
1087 for i
in message.inv:
1091 conn.send_message(want)
1103 if conn.ver_send > BIP0031_VERSION:
1104 conn.send_message(
msg_pong(message.nonce))
1113 NodeConnCB.__init__(self)
1130 def received_pong():
1141 b
"version": msg_version,
1142 b
"verack": msg_verack,
1144 b
"alert": msg_alert,
1146 b
"getdata": msg_getdata,
1147 b
"getblocks": msg_getblocks,
1149 b
"block": msg_block,
1150 b
"getaddr": msg_getaddr,
1153 b
"headers": msg_headers,
1154 b
"getheaders": msg_getheaders,
1155 b
"reject": msg_reject,
1156 b
"mempool": msg_mempool,
1159 "mainnet": b
"\xbf\x0c\x6b\xbd",
1160 "testnet3": b
"\xce\xe2\xca\xff",
1161 "regtest": b
"\xfc\xc1\xb7\xdc" 1164 def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=1):
1165 asyncore.dispatcher.__init__(self, map=mininode_socket_map)
1166 self.
log = logging.getLogger(
"NodeConn(%s:%d)" % (dstaddr, dstport))
1169 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
1182 vt.nServices = services
1185 vt.addrFrom.ip =
"0.0.0.0" 1186 vt.addrFrom.port = 0
1188 print 'MiniNode: Connecting to Dash Node IP # ' + dstaddr +
':' \
1192 self.connect((dstaddr, dstport))
1202 self.
state =
"connected" 1207 self.
state =
"closed" 1214 self.
cb.on_close(self)
1236 sent = self.send(self.
sendbuf)
1248 raise ValueError(
"got garbage %s" % repr(self.
recvbuf))
1250 if len(self.
recvbuf) < 4 + 12 + 4:
1252 command = self.
recvbuf[4:4+12].split(b
"\x00", 1)[0]
1253 msglen = struct.unpack(
"<i", self.
recvbuf[4+12:4+12+4])[0]
1255 if len(self.
recvbuf) < 4 + 12 + 4 + msglen:
1257 msg = self.
recvbuf[4+12+4:4+12+4+msglen]
1260 if len(self.
recvbuf) < 4 + 12 + 4 + 4:
1262 command = self.
recvbuf[4:4+12].split(b
"\x00", 1)[0]
1263 msglen = struct.unpack(
"<i", self.
recvbuf[4+12:4+12+4])[0]
1264 checksum = self.
recvbuf[4+12+4:4+12+4+4]
1265 if len(self.
recvbuf) < 4 + 12 + 4 + 4 + msglen:
1267 msg = self.
recvbuf[4+12+4+4:4+12+4+4+msglen]
1270 if checksum != h[:4]:
1271 raise ValueError(
"got bad checksum " + repr(self.
recvbuf))
1281 except Exception
as e:
1282 print 'got_data:', repr(e)
1285 if self.
state !=
"connected" and not pushbuf:
1288 command = message.command
1289 data = message.serialize()
1292 tmsg += b
"\x00" * (12 - len(command))
1293 tmsg += struct.pack(
"<I", len(data))
1304 if message.command == b
"version":
1305 if message.nVersion <= BIP0031_VERSION:
1307 if self.
last_sent + 30 * 60 < time.time():
1310 self.
cb.deliver(self, message)
1318 while mininode_socket_map:
1323 for fd, obj
in mininode_socket_map.items():
1325 disconnected.append(obj)
1326 [ obj.handle_close()
for obj
in disconnected ]
1327 asyncore.loop(0.1, use_poll=
True, map=mininode_socket_map, count=1)
1337 return repr(self.
value)
def __init__(self, inv=None)
def uint256_from_compact(c)
def add_connection(self, conn)
def __init__(self, tx=CTransaction())
def __init__(self, nonce=0L)
def __init__(self, value)
def deliver(self, conn, message)
def on_getblocks(self, conn, message)
def deser_string_vector(f)
def on_headers(self, conn, message)
def FromHex(obj, hex_string)
def on_alert(self, conn, message)
def on_getaddr(self, conn, message)
def get_deliver_sleep_time(self)
def on_getheaders(self, conn, message)
def __init__(self, outpoint=None, scriptSig=b"", nSequence=0)
def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=1)
def on_ping(self, conn, message)
def on_verack(self, conn, message)
def on_getdata(self, conn, message)
def __init__(self, t=0, h=0L)
def wait_until(predicate, attempts=float('inf'), timeout=float('inf'))
def __init__(self, inv=None)
def sync_with_ping(self, timeout=30)
def on_addr(self, conn, message)
def disconnect_node(self)
def on_tx(self, conn, message)
def on_pong(self, conn, message)
def on_mempool(self, conn)
def __init__(self, nValue=0, scriptPubKey=b"")
def on_pong(self, conn, message)
def __init__(self, header=None)
def __init__(self, nonce=0)
def on_reject(self, conn, message)
def send_message(self, message, pushbuf=False)
def calc_merkle_root(self)
def on_inv(self, conn, message)
def on_version(self, conn, message)
def set_deliver_sleep_time(self, value)
def ser_uint256_vector(l)
def got_message(self, message)
Internal SHA-256 implementation.
def __init__(self, block=None)
def __init__(self, tx=None)
def show_debug_msg(self, msg)
def wait_for_verack(self)
def deser_uint256_vector(f)
def send_message(self, message)
UniValue debug(const UniValue ¶ms, bool fHelp)
def __init__(self, hash=0, n=0)
def on_block(self, conn, message)