Skip to content

Commit e5ab941

Browse files
committed
Merge #813: Fix claimpegin and createrawpegin support for multiwallet.
fc841c8 Fix claimpegin and createrawpegin support for multiwallet. (Glenn Willen) Pull request description: Fixes #812. @stevenroose, take a look when you get back? Fix multiple issues with claimpegin and createrawpegin support for multiple loaded wallets: - Failure to call EnsureWalletIsAvailable would cause a crash when multiple wallets were loaded, but one was not specified in the RPC call. - Failure to propagate the request URL from claimpegin when making an internal call to another RPC would result in failure when multiple wallets were loaded, by failing to specify one for that call. Add a regression test to the feature_fedpeg.py test: at a critical point, create a second wallet on the sidechaind, and set up the RPC client to use the first one, to check that it still works correctly. Tree-SHA512: 38d28319d0bc131f530a03e2477b013a982b28d321383a2316372d9aa94f66b19137ba4c1c7e1fe44e3470fe87e80fabbd435836892925b50134c05613581e10
2 parents da3611a + fc841c8 commit e5ab941

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

src/wallet/rpcwallet.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5554,6 +5554,12 @@ extern UniValue sendrawtransaction(const JSONRPCRequest& request);
55545554
template<typename T_tx_ref, typename T_tx, typename T_merkle_block>
55555555
static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef, T_tx& tx_aux, T_merkle_block& merkleBlock)
55565556
{
5557+
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
5558+
CWallet* const pwallet = wallet.get();
5559+
5560+
if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
5561+
return NullUniValue;
5562+
55575563
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
55585564
throw std::runtime_error(
55595565
RPCHelpMan{"createrawpegin",
@@ -5577,9 +5583,6 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
55775583
},
55785584
}.ToString());
55795585

5580-
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
5581-
CWallet* const pwallet = wallet.get();
5582-
55835586
auto locked_chain = pwallet->chain().lock();
55845587
LOCK(pwallet->cs_wallet);
55855588

@@ -5695,6 +5698,11 @@ UniValue createrawpegin(const JSONRPCRequest& request)
56955698

56965699
UniValue claimpegin(const JSONRPCRequest& request)
56975700
{
5701+
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
5702+
CWallet* const pwallet = wallet.get();
5703+
5704+
if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
5705+
return NullUniValue;
56985706

56995707
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
57005708
throw std::runtime_error(
@@ -5716,8 +5724,6 @@ UniValue claimpegin(const JSONRPCRequest& request)
57165724
},
57175725
}.ToString());
57185726

5719-
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
5720-
CWallet* const pwallet = wallet.get();
57215727
CTransactionRef tx_ref;
57225728
CMutableTransaction mtx;
57235729

@@ -5728,20 +5734,30 @@ UniValue claimpegin(const JSONRPCRequest& request)
57285734
throw JSONRPCError(RPC_WALLET_ERROR, "Peg-ins cannot be completed during initial sync or reindexing.");
57295735
}
57305736

5737+
// NOTE: Making an RPC from within another RPC is not generally a good idea. In particular, it
5738+
// is necessary to copy the URI, which contains the wallet if one was given; otherwise
5739+
// multi-wallet support will silently break. The resulting request object is still missing a
5740+
// bunch of other fields, although they are usually not used by RPC handlers. This is a
5741+
// brittle hack, and further examples of this pattern should not be introduced.
5742+
57315743
// Get raw peg-in transaction
5732-
UniValue ret(createrawpegin(request));
5744+
JSONRPCRequest req;
5745+
req.URI = request.URI;
5746+
req.params = request.params;
5747+
UniValue ret(createrawpegin(req)); // See the note above, on why this is a bad idea.
57335748

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

57395754
// Sign it
5740-
JSONRPCRequest request2;
5755+
JSONRPCRequest req2;
5756+
req2.URI = request.URI;
57415757
UniValue varr(UniValue::VARR);
57425758
varr.push_back(ret["hex"]);
5743-
request2.params = varr;
5744-
UniValue result = signrawtransactionwithwallet(request2);
5759+
req2.params = varr;
5760+
UniValue result = signrawtransactionwithwallet(req2); // See the note above, on why this is a bad idea.
57455761

57465762
if (!DecodeHexTx(mtx, result["hex"].get_str(), false, true)) {
57475763
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");

test/functional/feature_fedpeg.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,14 @@ def run_test(self):
229229

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

232+
# Create a wallet in order to test that multi-wallet support works correctly for claimpegin
233+
# (Regression test for https://github.com/ElementsProject/elements/issues/812 .)
234+
sidechain.createwallet("throwaway")
235+
# Set up our sidechain RPCs to use the first wallet (with empty name). We do this by
236+
# overriding the RPC object in a hacky way, to avoid breaking a different hack on TestNode
237+
# that enables generate() to work despite the deprecation of the generate RPC.
238+
sidechain.rpc = sidechain.get_wallet_rpc("")
239+
232240
print("Attempting peg-ins")
233241
# First attempt fails the consensus check but gives useful result
234242
try:

0 commit comments

Comments
 (0)