Skip to content

Commit 38aa168

Browse files
author
neocogent
committed
add nodetxs demo
1 parent 0170f1f commit 38aa168

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

scripts/nodetxs

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/usr/bin/env python3
2+
3+
# Import dependencies
4+
import socket, time, random, hashlib, binascii
5+
from struct import pack, unpack, unpack_from
6+
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
7+
8+
# node access info
9+
rpc_user = 'userid'
10+
rpc_pwd = 'pwd'
11+
peer_ip_address = '192.168.0.12'
12+
peer_rpc_port = 8332
13+
peer_tcp_port = my_tcp_port = 8333
14+
my_ip_address = '127.0.0.1'
15+
16+
sub_version = "/FeeCalc:0.1.0/"
17+
magic_value = 0xd9b4bef9 # mainnet
18+
avg_txs_blk = 2000
19+
buffer_size = 4096
20+
txcnt = txprn = 0
21+
22+
feebins = [1,2,3,4,5,6,7,8,10,12,14,17,20,25,30,40,50,60,70,80,100,120,140,170,200,250,300,400,500,600,700,800,1000,1200,1400,1700,2000,3000,4000,5000,100000000]
23+
feetxs = [0] * len(feebins)
24+
#blkbins = [1,2,6,12,24,48,96,24*6,48*6,72*6]
25+
#feeblks = [0] * len(blkbins)
26+
27+
def mk_msg(command, payload):
28+
checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[0:4]
29+
return(pack('I12sI4s', magic_value, command.encode(), len(payload), checksum) + payload)
30+
31+
def create_network_address(ip_address, port):
32+
network_address = pack('>8s16sH', b'\x01',
33+
bytearray.fromhex("00000000000000000000ffff") + socket.inet_aton(ip_address), port)
34+
return(network_address)
35+
36+
def create_payload_version():
37+
version = 70015
38+
services = 0
39+
timestamp = int(time.time())
40+
addr_local = create_network_address(my_ip_address, my_tcp_port)
41+
addr_peer = create_network_address(peer_ip_address, peer_tcp_port)
42+
nonce = random.getrandbits(64)
43+
start_height = 0
44+
relay = False
45+
subver = sub_version.encode()
46+
subver = bytes(len(subver))+subver
47+
payload = pack('<LQQ26s26sQ%dsL?' % len(subver), version, services, timestamp, addr_peer,
48+
addr_local, nonce, subver, start_height, relay)
49+
return(payload)
50+
51+
def decodeVarInt(v):
52+
if v[0] <= 0xfc:
53+
return unpack('<B', v[0:1])[0],1
54+
if v[0] == 0xfd:
55+
return unpack('<H', v[1:3])[0],3
56+
if v[0] == 0xfe:
57+
return unpack('<I', v[1:5])[0],5
58+
return unpack('<Q', v[1:9])[0],9
59+
60+
def addFees(inv):
61+
global feetxs,txcnt,txprn
62+
count,sz = decodeVarInt(inv[:9])
63+
for n in range(count):
64+
t,txid = unpack('I32s', inv[sz+n*36:sz+36+n*36])
65+
if t == 1:
66+
try:
67+
tx = rpc.getmempoolentry(txid[::-1].hex())
68+
except JSONRPCException:
69+
print("BADTX", txid.hex())
70+
pass
71+
fee = int(tx['fees']['base']/tx['vsize']*100000000)
72+
for n in range(len(feebins)):
73+
if feebins[n] > fee:
74+
feetxs[max(n-1,0)] += 1
75+
break
76+
txcnt += 1
77+
else:
78+
print("BADINV")
79+
if txcnt > txprn+10:
80+
feesum = 0
81+
fees = [0] * len(feetxs)
82+
for n in range(len(feetxs)-1,-1,-1):
83+
feesum += feetxs[n]
84+
fees[n] = feesum
85+
for n in range(len(fees)):
86+
if fees[n] > 0:
87+
print('(%d,%d)' % (feebins[n],fees[n]),end ="")
88+
print("\n")
89+
txprn = txcnt
90+
91+
if __name__ == '__main__':
92+
93+
# init connection to node
94+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
95+
s.connect((peer_ip_address, peer_tcp_port))
96+
rpc = AuthServiceProxy("http://%s:%s@%s:%d" % (rpc_user,rpc_pwd,peer_ip_address,peer_rpc_port))
97+
98+
s.send(mk_msg('version', create_payload_version()))
99+
data = s.recv(buffer_size)
100+
101+
s.send(mk_msg('verack', b''))
102+
data = s.recv(buffer_size)
103+
104+
# request the mempool
105+
s.send(mk_msg('mempool', b''))
106+
107+
# clear filter allowing txs
108+
s.send(mk_msg('filterclear', b''))
109+
110+
data = b''
111+
while True:
112+
data += s.recv(buffer_size)
113+
if len(data) >= 24:
114+
size, = unpack_from('I', data, 16)
115+
while(len(data) < size+24):
116+
data += s.recv(buffer_size)
117+
payload = data[24:size+24]
118+
if data[4:7] == b'inv':
119+
addFees(payload)
120+
elif data[4:8] == b'ping':
121+
s.send(mk_msg('pong', payload))
122+
else:
123+
print("MSG", data[4:16].decode('ascii'))
124+
data = data[size+24:]
125+
126+
s.close()

0 commit comments

Comments
 (0)