Skip to content

Commit

Permalink
Merge #602: refactor getpeginaddress to not call getnewaddress RPC
Browse files Browse the repository at this point in the history
b919ca3 fedpeg test makes sure claim_script is wpkh (Gregory Sanders)
a9cbe55 refactor getpeginaddress to not call getnewaddress RPC (Gregory Sanders)
cdb33e5 createrawpegin should look for wpkh addresses, not nested (Gregory Sanders)

Pull request description:

  resolves #599

Tree-SHA512: 37fbcb865df78337827b44fed00e54fcd5c44eea57bf48d66416be00c915129dcc5f5fda613d9f64fdb325303c24fab4a1e8b1c96fd54ee2dcaac90ba841bfb7
  • Loading branch information
stevenroose committed May 3, 2019
2 parents 8c21d41 + b919ca3 commit 2c56e0d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 37 deletions.
68 changes: 31 additions & 37 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4503,33 +4503,34 @@ UniValue getpeginaddress(const JSONRPCRequest& request)
+ HelpExampleRpc("getpeginaddress", "")
);

//Creates new address for receiving unlocked utxos
JSONRPCRequest req;
CTxDestination address = DecodeDestination(getnewaddress(req).get_str());
if (!pwallet->IsLocked()) {
pwallet->TopUpKeyPool();
}

Witnessifier w(pwallet);
bool ret = boost::apply_visitor(w, address);
if (!ret) {
throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed");
// Generate a new key that is added to wallet
CPubKey newKey;
if (!pwallet->GetKeyFromPool(newKey)) {
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
}

pwallet->SetAddressBook(w.result, "", "receive");
// Use native witness destination
CTxDestination dest = GetDestinationForKey(newKey, OutputType::BECH32);

CScript destScript = GetScriptForDestination(address);
CScript witProg = GetScriptForWitness(destScript);
pwallet->SetAddressBook(dest, "", "receive");

CScript dest_script = GetScriptForDestination(dest);

// Also add raw scripts to index to recognize later.
pwallet->AddCScript(witProg);
pwallet->AddCScript(destScript);
pwallet->AddCScript(dest_script);

//Call contracthashtool, get deposit address on mainchain.
CTxDestination destAddr(ScriptHash(GetScriptForWitness(calculate_contract(Params().GetConsensus().fedpegScript, witProg))));
// Get P2CH deposit address on mainchain.
CTxDestination mainchain_dest(ScriptHash(GetScriptForWitness(calculate_contract(Params().GetConsensus().fedpegScript, dest_script))));

UniValue fundinginfo(UniValue::VOBJ);
UniValue ret(UniValue::VOBJ);

fundinginfo.pushKV("mainchain_address", EncodeParentDestination(destAddr));
fundinginfo.pushKV("claim_script", HexStr(witProg));
return fundinginfo;
ret.pushKV("mainchain_address", EncodeParentDestination(mainchain_dest));
ret.pushKV("claim_script", HexStr(dest_script));
return ret;
}

//! Derive BIP32 tweak from master xpub to child pubkey.
Expand Down Expand Up @@ -5116,7 +5117,7 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
if (txHashes.size() != 1 || txHashes[0] != txBTC.GetHash())
throw JSONRPCError(RPC_INVALID_PARAMETER, "The txoutproof must contain bitcoinTx and only bitcoinTx");

CScript witnessProgScript;
CScript witness_script;
unsigned int nOut = txBTC.vout.size();
if (request.params.size() > 2) {
const std::string claim_script = request.params[2].get_str();
Expand All @@ -5125,39 +5126,32 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
}
// If given manually, no need for it to be a witness script
std::vector<unsigned char> witnessBytes(ParseHex(claim_script));
witnessProgScript = CScript(witnessBytes.begin(), witnessBytes.end());
nOut = GetPeginTxnOutputIndex(txBTC, witnessProgScript);
witness_script = CScript(witnessBytes.begin(), witnessBytes.end());
nOut = GetPeginTxnOutputIndex(txBTC, witness_script);
if (nOut == txBTC.vout.size()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Given claim_script does not match the given Bitcoin transaction.");
}
}
else {
// Look through address book for pegin contract value by extracting the unlderlying witness program from p2sh-p2wpkh
// Look for known wpkh address in wallet
for (std::map<CTxDestination, CAddressBookData>::const_iterator iter = pwallet->mapAddressBook.begin(); iter != pwallet->mapAddressBook.end(); ++iter) {
CTxDestination sidechainAddress(CTxDestination(iter->first));
CScript witnessProgramScript = GetScriptForWitness(GetScriptForDestination(sidechainAddress));
int version;
std::vector<unsigned char> witnessProgram;
// Only process witness v0 programs
if (!witnessProgramScript.IsWitnessProgram(version, witnessProgram) || version != 0) {
continue;
}
nOut = GetPeginTxnOutputIndex(txBTC, witnessProgramScript);
CScript dest_script = GetScriptForDestination(iter->first);
nOut = GetPeginTxnOutputIndex(txBTC, dest_script);
if (nOut != txBTC.vout.size()) {
witnessProgScript = witnessProgramScript;
witness_script = dest_script;
break;
}
}
}
if (nOut == txBTC.vout.size()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Failed to find output in bitcoinTx to the mainchain_address from getpeginaddress");
}
assert(witnessProgScript != CScript());
assert(witness_script != CScript());

int version = -1;
std::vector<unsigned char> witnessProgram;
if (!witnessProgScript.IsWitnessProgram(version, witnessProgram)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Given or recovered script is not a witness program.");
std::vector<unsigned char> witness_program;
if (!witness_script.IsWitnessProgram(version, witness_program) || version != 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Given or recovered script is not a v0 witness program.");
}

CAmount value = 0;
Expand Down Expand Up @@ -5207,7 +5201,7 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
stack.push_back(value_bytes);
stack.push_back(std::vector<unsigned char>(Params().GetConsensus().pegged_asset.begin(), Params().GetConsensus().pegged_asset.end()));
stack.push_back(std::vector<unsigned char>(genesisBlockHash.begin(), genesisBlockHash.end()));
stack.push_back(std::vector<unsigned char>(witnessProgScript.begin(), witnessProgScript.end()));
stack.push_back(std::vector<unsigned char>(witness_script.begin(), witness_script.end()));
stack.push_back(txData);
stack.push_back(txOutProofData);

Expand Down
1 change: 1 addition & 0 deletions test/functional/feature_fedpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ def run_test(self):

addrs = sidechain.getpeginaddress()
addr = addrs["mainchain_address"]
assert_equal(sidechain.decodescript(addrs["claim_script"])["type"], "witness_v0_keyhash")
txid1 = parent.sendtoaddress(addr, 24)
# 10+2 confirms required to get into mempool and confirm
parent.generate(1)
Expand Down

0 comments on commit 2c56e0d

Please sign in to comment.