Skip to content

Commit be735cf

Browse files
committed
re-add pegging python test
1 parent 3ba146d commit be735cf

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed

qa/rpc-tests/pegging.py

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
#!/usr/bin/env python2
2+
3+
from test_framework.authproxy import AuthServiceProxy, JSONRPCException
4+
import os
5+
import random
6+
import sys
7+
import time
8+
import subprocess
9+
import shutil
10+
11+
if len(sys.argv) != 3:
12+
print("paths to bitcoind and sidechain daemon must be included as arguments")
13+
sys.exit(0)
14+
print(sys.argv[1])
15+
print(sys.argv[2])
16+
17+
def sync_all(sidechain, sidechain2):
18+
timeout = 20
19+
while len(sidechain.getrawmempool()) != len(sidechain2.getrawmempool()):
20+
time.sleep(1)
21+
timeout -= 1
22+
if timeout == 0:
23+
raise Exception("Peg-in has failed to propagate.")
24+
sidechain2.generate(1)
25+
while sidechain.getblockcount() != sidechain2.getblockcount():
26+
time.sleep(1)
27+
timeout -= 1
28+
if timeout == 0:
29+
raise Exception("Blocks are not propagating.")
30+
31+
fedpeg_key="cPxqWyf1HDGpGFH1dnfjz8HbiWxvwG8WXyetbuAiw4thKXUdXLpR"
32+
fedpeg_pubkey="512103dff4923d778550cc13ce0d887d737553b4b58f4e8e886507fc39f5e447b2186451ae"
33+
34+
bitcoin_datadir="/tmp/"+''.join(random.choice('0123456789ABCDEF') for i in range(5))
35+
bitcoin_pass=''.join(random.choice('0123456789ABCDEF') for i in range(10))
36+
sidechain_datadir="/tmp/"+''.join(random.choice('0123456789ABCDEF') for i in range(5))
37+
sidechain_pass=''.join(random.choice('0123456789ABCDEF') for i in range(10))
38+
sidechain2_datadir="/tmp/"+''.join(random.choice('0123456789ABCDEF') for i in range(5))
39+
sidechain2_pass=''.join(random.choice('0123456789ABCDEF') for i in range(10))
40+
41+
bitcoin_port = 8000 + os.getpid()%999
42+
sidechain_port = bitcoin_port + 1
43+
sidechain2_port = bitcoin_port + 2
44+
sidechain1_p2p_port = bitcoin_port + 3
45+
sidechain2_p2p_port = bitcoin_port + 4
46+
47+
os.makedirs(bitcoin_datadir)
48+
os.makedirs(sidechain_datadir)
49+
os.makedirs(sidechain2_datadir)
50+
51+
with open(os.path.join(bitcoin_datadir, "bitcoin.conf"), 'w') as f:
52+
f.write("regtest=1\n")
53+
f.write("rpcuser=bitcoinrpc\n")
54+
f.write("rpcpassword="+bitcoin_pass+"\n")
55+
f.write("rpcport="+str(bitcoin_port)+"\n")
56+
f.write("discover=0\n")
57+
f.write("listen=0\n")
58+
f.write("testnet=0\n")
59+
f.write("txindex=1\n")
60+
f.write("daemon=1\n")
61+
f.write("listen=0\n")
62+
63+
with open(os.path.join(sidechain_datadir, "elements.conf"), 'w') as f:
64+
f.write("regtest=1\n")
65+
f.write("rpcuser=sidechainrpc\n")
66+
f.write("rpcpassword="+sidechain_pass+"\n")
67+
f.write("rpcport="+str(sidechain_port)+"\n")
68+
f.write("discover=0\n")
69+
f.write("testnet=0\n")
70+
f.write("txindex=1\n")
71+
f.write("fedpegscript="+fedpeg_pubkey+"\n")
72+
f.write("daemon=1\n")
73+
f.write("mainchainrpchost=127.0.0.1\n")
74+
f.write("mainchainrpcport="+str(bitcoin_port)+"\n")
75+
f.write("mainchainrpcuser=bitcoinrpc\n")
76+
f.write("mainchainrpcpassword="+bitcoin_pass+"\n")
77+
f.write("validatepegin=1\n")
78+
f.write("validatepegout=0\n")
79+
f.write("port="+str(sidechain1_p2p_port)+"\n")
80+
f.write("connect=localhost:"+str(sidechain2_p2p_port)+"\n")
81+
f.write("listen=1\n")
82+
83+
with open(os.path.join(sidechain2_datadir, "elements.conf"), 'w') as f:
84+
f.write("regtest=1\n")
85+
f.write("rpcuser=sidechainrpc2\n")
86+
f.write("rpcpassword="+sidechain2_pass+"\n")
87+
f.write("rpcport="+str(sidechain2_port)+"\n")
88+
f.write("discover=0\n")
89+
f.write("testnet=0\n")
90+
f.write("txindex=1\n")
91+
f.write("fedpegscript="+fedpeg_pubkey+"\n")
92+
f.write("daemon=1\n")
93+
f.write("mainchainrpchost=127.0.0.1\n")
94+
f.write("mainchainrpcport="+str(bitcoin_port)+"\n")
95+
f.write("mainchainrpcuser=bitcoinrpc\n")
96+
f.write("mainchainrpcpassword="+bitcoin_pass+"\n")
97+
f.write("validatepegin=1\n")
98+
f.write("validatepegout=0\n")
99+
f.write("port="+str(sidechain2_p2p_port)+"\n")
100+
f.write("connect=localhost:"+str(sidechain1_p2p_port)+"\n")
101+
f.write("listen=1\n")
102+
103+
try:
104+
105+
# Default is 8, meaning 8+2 confirms for wallet acceptance normally
106+
# this will require 10+2.
107+
sidechain_args = " -peginconfirmationdepth=10 "
108+
109+
# Start daemons
110+
print("Starting daemons at "+bitcoin_datadir+", "+sidechain_datadir+" and "+sidechain2_datadir)
111+
bitcoindstart = sys.argv[1]+"/bitcoind -datadir="+bitcoin_datadir
112+
subprocess.Popen(bitcoindstart.split(), stdout=subprocess.PIPE)
113+
114+
sidechainstart = sys.argv[2]+"/elementsd -datadir="+sidechain_datadir + sidechain_args
115+
subprocess.Popen(sidechainstart.split(), stdout=subprocess.PIPE)
116+
117+
sidechain2start = sys.argv[2]+"/elementsd -datadir="+sidechain2_datadir + sidechain_args
118+
subprocess.Popen(sidechain2start.split(), stdout=subprocess.PIPE)
119+
120+
print("Daemons started")
121+
time.sleep(3)
122+
123+
bitcoin = AuthServiceProxy("http://bitcoinrpc:"+bitcoin_pass+"@127.0.0.1:"+str(bitcoin_port))
124+
sidechain = AuthServiceProxy("http://sidechainrpc:"+sidechain_pass+"@127.0.0.1:"+str(sidechain_port))
125+
sidechain2 = AuthServiceProxy("http://sidechainrpc2:"+sidechain2_pass+"@127.0.0.1:"+str(sidechain2_port))
126+
print("Daemons started, making blocks to get funds")
127+
128+
bitcoin.generate(101)
129+
sidechain.generate(101)
130+
131+
addr = bitcoin.getnewaddress()
132+
133+
addrs = sidechain.getpeginaddress()
134+
txid1 = bitcoin.sendtoaddress(addrs["mainchain_address"], 24)
135+
# 10+2 confirms required to get into mempool and confirm
136+
bitcoin.generate(11)
137+
time.sleep(2)
138+
proof = bitcoin.gettxoutproof([txid1])
139+
raw = bitcoin.getrawtransaction(txid1)
140+
141+
print("Attempting peg-in")
142+
try:
143+
pegtxid = sidechain.claimpegin(raw, proof)
144+
raise Exception("Peg-in should not mature enough yet, need another block.")
145+
except JSONRPCException as e:
146+
assert("Peg-in Bitcoin transaction needs more confirmations to be sent." in e.error["message"])
147+
pass
148+
149+
# Should fail due to non-matching wallet address
150+
try:
151+
pegtxid = sidechain.claimpegin(raw, proof, sidechain.getnewaddress())
152+
raise Exception("Peg-in with non-matching witness_program should fail.")
153+
except JSONRPCException as e:
154+
assert("Given witness_program is not a valid v0 witness program" in e.error["message"])
155+
pass
156+
157+
# 12 confirms allows in mempool
158+
bitcoin.generate(1)
159+
160+
# Should succeed via wallet lookup for address match, and when given
161+
pegtxid1 = sidechain.claimpegin(raw, proof)
162+
163+
sync_all(sidechain, sidechain2)
164+
165+
tx1 = sidechain.gettransaction(pegtxid1)
166+
167+
if "confirmations" in tx1 and tx1["confirmations"] > 0:
168+
print("Peg-in is confirmed: Success!")
169+
else:
170+
raise Exception("Peg-in confirmation has failed.")
171+
172+
# Do many claims in mempool
173+
n_claims = 100
174+
175+
print("Flooding mempool with many small claims")
176+
pegtxs = []
177+
sidechain.generate(101)
178+
179+
for i in range(n_claims):
180+
addrs = sidechain.getpeginaddress()
181+
txid = bitcoin.sendtoaddress(addrs["mainchain_address"], 1)
182+
bitcoin.generate(12)
183+
proof = bitcoin.gettxoutproof([txid])
184+
raw = bitcoin.getrawtransaction(txid)
185+
pegtxs += [sidechain.claimpegin(raw, proof)]
186+
187+
sync_all(sidechain, sidechain2)
188+
189+
sidechain2.generate(1)
190+
for pegtxid in pegtxs:
191+
tx = sidechain.gettransaction(pegtxid)
192+
if "confirmations" not in tx or tx["confirmations"] == 0:
193+
raise Exception("Peg-in confirmation has failed.")
194+
195+
# TODO test reorgs, conflicting peg-ins
196+
197+
print("Success!")
198+
199+
except JSONRPCException as e:
200+
print("Pegging testing failed, aborting:")
201+
print(e.error)
202+
except Exception as e:
203+
print("Pegging testing failed, aborting:")
204+
print(e)
205+
206+
print("Stopping daemons and cleaning up")
207+
bitcoin.stop()
208+
sidechain.stop()
209+
210+
time.sleep(5)
211+
212+
shutil.rmtree(sidechain_datadir)
213+
shutil.rmtree(bitcoin_datadir)

0 commit comments

Comments
 (0)