Skip to content

Commit

Permalink
Merge e5ab941 into merged_master (Elements PR #813)
Browse files Browse the repository at this point in the history
  • Loading branch information
apoelstra committed Nov 26, 2020
2 parents f11b83b + e5ab941 commit dd22beb
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
34 changes: 25 additions & 9 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5675,6 +5675,12 @@ extern UniValue sendrawtransaction(const JSONRPCRequest& request);
template<typename T_tx_ref, typename T_tx, typename T_merkle_block>
static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef, T_tx& tx_aux, T_merkle_block& merkleBlock)
{
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();

if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
return NullUniValue;

if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
throw std::runtime_error(
RPCHelpMan{"createrawpegin",
Expand All @@ -5698,9 +5704,6 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
},
}.ToString());

std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();

auto locked_chain = pwallet->chain().lock();
LOCK(pwallet->cs_wallet);

Expand Down Expand Up @@ -5815,6 +5818,11 @@ UniValue createrawpegin(const JSONRPCRequest& request)

UniValue claimpegin(const JSONRPCRequest& request)
{
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();

if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
return NullUniValue;

if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
throw std::runtime_error(
Expand All @@ -5836,8 +5844,6 @@ UniValue claimpegin(const JSONRPCRequest& request)
},
}.ToString());

std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
CTransactionRef tx_ref;
CMutableTransaction mtx;

Expand All @@ -5848,20 +5854,30 @@ UniValue claimpegin(const JSONRPCRequest& request)
throw JSONRPCError(RPC_WALLET_ERROR, "Peg-ins cannot be completed during initial sync or reindexing.");
}

// NOTE: Making an RPC from within another RPC is not generally a good idea. In particular, it
// is necessary to copy the URI, which contains the wallet if one was given; otherwise
// multi-wallet support will silently break. The resulting request object is still missing a
// bunch of other fields, although they are usually not used by RPC handlers. This is a
// brittle hack, and further examples of this pattern should not be introduced.

// Get raw peg-in transaction
UniValue ret(createrawpegin(request));
JSONRPCRequest req;
req.URI = request.URI;
req.params = request.params;
UniValue ret(createrawpegin(req)); // See the note above, on why this is a bad idea.

// Make sure it can be propagated and confirmed
if (!ret["mature"].isNull() && ret["mature"].get_bool() == false) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Peg-in Bitcoin transaction needs more confirmations to be sent.");
}

// Sign it
JSONRPCRequest request2;
JSONRPCRequest req2;
req2.URI = request.URI;
UniValue varr(UniValue::VARR);
varr.push_back(ret["hex"]);
request2.params = varr;
UniValue result = signrawtransactionwithwallet(request2);
req2.params = varr;
UniValue result = signrawtransactionwithwallet(req2); // See the note above, on why this is a bad idea.

if (!DecodeHexTx(mtx, result["hex"].get_str(), false, true)) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
Expand Down
8 changes: 8 additions & 0 deletions test/functional/feature_fedpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ def run_test(self):

raw = parent.gettransaction(txid1)["hex"]

# Create a wallet in order to test that multi-wallet support works correctly for claimpegin
# (Regression test for https://github.com/ElementsProject/elements/issues/812 .)
sidechain.createwallet("throwaway")
# Set up our sidechain RPCs to use the first wallet (with empty name). We do this by
# overriding the RPC object in a hacky way, to avoid breaking a different hack on TestNode
# that enables generate() to work despite the deprecation of the generate RPC.
sidechain.rpc = sidechain.get_wallet_rpc("")

print("Attempting peg-ins")
# First attempt fails the consensus check but gives useful result
try:
Expand Down

0 comments on commit dd22beb

Please sign in to comment.