Skip to content

Commit 59def74

Browse files
committed
Merge #588: CreateTransaction: Place blinding pubkey into nNonce in case of fundraw
7fd6b88 claimpegins should arrive in witness destinations (Gregory Sanders) a4a051e Add tests for fundrawtransaction placing back blinding keys properly (Gregory Sanders) 48958a6 CreateTransaction: Place blinding pubkey into nNonce in case of fundraw (Gregory Sanders) 2e6191d QA: Hack around no issuance an non-witness tx bug issue#473 (Gregory Sanders) Pull request description: Currently any fundrawtransaction call will result in unblinded change output. Automated flow isn't effected by this bug. Tree-SHA512: ee09a58bd8d5ac35f8d090a0e8928efebb7f9d8e886105bff7188ad4983406d53e4693b46b1e4f70ba76d3e06a420bd778b4c879de183d02d7ec3c7ccbac3f8e
2 parents 346c544 + 7fd6b88 commit 59def74

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

src/wallet/rpcwallet.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -5189,16 +5189,16 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
51895189
CPubKey newKey;
51905190
if (!pwallet->GetKeyFromPool(newKey))
51915191
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
5192-
PKHash pkhash(newKey);
5192+
WitnessV0KeyHash wpkhash(newKey.GetID());
51935193

5194-
pwallet->SetAddressBook(pkhash, "", "receive");
5194+
pwallet->SetAddressBook(wpkhash, "", "receive");
51955195

51965196
// One peg-in input, one wallet output and one fee output
51975197
CMutableTransaction mtx;
51985198
mtx.vin.push_back(CTxIn(COutPoint(txHashes[0], nOut), CScript(), ~(uint32_t)0));
51995199
// mark as peg-in input
52005200
mtx.vin[0].m_is_pegin = true;
5201-
mtx.vout.push_back(CTxOut(Params().GetConsensus().pegged_asset, value, GetScriptForDestination(pkhash)));
5201+
mtx.vout.push_back(CTxOut(Params().GetConsensus().pegged_asset, value, GetScriptForDestination(wpkhash)));
52025202
mtx.vout.push_back(CTxOut(Params().GetConsensus().pegged_asset, 0, CScript()));
52035203

52045204
// Construct pegin proof

src/wallet/wallet.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -3166,15 +3166,17 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
31663166
}
31673167

31683168
std::vector<CTxOut>::iterator position = txNew.vout.begin()+vChangePosInOut[assetChange.first];
3169-
txNew.vout.insert(position, newTxOut);
3170-
CPubKey blind_pub = GetBlindingPubKey(itScript->second.second);
31713169
if (blind_details) {
3170+
CPubKey blind_pub = GetBlindingPubKey(itScript->second.second);
31723171
blind_details->o_pubkeys.insert(blind_details->o_pubkeys.begin() + vChangePosInOut[assetChange.first], blind_pub);
31733172
assert(blind_pub.IsFullyValid());
31743173
blind_details->num_to_blind++;
31753174
blind_details->change_to_blind++;
31763175
blind_details->only_change_pos = vChangePosInOut[assetChange.first];
3176+
// Place the blinding pubkey here in case of fundraw calls
3177+
newTxOut.nNonce.vchCommitment = std::vector<unsigned char>(blind_pub.begin(), blind_pub.end());
31773178
}
3179+
txNew.vout.insert(position, newTxOut);
31783180
}
31793181
}
31803182
// Set the correct nChangePosInOut for output. Should be policyAsset's position.

test/functional/feature_confidential_transactions.py

+26-1
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,29 @@ def run_test(self):
281281
signed = self.nodes[0].signrawtransactionwithwallet(blinded2)
282282
self.nodes[0].sendrawtransaction(signed["hex"])
283283

284+
# Aside: Check all outputs after fundraw are properly marked for blinding
285+
fund_decode = self.nodes[0].decoderawtransaction(funded["hex"])
286+
for output in fund_decode["vout"][:-1]:
287+
assert "asset" in output
288+
assert "value" in output
289+
assert output["scriptPubKey"]["type"] != "fee"
290+
assert output["commitmentnonce_fully_valid"]
291+
assert fund_decode["vout"][-1]["scriptPubKey"]["type"] == "fee"
292+
assert not fund_decode["vout"][-1]["commitmentnonce_fully_valid"]
293+
294+
# Also check that all fundraw outputs marked for blinding are blinded later
295+
for blind_tx in [blinded, blinded2]:
296+
blind_decode = self.nodes[0].decoderawtransaction(blind_tx)
297+
for output in blind_decode["vout"][:-1]:
298+
assert "asset" not in output
299+
assert "value" not in output
300+
assert output["scriptPubKey"]["type"] != "fee"
301+
assert output["commitmentnonce_fully_valid"]
302+
assert blind_decode["vout"][-1]["scriptPubKey"]["type"] == "fee"
303+
assert "asset" in blind_decode["vout"][-1]
304+
assert "value" in blind_decode["vout"][-1]
305+
assert not blind_decode["vout"][-1]["commitmentnonce_fully_valid"]
306+
284307
# Check createblindedaddress functionality
285308
blinded_addr = self.nodes[0].getnewaddress()
286309
validated_addr = self.nodes[0].validateaddress(blinded_addr)
@@ -379,6 +402,9 @@ def run_test(self):
379402
self.sync_all()
380403

381404
# Check for value accounting when asset issuance is null but token not, ie unblinded
405+
# HACK: Self-send to sweep up bitcoin inputs into blinded output.
406+
# We were hitting https://github.com/ElementsProject/elements/issues/473 for the following issuance
407+
self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[0].getwalletinfo()["balance"]["bitcoin"], "", "", True)
382408
issued = self.nodes[0].issueasset(0, 1, False)
383409
walletinfo = self.nodes[0].getwalletinfo()
384410
assert(issued["asset"] not in walletinfo["balance"])
@@ -559,7 +585,6 @@ def run_test(self):
559585
self.nodes[0].sendtoaddress(blinded_addr, 1)
560586
self.nodes[0].sendtoaddress(blinded_addr, 3)
561587
unspent = self.nodes[0].listunspent(0, 0)
562-
assert_equal(len(unspent), 4)
563588
rawtx = self.nodes[0].createrawtransaction([{"txid":unspent[0]["txid"], "vout":unspent[0]["vout"]}, {"txid":unspent[1]["txid"], "vout":unspent[1]["vout"]}], {addr:unspent[0]["amount"]+unspent[1]["amount"]-Decimal("0.2"), "fee":Decimal("0.2")})
564589
# Blinding will fail with 2 blinded inputs and 0 blinded outputs
565590
# since it has no notion of a wallet to fill in a 0-value OP_RETURN output

0 commit comments

Comments
 (0)