Skip to content

Commit 49d3c1c

Browse files
committed
Merge #836: Backports + version bump for v0.18.1.6
17f8e74 Bump version to 0.18.1.6 (Steven Roose) 8de91ec Reduce mintxfee to 0.1 sat/vbyte and fallback fee to 2 sat/vb (Steven Roose) 356f25b Some readability improvements in blind.cpp (Steven Roose) a72d9c6 Switch default bits of hiding to 52 (Gregory Sanders) 32792e3 initpegoutwallet: check for hardened derivation steps early (Gregory Sanders) ed88521 Create witness outputs for (re)issueasset RPC (Gregory Sanders) 214789b Place the mainchain RPC warmup message in a better place (Steven Roose) 34784a6 Fix claimpegin and createrawpegin support for multiwallet. (Glenn Willen) Pull request description: v0.18.1.6 changelog: - Reduce mintxfee to 0.1 sat/vbyte and fallback fee to 2 sat/vb - Switch default bits of hiding to 52 - check for hardened derivation steps early in initpegoutwallet - Create witness outputs for (re)issueasset RPC - Fix claimpegin and createrawpegin support for multiwallet - Place the mainchain RPC warmup message in a better place Backported commits: ``` commit bfb77ad (origin/pr/835, mine/mintxfee, mintxfee) Author: Steven Roose <[email protected]> Date: Tue Mar 17 12:47:03 2020 +0000 Reduce mintxfee to 0.1 sat/vbyte and fallback fee to 2 sat/vb commit 26e5490 Author: Gregory Sanders <[email protected]> Date: Tue Dec 3 16:14:13 2019 -0500 Switch default bits of hiding to 52 commit a7b41e1 (upstream/pr/829, origin/pr/829, instagibbs/check_hardened) Author: Gregory Sanders <[email protected]> Date: Tue Mar 3 09:52:57 2020 -0500 initpegoutwallet: check for hardened derivation steps early commit 91583b6 (upstream/pr/825, origin/pr/825, instagibbs/witness_issue) Author: Gregory Sanders <[email protected]> Date: Mon Feb 24 09:32:21 2020 -0500 Create witness outputs for (re)issueasset RPC commit c5cb714 (upstream/pr/818, origin/pr/818, mine/msg-warmup, msg-warmup) Author: Steven Roose <[email protected]> Date: Tue Feb 18 15:15:52 2020 +0000 Place the mainchain RPC warmup message in a better place commit fc841c8 (upstream/pr/813, origin/pr/813) Author: Glenn Willen <[email protected]> Date: Thu Feb 6 23:08:56 2020 -0800 Fix claimpegin and createrawpegin support for multiwallet. ``` Tree-SHA512: 8ad9f22a26e7ea174f8a001651c2f36b5799578d18187231fb170b000c5d6489cd20f2aea776506e6e604a7d6c981a6b32edd532629ec21851ff5f9e7f95a0ed
2 parents 4683c94 + 17f8e74 commit 49d3c1c

11 files changed

+71
-39
lines changed

configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ AC_PREREQ([2.60])
33
define(_CLIENT_VERSION_MAJOR, 0)
44
define(_CLIENT_VERSION_MINOR, 18)
55
define(_CLIENT_VERSION_REVISION, 1)
6-
define(_CLIENT_VERSION_BUILD, 5)
6+
define(_CLIENT_VERSION_BUILD, 6)
77
define(_CLIENT_VERSION_RC, 0)
88
define(_CLIENT_VERSION_IS_RELEASE, true)
99
define(_COPYRIGHT_YEAR, 2019)

