mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-16 13:01:19 +02:00
Merge pull request #179 from instagibbs/peginaddrlookup
Use wallet to find compatible pegin sidechain_address by default duri…
This commit is contained in:
commit
593969c18d
2 changed files with 93 additions and 53 deletions
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python2
|
||||
|
||||
from test_framework.authproxy import AuthServiceProxy
|
||||
from test_framework.authproxy import AuthServiceProxy, JSONRPCException
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
|
|
@ -38,6 +38,7 @@ with open(os.path.join(bitcoin_datadir, "bitcoin.conf"), 'w') as f:
|
|||
f.write("testnet=0\n")
|
||||
f.write("txindex=1\n")
|
||||
f.write("daemon=1\n")
|
||||
f.write("listen=0\n")
|
||||
|
||||
with open(os.path.join(sidechain_datadir, "elements.conf"), 'w') as f:
|
||||
f.write("regtest=1\n")
|
||||
|
|
@ -56,49 +57,67 @@ with open(os.path.join(sidechain_datadir, "elements.conf"), 'w') as f:
|
|||
f.write("mainchainrpcpassword="+bitcoin_pass+"\n")
|
||||
f.write("validatepegin=1\n")
|
||||
f.write("validatepegout=0\n")
|
||||
f.write("listen=0\n")
|
||||
|
||||
# Start daemons
|
||||
print("Starting daemons at "+bitcoin_datadir+" and "+sidechain_datadir)
|
||||
bitcoindstart = sys.argv[1]+"/bitcoind -datadir="+bitcoin_datadir
|
||||
subprocess.Popen(bitcoindstart.split(), stdout=subprocess.PIPE)
|
||||
try:
|
||||
|
||||
sidechainstart = sys.argv[2]+"/elementsd -datadir="+sidechain_datadir
|
||||
subprocess.Popen(sidechainstart.split(), stdout=subprocess.PIPE)
|
||||
# Start daemons
|
||||
print("Starting daemons at "+bitcoin_datadir+" and "+sidechain_datadir)
|
||||
bitcoindstart = sys.argv[1]+"/bitcoind -datadir="+bitcoin_datadir
|
||||
subprocess.Popen(bitcoindstart.split(), stdout=subprocess.PIPE)
|
||||
|
||||
print("Daemons started")
|
||||
time.sleep(2)
|
||||
sidechainstart = sys.argv[2]+"/elementsd -datadir="+sidechain_datadir
|
||||
subprocess.Popen(sidechainstart.split(), stdout=subprocess.PIPE)
|
||||
|
||||
bitcoin = AuthServiceProxy("http://bitcoinrpc:"+bitcoin_pass+"@127.0.0.1:"+str(bitcoin_port))
|
||||
sidechain = AuthServiceProxy("http://sidechainrpc:"+sidechain_pass+"@127.0.0.1:"+str(sidechain_port))
|
||||
print("Daemons started, making blocks to get funds")
|
||||
print("Daemons started")
|
||||
time.sleep(2)
|
||||
|
||||
bitcoin.generate(101)
|
||||
sidechain.generate(101)
|
||||
bitcoin = AuthServiceProxy("http://bitcoinrpc:"+bitcoin_pass+"@127.0.0.1:"+str(bitcoin_port))
|
||||
sidechain = AuthServiceProxy("http://sidechainrpc:"+sidechain_pass+"@127.0.0.1:"+str(sidechain_port))
|
||||
print("Daemons started, making blocks to get funds")
|
||||
|
||||
addr = bitcoin.getnewaddress()
|
||||
bitcoin.generate(101)
|
||||
sidechain.generate(101)
|
||||
|
||||
# Lockup some funds to unlock later
|
||||
sidechain.sendtomainchain(addr, 50)
|
||||
sidechain.generate(101)
|
||||
addr = bitcoin.getnewaddress()
|
||||
|
||||
addrs = sidechain.getpeginaddress()
|
||||
txid = bitcoin.sendtoaddress(addrs["mainchain_address"], 49)
|
||||
bitcoin.generate(10)
|
||||
proof = bitcoin.gettxoutproof([txid])
|
||||
raw = bitcoin.getrawtransaction(txid)
|
||||
# Lockup some funds to unlock later
|
||||
sidechain.sendtomainchain(addr, 50)
|
||||
sidechain.generate(101)
|
||||
|
||||
print("Attempting peg-in")
|
||||
pegtxid = sidechain.claimpegin(addrs["sidechain_address"], raw, proof)
|
||||
sidechain.generate(1)
|
||||
addrs = sidechain.getpeginaddress()
|
||||
txid = bitcoin.sendtoaddress(addrs["mainchain_address"], 49)
|
||||
bitcoin.generate(10)
|
||||
proof = bitcoin.gettxoutproof([txid])
|
||||
raw = bitcoin.getrawtransaction(txid)
|
||||
|
||||
tx = sidechain.gettransaction(pegtxid)
|
||||
print("Attempting peg-in")
|
||||
|
||||
if "confirmations" in tx and tx["confirmations"] > 0:
|
||||
print("Peg-in is confirmed: Success!")
|
||||
else:
|
||||
print("Peg-in has failed.")
|
||||
# Should fail due to non-matching address
|
||||
try:
|
||||
pegtxid = sidechain.claimpegin(raw, proof, sidechain.getnewaddress())
|
||||
raise Exception("Peg-in with non-matching address should fail.")
|
||||
except JSONRPCException:
|
||||
pass
|
||||
|
||||
# Should succeed via wallet lookup for address match
|
||||
pegtxid = sidechain.claimpegin(raw, proof)
|
||||
|
||||
sidechain.generate(1)
|
||||
|
||||
tx = sidechain.gettransaction(pegtxid)
|
||||
|
||||
if "confirmations" in tx and tx["confirmations"] > 0:
|
||||
print("Peg-in is confirmed: Success!")
|
||||
else:
|
||||
raise Exception("Peg-in confirmation has failed.")
|
||||
|
||||
except JSONRPCException as e:
|
||||
print("Pegging testing failed, aborting:")
|
||||
print(e.error)
|
||||
except Exception as e:
|
||||
print("Pegging testing failed, aborting:")
|
||||
print(e)
|
||||
|
||||
print("Stopping daemons and cleaning up")
|
||||
bitcoin.stop()
|
||||
|
|
|
|||
|
|
@ -3175,19 +3175,32 @@ UniValue sendtomainchain(const UniValue& params, bool fHelp)
|
|||
|
||||
extern UniValue sendrawtransaction(const UniValue& params, bool fHelp);
|
||||
|
||||
unsigned int GetPeginTxnOutputIndex(const Sidechain::Bitcoin::CTransaction& txn, const CBitcoinAddress& sidechainAddress, unsigned char* fullcontract)
|
||||
{
|
||||
unsigned char nonce[16];
|
||||
memset(nonce, 0, sizeof(nonce));
|
||||
unsigned int nOut = 0;
|
||||
//Call contracthashtool
|
||||
CScript mainchain_script = GetScriptForDestination(calculate_contract(Params().GetConsensus().fedpegScript, sidechainAddress, &nonce[0], fullcontract));
|
||||
for (; nOut < txn.vout.size(); nOut++)
|
||||
if (txn.vout[nOut].scriptPubKey == mainchain_script)
|
||||
break;
|
||||
return nOut;
|
||||
}
|
||||
|
||||
UniValue claimpegin(const UniValue& params, bool fHelp)
|
||||
{
|
||||
|
||||
if (fHelp || params.size() != 3)
|
||||
if (fHelp || params.size() < 2 || params.size() > 3)
|
||||
throw runtime_error(
|
||||
"claimpegin sidechainaddress bitcoinTx txoutproof\n"
|
||||
"claimpegin bitcoinTx txoutproof ( sidechain_address )\n"
|
||||
"\nClaim coins from the main chain by creating a withdraw transaction with the necessary metadata after the corresponding Bitcoin transaction.\n"
|
||||
"Note that the transaction will not be mined or relayed unless it is buried at least 10 blocks deep.\n"
|
||||
"Note that the transaction will not be relayed unless it is buried at least 102 blocks deep.\n"
|
||||
"If a transaction is not relayed it may require manual addition to a functionary mempool in order for it to be mined.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"sidechain_address\" (string, required) The sidechain_address address generated by getpeginaddress\n"
|
||||
"2. \"bitcoinTx\" (string, required) The raw bitcoin transaction (in hex) depositing bitcoin to the mainchain_address generated by getpeginaddress\n"
|
||||
"3. \"txoutproof\" (string, required) A rawtxoutproof (in hex) generated by bitcoind's `gettxoutproof` containing a proof of only bitcoinTx\n"
|
||||
"1. \"bitcoinTx\" (string, required) The raw bitcoin transaction (in hex) depositing bitcoin to the mainchain_address generated by getpeginaddress\n"
|
||||
"2. \"txoutproof\" (string, required) A rawtxoutproof (in hex) generated by bitcoind's `gettxoutproof` containing a proof of only bitcoinTx\n"
|
||||
"3. \"sidechain_address\" (string, optional) The sidechain_address generated by getpeginaddress. Only needed if not in wallet.\n"
|
||||
"\nResult:\n"
|
||||
"\"txid\" (string) Txid of the resulting sidechain transaction\n"
|
||||
"\nExamples:\n"
|
||||
|
|
@ -3200,14 +3213,12 @@ UniValue claimpegin(const UniValue& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_WALLET_ERROR, "Peg-ins cannot be completed during initial sync or reindexing.");
|
||||
}
|
||||
|
||||
CBitcoinAddress sidechainAddress(params[0].get_str());
|
||||
if (!sidechainAddress.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid sidechain_address");
|
||||
if (!IsHex(params[0].get_str()) || !IsHex(params[1].get_str())) {
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "the first two arguments must be hex strings");
|
||||
}
|
||||
|
||||
if (!IsHex(params[1].get_str()) || !IsHex(params[2].get_str()))
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "the last two arguments must be hex strings");
|
||||
|
||||
std::vector<unsigned char> txData = ParseHex(params[1].get_str());
|
||||
std::vector<unsigned char> txData = ParseHex(params[0].get_str());
|
||||
CDataStream ssTx(txData, SER_NETWORK, PROTOCOL_VERSION);
|
||||
Sidechain::Bitcoin::CTransaction txBTC;
|
||||
try {
|
||||
|
|
@ -3217,7 +3228,7 @@ UniValue claimpegin(const UniValue& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_TYPE_ERROR, "The included bitcoinTx is malformed. Are you sure that is the whole string?");
|
||||
}
|
||||
|
||||
std::vector<unsigned char> txOutProofData = ParseHex(params[2].get_str());
|
||||
std::vector<unsigned char> txOutProofData = ParseHex(params[1].get_str());
|
||||
CDataStream ssTxOutProof(txOutProofData, SER_NETWORK, PROTOCOL_VERSION);
|
||||
Sidechain::Bitcoin::CMerkleBlock merkleBlock;
|
||||
try {
|
||||
|
|
@ -3237,16 +3248,26 @@ UniValue claimpegin(const UniValue& params, bool fHelp)
|
|||
if (txHashes.size() != 1 || txHashes[0] != txBTC.GetHash())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "The txoutproof must contain bitcoinTx and only bitcoinTx");
|
||||
|
||||
//Call contracthashtool
|
||||
unsigned char nonce[16];
|
||||
memset(nonce, 0, sizeof(nonce));
|
||||
unsigned char fullcontract[40];
|
||||
CScript mainchain_script = GetScriptForDestination(calculate_contract(Params().GetConsensus().fedpegScript, sidechainAddress, &nonce[0], fullcontract));
|
||||
|
||||
unsigned int nOut = 0;
|
||||
for (; nOut < txBTC.vout.size(); nOut++)
|
||||
if (txBTC.vout[nOut].scriptPubKey == mainchain_script)
|
||||
break;
|
||||
unsigned char fullcontract[40];
|
||||
CBitcoinAddress sidechainAddress;
|
||||
if (params.size() > 2) {
|
||||
sidechainAddress = CBitcoinAddress(params[2].get_str());
|
||||
if (!sidechainAddress.IsValid()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Given sidechain_address is invalid.");
|
||||
}
|
||||
nOut = GetPeginTxnOutputIndex(txBTC, sidechainAddress, fullcontract);
|
||||
}
|
||||
else {
|
||||
// Look through address book for pegin contract value
|
||||
for (std::map<CTxDestination, CAddressBookData>::const_iterator iter = pwalletMain->mapAddressBook.begin(); iter != pwalletMain->mapAddressBook.end(); ++iter) {
|
||||
sidechainAddress = CBitcoinAddress(iter->first);
|
||||
nOut = GetPeginTxnOutputIndex(txBTC, sidechainAddress, fullcontract);
|
||||
if (nOut != txBTC.vout.size()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nOut == txBTC.vout.size())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Failed to find output in bitcoinTx to the mainchain_address from getpeginaddress");
|
||||
CAmount value = txBTC.vout[nOut].nValue;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue