diff --git a/qa/rpc-tests/feature_fedpeg.py b/qa/rpc-tests/feature_fedpeg.py index 698133b029..759cb5f572 100755 --- a/qa/rpc-tests/feature_fedpeg.py +++ b/qa/rpc-tests/feature_fedpeg.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from decimal import Decimal +import os import json import time @@ -10,8 +11,8 @@ connect_nodes_bi, rpc_auth_pair, rpc_port, + p2p_port, start_node, - start_nodes, stop_node, ) @@ -47,30 +48,59 @@ def __init__(self): self.setup_clean_chain = True self.num_nodes = 4 + def add_options(self, parser): + parser.add_option("--parent_binpath", dest="parent_binpath", default="", + help="Use a different binary for launching nodes") + parser.add_option("--parent_bitcoin", dest="parent_bitcoin", default=False, action="store_true", + help="Parent nodes are Bitcoin") + def setup_network(self, split=False): + if self.options.parent_bitcoin and self.options.parent_binpath == "": + raise Exception("Can't run with --parent_bitcoin without specifying --parent_binpath") + self.nodes = [] + self.extra_args = [] # Parent chain args - self.extra_args = [[ - # '-printtoconsole', - '-validatepegin=0', - '-anyonecanspendaremine', - '-initialfreecoins=2100000000000000', - ]] * 2 - - self.nodes = start_nodes(2, self.options.tmpdir, self.extra_args[:2], chain='parent') + for n in range(2): + if self.options.parent_bitcoin: + self.parent_chain = 'regtest' + rpc_u, rpc_p = rpc_auth_pair(n) + self.extra_args.append([ + "-printtoconsole=0", + "-port="+str(p2p_port(n)), + "-rpcuser="+rpc_u, + "-rpcpassword="+rpc_p, + "-rpcport="+str(rpc_port(n)), + "-addresstype=legacy", # To make sure bitcoind gives back p2pkh no matter version + "-deprecatedrpc=validateaddress", + ]) + else: + self.parent_chain = 'parent' + self.extra_args.append([ + "-printtoconsole=0", + '-validatepegin=0', + '-anyonecanspendaremine', + '-initialfreecoins=2100000000000000', + ]) + self.binary = self.options.parent_binpath if self.options.parent_binpath != "" else None + self.nodes.append(start_node(n, self.options.tmpdir, self.extra_args[n], binary=self.binary, chain=self.parent_chain)) + connect_nodes_bi(self.nodes, 0, 1) self.parentgenesisblockhash = self.nodes[0].getblockhash(0) print('parentgenesisblockhash', self.parentgenesisblockhash) - parent_pegged_asset = self.nodes[0].getsidechaininfo()['pegged_asset'] + if not self.options.parent_bitcoin: + parent_pegged_asset = self.nodes[0].getsidechaininfo()['pegged_asset'] # Sidechain args + self.fedpeg_script = "512103dff4923d778550cc13ce0d887d737553b4b58f4e8e886507fc39f5e447b2186451ae" parent_chain_signblockscript = '51' for n in range(2): rpc_u, rpc_p = rpc_auth_pair(n) - self.extra_args.append([ - # '-printtoconsole', + args = [ + "-printtoconsole=0", '-parentgenesisblockhash=%s' % self.parentgenesisblockhash, '-validatepegin=1', + '-fedpegscript=%s' % self.fedpeg_script, '-anyonecanspendaremine=0', '-initialfreecoins=0', '-peginconfirmationdepth=10', @@ -78,11 +108,15 @@ def setup_network(self, split=False): '-mainchainrpcport=%s' % rpc_port(n), '-mainchainrpcuser=%s' % rpc_u, '-mainchainrpcpassword=%s' % rpc_p, - '-parentpubkeyprefix=235', - '-parentscriptprefix=75', - '-con_parent_chain_signblockscript=%s' % parent_chain_signblockscript, - '-con_parent_pegged_asset=%s' % parent_pegged_asset, - ]) + ] + if not self.options.parent_bitcoin: + args.extend([ + '-parentpubkeyprefix=235', + '-parentscriptprefix=75', + '-con_parent_chain_signblockscript=%s' % parent_chain_signblockscript, + '-con_parent_pegged_asset=%s' % parent_pegged_asset, + ]) + self.extra_args.append(args) self.nodes.append(start_node(n + 2, self.options.tmpdir, self.extra_args[n + 2], chain='sidechain')) connect_nodes_bi(self.nodes, 2, 3) @@ -116,10 +150,10 @@ def run_test(self): sidechain.generate(101) addrs = sidechain.getpeginaddress() - addr = parent.validateaddress(addrs["mainchain_address"]) + addr = addrs["mainchain_address"] print('addrs', addrs) - print('addr', addr) - txid1 = parent.sendtoaddress(addrs["mainchain_address"], 24) + print(parent.validateaddress(addr)) + txid1 = parent.sendtoaddress(addr, 24) # 10+2 confirms required to get into mempool and confirm parent.generate(1) time.sleep(2) @@ -134,7 +168,7 @@ def run_test(self): pegtxid = sidechain.claimpegin(raw, proof) raise Exception("Peg-in should not be mature enough yet, need another block.") except JSONRPCException as e: - print('ERROR:', e.error) + print('RPC ERROR:', e.error['message']) assert("Peg-in Bitcoin transaction needs more confirmations to be sent." in e.error["message"]) # Second attempt simply doesn't hit mempool bar @@ -143,23 +177,24 @@ def run_test(self): pegtxid = sidechain.claimpegin(raw, proof) raise Exception("Peg-in should not be mature enough yet, need another block.") except JSONRPCException as e: + print('RPC ERROR:', e.error['message']) assert("Peg-in Bitcoin transaction needs more confirmations to be sent." in e.error["message"]) - # Should fail due to non-witness try: - pegtxid = sidechain.claimpegin(raw, proof, get_new_unconfidential_address(parent)) - raise Exception("Peg-in with non-matching claim_script should fail.") + pegtxid = sidechain.createrawpegin(raw, proof, 'AEIOU') + raise Exception("Peg-in with non-hex claim_script should fail.") except JSONRPCException as e: - print(e.error["message"]) - assert("Given or recovered script is not a witness program." in e.error["message"]) + print('RPC ERROR:', e.error['message']) + assert("Given claim_script is not hex." in e.error["message"]) - # # Should fail due to non-matching wallet address - # try: - # pegtxid = sidechain.claimpegin(raw, proof, get_new_unconfidential_address(sidechain)) - # raise Exception("Peg-in with non-matching claim_script should fail.") - # except JSONRPCException as e: - # print(e.error["message"]) - # assert("Given claim_script does not match the given Bitcoin transaction." in e.error["message"]) + # Should fail due to non-matching wallet address + try: + scriptpubkey = sidechain.validateaddress(get_new_unconfidential_address(sidechain))["scriptPubKey"] + pegtxid = sidechain.claimpegin(raw, proof, scriptpubkey) + raise Exception("Peg-in with non-matching claim_script should fail.") + except JSONRPCException as e: + print('RPC ERROR:', e.error['message']) + assert("Given claim_script does not match the given Bitcoin transaction." in e.error["message"]) # 12 confirms allows in mempool parent.generate(1) @@ -269,7 +304,7 @@ def run_test(self): print ("Now test failure to validate peg-ins based on intermittant bitcoind rpc failure") stop_node(self.nodes[1], 1) - txid = parent.sendtoaddress(addrs["mainchain_address"], 1) + txid = parent.sendtoaddress(addr, 1) parent.generate(12) proof = parent.gettxoutproof([txid]) raw = parent.getrawtransaction(txid) @@ -281,7 +316,7 @@ def run_test(self): assert(sidechain.getblockcount() != sidechain2.getblockcount()) print("Restarting parent2") - self.nodes[1] = start_node(1, self.options.tmpdir, self.extra_args[1], chain='parent') + self.nodes[1] = start_node(1, self.options.tmpdir, self.extra_args[1], binary=self.binary, chain=self.parent_chain) parent2 = self.nodes[1] connect_nodes_bi(self.nodes, 0, 1) time.sleep(5) diff --git a/qa/rpc-tests/pegging.py b/qa/rpc-tests/pegging.py deleted file mode 100755 index 1283f7dd82..0000000000 --- a/qa/rpc-tests/pegging.py +++ /dev/null @@ -1,450 +0,0 @@ -#!/usr/bin/env python3 - -from test_framework.authproxy import AuthServiceProxy, JSONRPCException -import os -import random -import sys -import time -import subprocess -import shutil -from decimal import Decimal - -if len(sys.argv) < 2: - print("path to bitcoind must be included as argument") - sys.exit(0) -bitcoin_bin_path = sys.argv[1] -sidechain_bin_path = os.path.normpath(os.path.dirname(os.path.realpath(__file__))+"/../../src") -if len(sys.argv) > 2: - sidechain_bin_path = sys.argv[2] - -print(bitcoin_bin_path) -print(sidechain_bin_path) - -# Sync mempool, make a block, sync blocks -def sync_all(sidechain, sidechain2, makeblock=True): - block = "" - timeout = 20 - while len(sidechain.getrawmempool()) != len(sidechain2.getrawmempool()): - time.sleep(1) - timeout -= 1 - if timeout == 0: - raise Exception("Peg-in has failed to propagate.") - if makeblock: - block = sidechain2.generate(1) - while sidechain.getblockcount() != sidechain2.getblockcount(): - time.sleep(1) - timeout -= 1 - if timeout == 0: - raise Exception("Blocks are not propagating.") - return block - -fedpeg_key="cPxqWyf1HDGpGFH1dnfjz8HbiWxvwG8WXyetbuAiw4thKXUdXLpR" -fedpeg_pubkey="512103dff4923d778550cc13ce0d887d737553b4b58f4e8e886507fc39f5e447b2186451ae" - -def get_pseudorandom_str(str_length=10): - return ''.join(random.choice('0123456789ABCDEF') for i in range(str_length)) - -def get_temp_dir(nodename): - return "/tmp/%s_%s" % (nodename, get_pseudorandom_str()) - -bitcoin_datadir = get_temp_dir('bitcoin') -bitcoin_pass = get_pseudorandom_str() -sidechain_datadir = get_temp_dir('sidechain') -sidechain_pass = get_pseudorandom_str() -sidechain2_datadir = get_temp_dir('sidechain2') -sidechain2_pass = get_pseudorandom_str() -bitcoin2_datadir = get_temp_dir('bitcoin2') -bitcoin2_rpccookiefile = bitcoin2_datadir + '/regtest/.cookie' - -bitcoin_port = 8000 + os.getpid()%999 -sidechain_port = bitcoin_port + 1 -sidechain2_port = bitcoin_port + 2 -sidechain1_p2p_port = bitcoin_port + 3 -sidechain2_p2p_port = bitcoin_port + 4 -bitcoin2_port = bitcoin_port + 5 -bitcoin2_p2p_port = bitcoin_port + 6 -bitcoin_p2p_port = bitcoin_port + 7 - -bitcoin = None -bitcoin2 = None -sidechain = None -sidechain2 = None - -os.makedirs(bitcoin_datadir) -os.makedirs(sidechain_datadir) -os.makedirs(sidechain2_datadir) -os.makedirs(bitcoin2_datadir) - -def write_bitcoin_conf(datadir, rpcport, rpcpass=None, p2p_port=None, connect_port=None): - with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f: - f.write("regtest=1\n") - if p2p_port: - f.write("port="+str(p2p_port)+"\n") - if rpcpass: - f.write("rpcuser=bitcoinrpc\n") - f.write("rpcpassword="+rpcpass+"\n") - f.write("rpcport="+str(rpcport)+"\n") - f.write("discover=0\n") - f.write("testnet=0\n") - f.write("txindex=1\n") - f.write("daemon=1\n") - # To make sure bitcoind gives back p2pkh no matter version - f.write("addresstype=legacy\n") - if connect_port: - f.write("connect=localhost:"+str(connect_port)+"\n") - f.write("listen=1\n") - else: - f.write("listen=0\n") - -write_bitcoin_conf(bitcoin_datadir, bitcoin_port, bitcoin_pass, p2p_port=bitcoin_p2p_port, connect_port=bitcoin2_p2p_port) -write_bitcoin_conf(bitcoin2_datadir, bitcoin2_port, rpcpass=None, p2p_port=bitcoin2_p2p_port, connect_port=bitcoin_p2p_port) - -with open(os.path.join(sidechain_datadir, "elements.conf"), 'w') as f: - f.write("regtest=1\n") - f.write("rpcuser=sidechainrpc\n") - f.write("rpcpassword="+sidechain_pass+"\n") - f.write("rpcport="+str(sidechain_port)+"\n") - f.write("discover=0\n") - f.write("testnet=0\n") - f.write("txindex=1\n") - f.write("fedpegscript="+fedpeg_pubkey+"\n") - f.write("daemon=1\n") - f.write("mainchainrpchost=127.0.0.1\n") - f.write("mainchainrpcport="+str(bitcoin_port)+"\n") - f.write("mainchainrpcuser=bitcoinrpc\n") - f.write("mainchainrpcpassword="+bitcoin_pass+"\n") - f.write("validatepegin=1\n") - f.write("port="+str(sidechain1_p2p_port)+"\n") - f.write("connect=localhost:"+str(sidechain2_p2p_port)+"\n") - f.write("listen=1\n") - f.write("fallbackfee=0.0001\n") - f.write("initialfreecoins=2100000000000000\n") - -with open(os.path.join(sidechain2_datadir, "elements.conf"), 'w') as f: - f.write("regtest=1\n") - f.write("rpcuser=sidechainrpc2\n") - f.write("rpcpassword="+sidechain2_pass+"\n") - f.write("rpcport="+str(sidechain2_port)+"\n") - f.write("discover=0\n") - f.write("testnet=0\n") - f.write("txindex=1\n") - f.write("fedpegscript="+fedpeg_pubkey+"\n") - f.write("daemon=1\n") - f.write("mainchainrpchost=127.0.0.1\n") - f.write("mainchainrpcport="+str(bitcoin2_port)+"\n") - f.write("mainchainrpccookiefile=%s\n" % bitcoin2_rpccookiefile) - f.write("validatepegin=1\n") - f.write("port="+str(sidechain2_p2p_port)+"\n") - f.write("connect=localhost:"+str(sidechain1_p2p_port)+"\n") - f.write("listen=1\n") - f.write("fallbackfee=0.0001\n") - f.write("initialfreecoins=2100000000000000\n") - -def test_pegout(parent_chain_addr, sidechain): - pegout_txid = sidechain.sendtomainchain(parent_chain_addr, 1) - raw_pegout = sidechain.getrawtransaction(pegout_txid, True) - assert 'vout' in raw_pegout and len(raw_pegout['vout']) > 0 - pegout_tested = False - for output in raw_pegout['vout']: - scriptPubKey = output['scriptPubKey'] - if 'type' in scriptPubKey and scriptPubKey['type'] == 'nulldata': - assert ('pegout_hex' in scriptPubKey and 'pegout_asm' in scriptPubKey and 'pegout_type' in scriptPubKey and - 'pegout_chain' in scriptPubKey and 'pegout_reqSigs' in scriptPubKey and 'pegout_addresses' in scriptPubKey) - assert scriptPubKey['pegout_chain'] == '0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206' #testnet3 - assert scriptPubKey['pegout_reqSigs'] == 1 - assert parent_chain_addr in scriptPubKey['pegout_addresses'] - pegout_tested = True - break - assert pegout_tested - -try: - - # Default is 8, meaning 8+2 confirms for wallet acceptance normally - # this will require 10+2. - sidechain_args = " -peginconfirmationdepth=10 " - - # Start daemons - print("Starting daemons at "+bitcoin_datadir+", "+bitcoin2_datadir+", "+sidechain_datadir+" and "+sidechain2_datadir) - bitcoindstart = bitcoin_bin_path+"/bitcoind -datadir="+bitcoin_datadir - subprocess.Popen(bitcoindstart.split(), stdout=subprocess.PIPE) - - bitcoind2start = bitcoin_bin_path+"/bitcoind -datadir="+bitcoin2_datadir - subprocess.Popen(bitcoind2start.split(), stdout=subprocess.PIPE) - - sidechainstart = sidechain_bin_path+"/elementsd -datadir="+sidechain_datadir + sidechain_args - subprocess.Popen(sidechainstart.split(), stdout=subprocess.PIPE) - - sidechain2start = sidechain_bin_path+"/elementsd -datadir="+sidechain2_datadir + sidechain_args - subprocess.Popen(sidechain2start.split(), stdout=subprocess.PIPE) - - print("Daemons started") - time.sleep(3) - - with open(bitcoin2_rpccookiefile, 'r') as f: - bitcoin2_rpccookie = f.readline() - - bitcoin = AuthServiceProxy("http://bitcoinrpc:"+bitcoin_pass+"@127.0.0.1:"+str(bitcoin_port)) - bitcoin2 = AuthServiceProxy("http://"+ bitcoin2_rpccookie +"@127.0.0.1:"+str(bitcoin2_port)) - sidechain = AuthServiceProxy("http://sidechainrpc:"+sidechain_pass+"@127.0.0.1:"+str(sidechain_port)) - sidechain2 = AuthServiceProxy("http://sidechainrpc2:"+sidechain2_pass+"@127.0.0.1:"+str(sidechain2_port)) - print("Daemons started, making blocks to get funds") - - bitcoin.generate(101) - sidechain.generate(101) - - addr = bitcoin.getnewaddress() - - # First, blackhole all 21M bitcoin that already exist(and test subtractfrom) - assert(sidechain.getwalletinfo()["balance"]["bitcoin"] == 21000000) - sidechain.sendtomainchain(addr, 21000000, True) - assert("bitcoin" not in sidechain.getwalletinfo()["balance"]) - - sidechain.generate(101) - - getpeginaddr_res = sidechain.getpeginaddress() - addr = getpeginaddr_res["mainchain_address"] - claim_script = getpeginaddr_res["claim_script"] - assert(addr == sidechain.tweakfedpegscript(claim_script)["address"]) - txid1 = bitcoin.sendtoaddress(addr, 24) - - bitcoin.generate(1) - time.sleep(2) - proof = bitcoin.gettxoutproof([txid1]) - raw = bitcoin.getrawtransaction(txid1) - - print("Attempting peg-in") - # First attempt fails the consensus check but gives useful result - try: - pegtxid = sidechain.claimpegin(raw, proof) - raise Exception("Peg-in should not be mature enough yet, need another block.") - except JSONRPCException as e: - assert("Peg-in Bitcoin transaction needs more confirmations to be sent." in e.error["message"]) - pass - - # Second attempt simply doesn't hit mempool bar - bitcoin.generate(10) - try: - pegtxid = sidechain.claimpegin(raw, proof) - raise Exception("Peg-in should not be mature enough yet, need another block.") - except JSONRPCException as e: - assert("Peg-in Bitcoin transaction needs more confirmations to be sent." in e.error["message"]) - pass - - # Should fail due to non-matching wallet address - try: - pegtxid = sidechain.claimpegin(raw, proof, sidechain.getnewaddress()) - raise Exception("Peg-in with non-matching claim_script should fail.") - except JSONRPCException as e: - assert("Given claim_script does not match the given Bitcoin transaction." in e.error["message"]) - pass - - # 12 confirms allows in mempool - bitcoin.generate(1) - # Should succeed via wallet lookup for address match, and when given - pegtxid1 = sidechain.claimpegin(raw, proof) - - # Will invalidate the block that confirms this transaction later - sync_all(bitcoin, bitcoin2) - blockhash = sync_all(sidechain, sidechain2) - sidechain.generate(5) - - tx1 = sidechain.gettransaction(pegtxid1) - - if "confirmations" in tx1 and tx1["confirmations"] == 6: - print("Peg-in is confirmed: Success!") - else: - raise Exception("Peg-in confirmation has failed.") - - # Look at pegin fields - decoded = sidechain.decoderawtransaction(tx1["hex"]) - assert decoded["vin"][0]["is_pegin"] == True - assert len(decoded["vin"][0]["pegin_witness"]) > 0 - # Check that there's sufficient fee for the peg-in - vsize = decoded["vsize"] - fee_output = decoded["vout"][1] - fallbackfee_pervbyte = Decimal("0.00001")/Decimal("1000") - assert fee_output["scriptPubKey"]["type"] == "fee" - assert fee_output["value"] >= fallbackfee_pervbyte*vsize - - # Quick reorg checks of pegs - sidechain.invalidateblock(blockhash[0]) - if sidechain.gettransaction(pegtxid1)["confirmations"] != 0: - raise Exception("Peg-in didn't unconfirm after invalidateblock call.") - # Re-enters block - sidechain.generate(1) - if sidechain.gettransaction(pegtxid1)["confirmations"] != 1: - raise Exception("Peg-in should have one confirm on side block.") - sidechain.reconsiderblock(blockhash[0]) - if sidechain.gettransaction(pegtxid1)["confirmations"] != 6: - raise Exception("Peg-in should be back to 6 confirms.") - - # Do many claims in mempool - n_claims = 5 - - print("Flooding mempool with many small claims") - pegtxs = [] - sidechain.generate(101) - - for i in range(n_claims): - addrs = sidechain.getpeginaddress() - txid = bitcoin.sendtoaddress(addrs["mainchain_address"], 1) - bitcoin.generate(12) - proof = bitcoin.gettxoutproof([txid]) - raw = bitcoin.getrawtransaction(txid) - pegtxs += [sidechain.claimpegin(raw, proof)] - - sync_all(bitcoin, bitcoin2) - sync_all(sidechain, sidechain2) - - sidechain2.generate(1) - for pegtxid in pegtxs: - tx = sidechain.gettransaction(pegtxid) - if "confirmations" not in tx or tx["confirmations"] == 0: - raise Exception("Peg-in confirmation has failed.") - - print("Test pegout") - test_pegout(bitcoin.getnewaddress(), sidechain) - - print("Test pegout P2SH") - parent_chain_addr = bitcoin.getnewaddress() - parent_pubkey = bitcoin.validateaddress(parent_chain_addr)["pubkey"] - parent_chain_p2sh_addr = bitcoin.createmultisig(1, [parent_pubkey])["address"] - test_pegout(parent_chain_p2sh_addr, sidechain) - - print("Test pegout Garbage") - parent_chain_addr = "garbage" - try: - test_pegout(parent_chain_addr, sidechain) - raise Exception("A garbage address should fail.") - except JSONRPCException as e: - assert("Invalid Bitcoin address" in e.error["message"]) - pass - - print("Test pegout Garbage valid") - prev_txid = sidechain.sendtoaddress(sidechain.getnewaddress(), 1) - sidechain.generate(1) - pegout_chain = 'a' * 64 - pegout_hex = 'b' * 500 - inputs = [{"txid": prev_txid, "vout": 0}] - outputs = {"vdata": [pegout_chain, pegout_hex]} - rawtx = sidechain.createrawtransaction(inputs, outputs) - raw_pegout = sidechain.decoderawtransaction(rawtx) - - assert 'vout' in raw_pegout and len(raw_pegout['vout']) > 0 - pegout_tested = False - for output in raw_pegout['vout']: - scriptPubKey = output['scriptPubKey'] - if 'type' in scriptPubKey and scriptPubKey['type'] == 'nulldata': - assert ('pegout_hex' in scriptPubKey and 'pegout_asm' in scriptPubKey and 'pegout_type' in scriptPubKey and - 'pegout_chain' in scriptPubKey and 'pegout_reqSigs' not in scriptPubKey and 'pegout_addresses' not in scriptPubKey) - assert scriptPubKey['pegout_type'] == 'nonstandard' - assert scriptPubKey['pegout_chain'] == pegout_chain - assert scriptPubKey['pegout_hex'] == pegout_hex - pegout_tested = True - break - assert pegout_tested - - print ("Now test failure to validate peg-ins based on intermittant bitcoind rpc failure") - bitcoin2.stop() - # give bitcoin2 time to stop - time.sleep(1) - txid = bitcoin.sendtoaddress(addrs["mainchain_address"], 1) - bitcoin.generate(12) - proof = bitcoin.gettxoutproof([txid]) - raw = bitcoin.getrawtransaction(txid) - stuck_peg = sidechain.claimpegin(raw, proof) - sidechain.generate(1) - print("Waiting to ensure block is being rejected by sidechain2") - time.sleep(5) - - assert(sidechain.getblockcount() != sidechain2.getblockcount()) - - bitcoind2start = bitcoin_bin_path+"/bitcoind -datadir="+bitcoin2_datadir - subprocess.Popen(bitcoind2start.split(), stdout=subprocess.PIPE) - print("Restarting bitcoind2") - time.sleep(5) - with open(bitcoin2_rpccookiefile, 'r') as f: - bitcoin2_rpccookie = f.readline() - bitcoin2 = AuthServiceProxy("http://"+ bitcoin2_rpccookie +"@127.0.0.1:"+str(bitcoin2_port)) - - # Don't make a block, race condition when pegin-invalid block - # is awaiting further validation, nodes reject subsequent blocks - # even ones they create - sync_all(sidechain, sidechain2, False) - print("Now send funds out in two stages, partial, and full") - some_btc_addr = bitcoin.getnewaddress() - bal_1 = sidechain.getwalletinfo()["balance"]["bitcoin"] - try: - sidechain.sendtomainchain(some_btc_addr, bal_1 + 1) - raise Exception("Sending out too much; should have failed") - except JSONRPCException as e: - assert("Insufficient funds" in e.error["message"]) - pass - - assert(sidechain.getwalletinfo()["balance"]["bitcoin"] == bal_1) - try: - sidechain.sendtomainchain(some_btc_addr+"b", bal_1 - 1) - raise Exception("Sending to invalid address; should have failed") - except JSONRPCException as e: - assert("Invalid Bitcoin address" in e.error["message"]) - pass - - assert(sidechain.getwalletinfo()["balance"]["bitcoin"] == bal_1) - try: - sidechain.sendtomainchain("1Nro9WkpaKm9axmcfPVp79dAJU1Gx7VmMZ", bal_1 - 1) - raise Exception("Sending to mainchain address when should have been testnet; should have failed") - except JSONRPCException as e: - assert("Invalid Bitcoin address" in e.error["message"]) - pass - - assert(sidechain.getwalletinfo()["balance"]["bitcoin"] == bal_1) - - peg_out_txid = sidechain.sendtomainchain(some_btc_addr, 1) - - peg_out_details = sidechain.decoderawtransaction(sidechain.getrawtransaction(peg_out_txid)) - # peg-out, change - assert(len(peg_out_details["vout"]) == 3) - found_pegout_value = False - for output in peg_out_details["vout"]: - if "value" in output and output["value"] == 1: - found_pegout_value = True - assert(found_pegout_value) - - bal_2 = sidechain.getwalletinfo()["balance"]["bitcoin"] - # Make sure balance went down - assert(bal_2 + 1 < bal_1) - - sidechain.sendtomainchain(some_btc_addr, bal_2, True) - - assert("bitcoin" not in sidechain.getwalletinfo()["balance"]) - - print("Success!") - exit_status = 0 - -except JSONRPCException as e: - print("Pegging testing failed, aborting:") - print(e.error) - exit_status = 1 -except Exception as e: - print("Pegging testing failed, aborting:") - print(e) - exit_status = 1 - -print("Stopping daemons and cleaning up") -if bitcoin is not None: - bitcoin.stop() -if bitcoin2 is not None: - bitcoin2.stop() -if sidechain is not None: - sidechain.stop() -if sidechain2 is not None: - sidechain2.stop() - -time.sleep(5) - -shutil.rmtree(bitcoin2_datadir) -shutil.rmtree(sidechain2_datadir) -shutil.rmtree(sidechain_datadir) -shutil.rmtree(bitcoin_datadir) - -sys.exit(exit_status) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 1fb6666684..82b357742e 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -340,7 +340,8 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= datadir = os.path.join(dirname, "node"+str(i)) if binary is None: binary = os.getenv("ELEMENTSD", "elementsd") - args = [ binary, '-chain='+chain, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-mocktime="+str(get_mocktime()) ] + args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-mocktime="+str(get_mocktime()) ] + args.append('-regtest' if chain == 'regtest' else '-chain=' + chain) if extra_args is not None: args.extend(extra_args) bitcoind_processes[i] = subprocess.Popen(args) if os.getenv("PYTHON_DEBUG", ""): diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1adae5c678..5930bb2e14 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3586,8 +3586,12 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef CScript witnessProgScript; unsigned int nOut = txBTC.vout.size(); if (request.params.size() > 2) { + const std::string claim_script = request.params[2].get_str(); + if (!IsHex(claim_script)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Given claim_script is not hex."); + } // If given manually, no need for it to be a witness script - std::vector witnessBytes(ParseHex(request.params[2].get_str())); + std::vector witnessBytes(ParseHex(claim_script)); witnessProgScript = CScript(witnessBytes.begin(), witnessBytes.end()); nOut = GetPeginTxnOutputIndex(txBTC, witnessProgScript); if (nOut == txBTC.vout.size()) {