src/blind.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,11 @@ bool GenerateRangeproof(std::vector<unsigned char>& rangeproof, const std::vecto
180180
memcpy(asset_message+32, asset_blindptrs[asset_blindptrs.size()-1], 32);
181181

182182
// Sign rangeproof
183+
int ct_exponent = std::min(std::max((int)gArgs.GetArg("-ct_exponent", 0), -1), 18);
184+
int ct_bits = (int)gArgs.GetArg("-ct_bits", 52);
183185
// If min_value is 0, scriptPubKey must be unspendable
184-
int res = secp256k1_rangeproof_sign(secp256k1_blind_context, rangeproof.data(), &nRangeProofLen, scriptPubKey.IsUnspendable() ? 0 : 1, &value_commit, value_blindptrs.back(), nonce.begin(), std::min(std::max((int)gArgs.GetArg("-ct_exponent", 0), -1),18), std::min(std::max((int)gArgs.GetArg("-ct_bits", 36), 1), 51), amount, asset_message, sizeof(asset_message), scriptPubKey.size() ? &scriptPubKey.front() : NULL, scriptPubKey.size(), &gen);
186+
uint64_t min_value = scriptPubKey.IsUnspendable() ? 0 : 1;
187+
int res = secp256k1_rangeproof_sign(secp256k1_blind_context, rangeproof.data(), &nRangeProofLen, min_value, &value_commit, value_blindptrs.back(), nonce.begin(), ct_exponent, ct_bits, amount, asset_message, sizeof(asset_message), scriptPubKey.size() ? &scriptPubKey.front() : NULL, scriptPubKey.size(), &gen);
185188
rangeproof.resize(nRangeProofLen);
186189
return (res == 1);
187190
}

src/blind.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#include <secp256k1_rangeproof.h>
1515
#include <secp256k1_surjectionproof.h>
1616

17-
//! ELEMENTS: 36-bit rangeproof size
18-
static const size_t DEFAULT_RANGEPROOF_SIZE = 2893;
17+
//! ELEMENTS: 52-bit rangeproof size
18+
static const size_t DEFAULT_RANGEPROOF_SIZE = 4174;
1919

2020
/*
2121
* Unblind a pair of confidential asset and value.

src/init.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ void SetupServerArgs()
591591
gArgs.AddArg("-feeasset=<hex>", strprintf("Asset ID (hex) for mempool/relay fees (default: %s)", defaultChainParams->GetConsensus().pegged_asset.GetHex()), false, OptionsCategory::CHAINPARAMS);
592592
gArgs.AddArg("-subsidyasset=<hex>", strprintf("Asset ID (hex) for the block subsidy (default: %s)", defaultChainParams->GetConsensus().pegged_asset.GetHex()), false, OptionsCategory::CHAINPARAMS);
593593
gArgs.AddArg("-initialreissuancetokens=<n>", "The amount of reissuance tokens created in the genesis block. (default: 0)", false, OptionsCategory::CHAINPARAMS);
594-
gArgs.AddArg("-ct_bits", strprintf("The default number of hiding bits in a rangeproof. Will be exceeded to cover amounts exceeding the maximum hiding value. (default: %d)", 36), false, OptionsCategory::CHAINPARAMS);
594+
gArgs.AddArg("-ct_bits", strprintf("The default number of hiding bits in a rangeproof. Will be exceeded to cover amounts exceeding the maximum hiding value. (default: %d)", 52), false, OptionsCategory::CHAINPARAMS);
595595
gArgs.AddArg("-ct_exponent", strprintf("The hiding exponent. (default: %s)", 0), false, OptionsCategory::CHAINPARAMS);
596596

597597
// Add the hidden options
@@ -1877,7 +1877,6 @@ bool AppInitMain(InitInterfaces& interfaces)
18771877
SetRPCWarmupFinished();
18781878

18791879
// ELEMENTS:
1880-
uiInterface.InitMessage(_("Awaiting mainchain RPC warmup"));
18811880
if (!MainchainRPCCheck(true)) { //Initial check only
18821881
const std::string err_msg = "ERROR: elements is set to verify pegins but cannot get valid response from the mainchain daemon. Please check debug.log for more information.\n\nIf you haven't setup a bitcoind please get the latest stable version from https://bitcoincore.org/en/download/ or if you do not need to validate pegins set in your elements configuration validatepegin=0";
18831882
// We fail immediately if this node has RPC server enabled

src/test/blind_tests.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -265,17 +265,17 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
265265

266266
// Check wallet borromean-based rangeproof results against expected args
267267
size_t proof_size = DEFAULT_RANGEPROOF_SIZE;
268-
BOOST_CHECK(tx4.witness.vtxoutwit[2].vchRangeproof.size() == proof_size);
268+
BOOST_CHECK_EQUAL(tx4.witness.vtxoutwit[2].vchRangeproof.size(), proof_size);
269269
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
270270
int exp = 0;
271271
int mantissa = 0;
272272
uint64_t min_value = 0;
273273
uint64_t max_value = 0;
274274
BOOST_CHECK(secp256k1_rangeproof_info(ctx, &exp, &mantissa, &min_value, &max_value, tx4.witness.vtxoutwit[2].vchRangeproof.data(), proof_size) == 1);
275-
BOOST_CHECK(exp == 0);
276-
BOOST_CHECK(mantissa == 36); // 36 bit default
277-
BOOST_CHECK(min_value == 1);
278-
BOOST_CHECK(max_value == 68719476736);
275+
BOOST_CHECK_EQUAL(exp, 0);
276+
BOOST_CHECK_EQUAL(mantissa, 52); // 36 bit default
277+
BOOST_CHECK_EQUAL(min_value, 1);
278+
BOOST_CHECK_EQUAL(max_value, 4503599627370496);
279279
}
280280
{
281281
inputs.clear();

src/validation.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -5288,6 +5288,7 @@ bool MainchainRPCCheck(const bool init)
52885288

52895289
// Next, check for working and valid rpc
52905290
if (gArgs.GetBoolArg("-validatepegin", Params().GetConsensus().has_parent_chain)) {
5291+
uiInterface.InitMessage(_("Awaiting mainchain RPC warmup"));
52915292
// During init try until a non-RPC_IN_WARMUP result
52925293
while (true) {
52935294
try {

src/wallet/rpcwallet.cpp

+42-23
Original file line numberDiff line numberDiff line change
@@ -4984,6 +4984,19 @@ UniValue initpegoutwallet(const JSONRPCRequest& request)
49844984
throw JSONRPCError(RPC_INVALID_PARAMETER, "bitcoin_descriptor must be a ranged descriptor.");
49854985
}
49864986

4987+
// Check if we can actually generate addresses(catches hardened derivation steps etc) before
4988+
// writing to cache
4989+
UniValue address_list(UniValue::VARR);
4990+
for (int i = counter; i < counter+3; i++) {
4991+
std::vector<CScript> scripts;
4992+
if (!desc->Expand(i, provider, scripts, provider)) {
4993+
throw JSONRPCError(RPC_WALLET_ERROR, "Could not generate lookahead addresses with descriptor. Are there hardened derivations after the xpub?");
4994+
}
4995+
CTxDestination destination;
4996+
ExtractDestination(scripts[0], destination);
4997+
address_list.push_back(EncodeParentDestination(destination));
4998+
}
4999+
49875000
// For our manual pattern matching, we don't want the checksum part.
49885001
auto checksum_char = bitcoin_desc.find('#');
49895002
if (checksum_char != std::string::npos) {
@@ -5052,16 +5065,6 @@ UniValue initpegoutwallet(const JSONRPCRequest& request)
50525065
assert(len == 33);
50535066
assert(negatedpubkeybytes.size() == 33);
50545067

5055-
UniValue address_list(UniValue::VARR);
5056-
for (int i = counter; i < counter+3; i++) {
5057-
std::vector<CScript> scripts;
5058-
if (!desc->Expand(i, provider, scripts, provider)) {
5059-
throw JSONRPCError(RPC_WALLET_ERROR, "Could not generate lookahead addresses with descriptor. This is a bug.");
5060-
}
5061-
CTxDestination destination;
5062-
ExtractDestination(scripts[0], destination);
5063-
address_list.push_back(EncodeParentDestination(destination));
5064-
}
50655068
UniValue pak(UniValue::VOBJ);
50665069
pak.pushKV("pakentry", "pak=" + HexStr(negatedpubkeybytes) + ":" + HexStr(online_pubkey));
50675070
pak.pushKV("liquid_pak", HexStr(online_pubkey));
@@ -5418,6 +5421,12 @@ unsigned int GetPeginTxnOutputIndex(const T_tx& txn, const CScript& witnessProgr
54185421
template<typename T_tx_ref, typename T_tx, typename T_merkle_block>
54195422
static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef, T_tx& tx_aux, T_merkle_block& merkleBlock)
54205423
{
5424+
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
5425+
CWallet* const pwallet = wallet.get();
5426+
5427+
if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
5428+
return NullUniValue;
5429+
54215430
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
54225431
throw std::runtime_error(
54235432
RPCHelpMan{"createrawpegin",
@@ -5441,9 +5450,6 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef
54415450
},
54425451
}.ToString());
54435452

5444-
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
5445-
CWallet* const pwallet = wallet.get();
5446-
54475453
auto locked_chain = pwallet->chain().lock();
54485454
LOCK(pwallet->cs_wallet);
54495455

@@ -5640,6 +5646,11 @@ UniValue createrawpegin(const JSONRPCRequest& request)
56405646

56415647
UniValue claimpegin(const JSONRPCRequest& request)
56425648
{
5649+
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
5650+
CWallet* const pwallet = wallet.get();
5651+
5652+
if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
5653+
return NullUniValue;
56435654

56445655
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
56455656
throw std::runtime_error(
@@ -5661,8 +5672,6 @@ UniValue claimpegin(const JSONRPCRequest& request)
56615672
},
56625673
}.ToString());
56635674

5664-
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
5665-
CWallet* const pwallet = wallet.get();
56665675
CTransactionRef tx_ref;
56675676
CMutableTransaction mtx;
56685677

@@ -5673,20 +5682,30 @@ UniValue claimpegin(const JSONRPCRequest& request)
56735682
throw JSONRPCError(RPC_WALLET_ERROR, "Peg-ins cannot be completed during initial sync or reindexing.");
56745683
}
56755684

5685+
// NOTE: Making an RPC from within another RPC is not generally a good idea. In particular, it
5686+
// is necessary to copy the URI, which contains the wallet if one was given; otherwise
5687+
// multi-wallet support will silently break. The resulting request object is still missing a
5688+
// bunch of other fields, although they are usually not used by RPC handlers. This is a
5689+
// brittle hack, and further examples of this pattern should not be introduced.
5690+
56765691
// Get raw peg-in transaction
5677-
UniValue ret(createrawpegin(request));
5692+
JSONRPCRequest req;
5693+
req.URI = request.URI;
5694+
req.params = request.params;
5695+
UniValue ret(createrawpegin(req)); // See the note above, on why this is a bad idea.
56785696

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

56845702
// Sign it
5685-
JSONRPCRequest request2;
5703+
JSONRPCRequest req2;
5704+
req2.URI = request.URI;
56865705
UniValue varr(UniValue::VARR);
56875706
varr.push_back(ret["hex"]);
5688-
request2.params = varr;
5689-
UniValue result = signrawtransactionwithwallet(request2);
5707+
req2.params = varr;
5708+
UniValue result = signrawtransactionwithwallet(req2); // See the note above, on why this is a bad idea.
56905709

56915710
if (!DecodeHexTx(mtx, result["hex"].get_str(), false, true)) {
56925711
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
@@ -6168,15 +6187,15 @@ UniValue issueasset(const JSONRPCRequest& request)
61686187
if (!pwallet->GetKeyFromPool(newKey)) {
61696188
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
61706189
}
6171-
asset_dest = PKHash(newKey.GetID());
6190+
asset_dest = WitnessV0KeyHash(newKey.GetID());
61726191
pwallet->SetAddressBook(asset_dest, "", "receive");
61736192
asset_dest_blindpub = pwallet->GetBlindingPubKey(GetScriptForDestination(asset_dest));
61746193
}
61756194
if (nTokens > 0) {
61766195
if (!pwallet->GetKeyFromPool(newKey)) {
61776196
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
61786197
}
6179-
token_dest = PKHash(newKey.GetID());
6198+
token_dest = WitnessV0KeyHash(newKey.GetID());
61806199
pwallet->SetAddressBook(token_dest, "", "receive");
61816200
token_dest_blindpub = pwallet->GetBlindingPubKey(GetScriptForDestination(token_dest));
61826201
}
@@ -6275,7 +6294,7 @@ UniValue reissueasset(const JSONRPCRequest& request)
62756294
if (!pwallet->GetKeyFromPool(newAssetKey)) {
62766295
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
62776296
}
6278-
CTxDestination asset_dest = PKHash(newAssetKey.GetID());
6297+
CTxDestination asset_dest = WitnessV0KeyHash(newAssetKey.GetID());
62796298
pwallet->SetAddressBook(asset_dest, "", "receive");
62806299
CPubKey asset_dest_blindpub = pwallet->GetBlindingPubKey(GetScriptForDestination(asset_dest));
62816300

@@ -6284,7 +6303,7 @@ UniValue reissueasset(const JSONRPCRequest& request)
62846303
if (!pwallet->GetKeyFromPool(newTokenKey)) {
62856304
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
62866305
}
6287-
CTxDestination token_dest = PKHash(newTokenKey.GetID());
6306+
CTxDestination token_dest = WitnessV0KeyHash(newTokenKey.GetID());
62886307
pwallet->SetAddressBook(token_dest, "", "receive");
62896308
CPubKey token_dest_blindpub = pwallet->GetBlindingPubKey(GetScriptForDestination(token_dest));
62906309

src/wallet/wallet.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@ static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
7474
//! -paytxfee default
7575
constexpr CAmount DEFAULT_PAY_TX_FEE = 0;
7676
//! -fallbackfee default
77-
static const CAmount DEFAULT_FALLBACK_FEE = 20000;
77+
static const CAmount DEFAULT_FALLBACK_FEE = 2000;
7878
//! -discardfee default
7979
static const CAmount DEFAULT_DISCARD_FEE = 10000;
8080
//! -mintxfee default
81-
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
81+
static const CAmount DEFAULT_TRANSACTION_MINFEE = 100;
8282
//! minimum recommended increment for BIP 125 replacement txs
8383
static const CAmount WALLET_INCREMENTAL_RELAY_FEE = 5000;
8484
//! Default for -spendzeroconfchange

test/functional/feature_confidential_transactions.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,9 @@ def run_test(self):
361361

362362
# Send some bitcoin and other assets over as well to fund wallet
363363
addr = self.nodes[2].getnewaddress()
364-
self.nodes[0].sendtoaddress(addr, 5)
364+
txid = self.nodes[0].sendtoaddress(addr, 5)
365+
# Make sure we're doing 52 bits of hiding which covers 21M BTC worth
366+
assert_equal(self.nodes[0].getrawtransaction(txid, 1)["vout"][0]["ct-bits"], 52)
365367
self.nodes[0].sendmany("", {addr: 1, self.nodes[2].getnewaddress(): 13}, 0, "", [], False, 1, "UNSET", {addr: test_asset})
366368

367369
self.sync_all()

test/functional/feature_fedpeg.py

+8
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,14 @@ def run_test(self):
225225

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

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

test/functional/feature_issuance.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def process_raw_issuance(node, issuance_list):
1616
raise Exception('Issuance list too long')
1717
# Make enough outputs for any subsequent spend
1818
next_destinations = {}
19-
output_values = (node.getbalance()['bitcoin']-1)/5
19+
output_values = Decimal('%.8f' % ((node.getbalance()['bitcoin']-1)/5))
2020
for i in range(5):
2121
next_destinations[node.getnewaddress()] = output_values
2222

@@ -382,7 +382,7 @@ def run_test(self):
382382
assert_equal(blinded_multisig, self.nodes[0].getaddressinfo(utxo_info["address"])["confidential"])
383383
break
384384
assert(utxo_info is not None)
385-
assert(utxo_info["amountblinder"] is not "0000000000000000000000000000000000000000000000000000000000000000")
385+
assert(utxo_info["amountblinder"] != "0000000000000000000000000000000000000000000000000000000000000000")
386386

387387
# Now make transaction spending that input
388388
raw_tx = self.nodes[0].createrawtransaction([], {issued_address:1}, 0, False, {issued_address:issued_asset["token"]})

0 commit comments

Comments
 (0)