Skip to content

Commit 9c1d4cc

Browse files
committed
Merge a4d7ac7 into merged_master (Elements PR ElementsProject#1317)
2 parents d1b8d68 + a4d7ac7 commit 9c1d4cc

17 files changed

+653
-24
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ BITCOIN_CORE_H = \
206206
noui.h \
207207
outputtype.h \
208208
pegins.h \
209+
policy/discount.h \
209210
policy/feerate.h \
210211
policy/fees.h \
211212
policy/packages.h \

src/chainparams.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ class CMainParams : public CChainParams {
227227
anyonecanspend_aremine = false;
228228
enforce_pak = false;
229229
multi_data_permitted = false;
230+
accept_discount_ct = false;
231+
create_discount_ct = false;
230232
consensus.has_parent_chain = false;
231233
g_signed_blocks = false;
232234
g_con_elementsmode = false;
@@ -366,6 +368,8 @@ class CTestNetParams : public CChainParams {
366368
anyonecanspend_aremine = false;
367369
enforce_pak = false;
368370
multi_data_permitted = false;
371+
accept_discount_ct = false;
372+
create_discount_ct = false;
369373
consensus.has_parent_chain = false;
370374
g_signed_blocks = false;
371375
g_con_elementsmode = false;
@@ -521,6 +525,8 @@ class SigNetParams : public CChainParams {
521525
anyonecanspend_aremine = false;
522526
enforce_pak = false;
523527
multi_data_permitted = false;
528+
accept_discount_ct = false;
529+
create_discount_ct = false;
524530
consensus.has_parent_chain = false;
525531
g_signed_blocks = false; // lol
526532
g_con_elementsmode = false;
@@ -613,6 +619,8 @@ class CRegTestParams : public CChainParams {
613619
anyonecanspend_aremine = false;
614620
enforce_pak = false;
615621
multi_data_permitted = false;
622+
accept_discount_ct = false;
623+
create_discount_ct = false;
616624
consensus.has_parent_chain = false;
617625
g_signed_blocks = false;
618626
g_con_elementsmode = false;
@@ -889,6 +897,8 @@ class CCustomParams : public CRegTestParams {
889897
const CScript default_script(CScript() << OP_TRUE);
890898
consensus.fedpegScript = StrHexToScriptWithDefault(args.GetArg("-fedpegscript", ""), default_script);
891899
consensus.start_p2wsh_script = args.GetIntArg("-con_start_p2wsh_script", consensus.start_p2wsh_script);
900+
create_discount_ct = args.GetBoolArg("-creatediscountct", false);
901+
accept_discount_ct = args.GetBoolArg("-acceptdiscountct", create_discount_ct);
892902

893903
// Calculate pegged Bitcoin asset
894904
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID);
@@ -1025,7 +1035,7 @@ class CLiquidTestNetParams : public CCustomParams {
10251035
*/
10261036
class CLiquidV1Params : public CChainParams {
10271037
public:
1028-
CLiquidV1Params()
1038+
explicit CLiquidV1Params(const ArgsManager& args)
10291039
{
10301040

10311041
strNetworkID = "liquidv1";
@@ -1119,6 +1129,8 @@ class CLiquidV1Params : public CChainParams {
11191129
enforce_pak = true;
11201130

11211131
multi_data_permitted = true;
1132+
create_discount_ct = args.GetBoolArg("-creatediscountct", false);
1133+
accept_discount_ct = args.GetBoolArg("-acceptdiscountct", false);
11221134

11231135
parentGenesisBlockHash = uint256S("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
11241136
const bool parent_genesis_is_null = parentGenesisBlockHash == uint256();
@@ -1262,7 +1274,7 @@ class CLiquidV1Params : public CChainParams {
12621274
*/
12631275
class CLiquidV1TestParams : public CLiquidV1Params {
12641276
public:
1265-
explicit CLiquidV1TestParams(const ArgsManager& args)
1277+
explicit CLiquidV1TestParams(const ArgsManager& args) : CLiquidV1Params(args)
12661278
{
12671279
// Our goal here is to override ONLY the things from liquidv1 that make no sense for a test chain / which are pointless and burdensome to require people to override manually.
12681280

@@ -1464,6 +1476,8 @@ class CLiquidV1TestParams : public CLiquidV1Params {
14641476
enforce_pak = args.GetBoolArg("-enforce_pak", enforce_pak);
14651477

14661478
multi_data_permitted = args.GetBoolArg("-multi_data_permitted", multi_data_permitted);
1479+
create_discount_ct = args.GetBoolArg("-creatediscountct", create_discount_ct);
1480+
accept_discount_ct = args.GetBoolArg("-acceptdiscountct", accept_discount_ct || create_discount_ct);
14671481

14681482
if (args.IsArgSet("-parentgenesisblockhash")) {
14691483
parentGenesisBlockHash = uint256S(args.GetArg("-parentgenesisblockhash", ""));
@@ -1555,7 +1569,7 @@ std::unique_ptr<const CChainParams> CreateChainParams(const ArgsManager& args, c
15551569
} else if (chain == CBaseChainParams::REGTEST) {
15561570
return std::unique_ptr<CChainParams>(new CRegTestParams(args));
15571571
} else if (chain == CBaseChainParams::LIQUID1) {
1558-
return std::unique_ptr<CChainParams>(new CLiquidV1Params());
1572+
return std::unique_ptr<CChainParams>(new CLiquidV1Params(args));
15591573
} else if (chain == CBaseChainParams::LIQUID1TEST) {
15601574
return std::unique_ptr<CChainParams>(new CLiquidV1TestParams(args));
15611575
} else if (chain == CBaseChainParams::LIQUIDTESTNET) {

src/chainparams.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ class CChainParams
135135
const std::string& ParentBlech32HRP() const { return parent_blech32_hrp; }
136136
bool GetEnforcePak() const { return enforce_pak; }
137137
bool GetMultiDataPermitted() const { return multi_data_permitted; }
138+
bool GetAcceptDiscountCT() const { return accept_discount_ct; }
139+
bool GetCreateDiscountCT() const { return create_discount_ct; }
138140

139141
protected:
140142
CChainParams() {}
@@ -167,6 +169,8 @@ class CChainParams
167169
std::string parent_blech32_hrp;
168170
bool enforce_pak;
169171
bool multi_data_permitted;
172+
bool accept_discount_ct;
173+
bool create_discount_ct;
170174
};
171175

172176
/**

src/core_write.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <consensus/validation.h>
1010
#include <issuance.h>
1111
#include <key_io.h>
12+
#include <policy/discount.h> // ELEMENTS
1213
#include <script/descriptor.h>
1314
#include <script/script.h>
1415
#include <script/sign.h>
@@ -238,6 +239,10 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
238239
entry.pushKV("version", static_cast<int64_t>(static_cast<uint32_t>(tx.nVersion)));
239240
entry.pushKV("size", (int)::GetSerializeSize(tx, PROTOCOL_VERSION));
240241
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
242+
// ELEMENTS: add discountvsize
243+
if (Params().GetAcceptDiscountCT()) {
244+
entry.pushKV("discountvsize", GetDiscountVirtualTransactionSize(tx));
245+
}
241246
entry.pushKV("weight", GetTransactionWeight(tx));
242247
entry.pushKV("locktime", (int64_t)tx.nLockTime);
243248

src/init.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,8 @@ void SetupServerArgs(ArgsManager& argsman)
640640
argsman.AddArg("-initialreissuancetokens=<n>", "The amount of reissuance tokens created in the genesis block. (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
641641
argsman.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), ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
642642
argsman.AddArg("-ct_exponent", strprintf("The hiding exponent. (default: %s)", 0), ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
643+
argsman.AddArg("-acceptdiscountct", "Accept discounted fees for Confidential Transactions (default: true for liquidv1, false for other chains)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
644+
argsman.AddArg("-creatediscountct", "Create Confidential Transactions with discounted fees (default: false). Setting this to true will also set 'acceptdiscountct' to true.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
643645

644646
#if defined(USE_SYSCALL_SANDBOX)
645647
argsman.AddArg("-sandbox=<mode>", "Use the experimental syscall sandbox in the specified mode (-sandbox=log-and-abort or -sandbox=abort). Allow only expected syscalls to be used by bitcoind. Note that this is an experimental new feature that may cause bitcoind to exit or crash unexpectedly: use with caution. In the \"log-and-abort\" mode the invocation of an unexpected syscall results in a debug handler being invoked which will log the incident and terminate the program (without executing the unexpected syscall). In the \"abort\" mode the invocation of an unexpected syscall results in the entire process being killed immediately by the kernel without executing the unexpected syscall.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);

src/net_processing.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5012,7 +5012,9 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
50125012
auto txid = txinfo.tx->GetHash();
50135013
auto wtxid = txinfo.tx->GetWitnessHash();
50145014
// Peer told you to not send transactions at that feerate? Don't bother sending it.
5015-
if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
5015+
// ELEMENTS: use the discounted vsize here so that discounted CTs are relayed.
5016+
// discountvsize only differs from vsize if accept_discount_ct is true.
5017+
if (txinfo.fee < filterrate.GetFee(txinfo.discountvsize)) {
50165018
continue;
50175019
}
50185020
if (peer->m_tx_relay->m_bloom_filter && !peer->m_tx_relay->m_bloom_filter->IsRelevantAndUpdate(*txinfo.tx)) continue;

src/node/miner.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ int BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& already
304304
if (mit == mapModifiedTx.end()) {
305305
CTxMemPoolModifiedEntry modEntry(desc);
306306
modEntry.nSizeWithAncestors -= it->GetTxSize();
307+
modEntry.discountSizeWithAncestors -= it->GetDiscountTxSize();
307308
modEntry.nModFeesWithAncestors -= it->GetModifiedFee();
308309
modEntry.nSigOpCostWithAncestors -= it->GetSigOpCost();
309310
mapModifiedTx.insert(modEntry);
@@ -367,7 +368,8 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
367368
// and modifying them for their already included ancestors
368369
UpdatePackagesForAdded(inBlock, mapModifiedTx);
369370

370-
CTxMemPool::indexed_transaction_set::index<ancestor_score>::type::iterator mi = m_mempool.mapTx.get<ancestor_score>().begin();
371+
// ELEMENTS: we use confidential_score instead of ancestor_score
372+
CTxMemPool::indexed_transaction_set::index<confidential_score>::type::iterator mi = m_mempool.mapTx.get<confidential_score>().begin();
371373
CTxMemPool::txiter iter;
372374

373375
// Limit the number of attempts to add transactions to the block when it is
@@ -376,9 +378,9 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
376378
const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
377379
int64_t nConsecutiveFailed = 0;
378380

379-
while (mi != m_mempool.mapTx.get<ancestor_score>().end() || !mapModifiedTx.empty()) {
381+
while (mi != m_mempool.mapTx.get<confidential_score>().end() || !mapModifiedTx.empty()) {
380382
// First try to find a new transaction in mapTx to evaluate.
381-
if (mi != m_mempool.mapTx.get<ancestor_score>().end() &&
383+
if (mi != m_mempool.mapTx.get<confidential_score>().end() &&
382384
SkipMapTxEntry(m_mempool.mapTx.project<0>(mi), mapModifiedTx, failedTx)) {
383385
++mi;
384386
continue;
@@ -388,16 +390,16 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
388390
// the next entry from mapTx, or the best from mapModifiedTx?
389391
bool fUsingModified = false;
390392

391-
modtxscoreiter modit = mapModifiedTx.get<ancestor_score>().begin();
392-
if (mi == m_mempool.mapTx.get<ancestor_score>().end()) {
393+
modconftxscoreiter modit = mapModifiedTx.get<confidential_score>().begin();
394+
if (mi == m_mempool.mapTx.get<confidential_score>().end()) {
393395
// We're out of entries in mapTx; use the entry from mapModifiedTx
394396
iter = modit->iter;
395397
fUsingModified = true;
396398
} else {
397399
// Try to compare the mapTx entry to the mapModifiedTx entry
398400
iter = m_mempool.mapTx.project<0>(mi);
399-
if (modit != mapModifiedTx.get<ancestor_score>().end() &&
400-
CompareTxMemPoolEntryByAncestorFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
401+
if (modit != mapModifiedTx.get<confidential_score>().end() &&
402+
CompareTxMemPoolEntryByConfidentialFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
401403
// The best entry in mapModifiedTx has higher score
402404
// than the one from mapTx.
403405
// Switch which transaction (package) to consider
@@ -439,7 +441,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
439441
// Since we always look at the best entry in mapModifiedTx,
440442
// we must erase failed entries so that we can consider the
441443
// next best entry on the next loop iteration
442-
mapModifiedTx.get<ancestor_score>().erase(modit);
444+
mapModifiedTx.get<confidential_score>().erase(modit);
443445
failedTx.insert(iter);
444446
}
445447

@@ -464,7 +466,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
464466
// Test if all tx's are Final
465467
if (!TestPackageTransactions(ancestors)) {
466468
if (fUsingModified) {
467-
mapModifiedTx.get<ancestor_score>().erase(modit);
469+
mapModifiedTx.get<confidential_score>().erase(modit);
468470
failedTx.insert(iter);
469471
}
470472
continue;

src/node/miner.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,22 @@ struct CTxMemPoolModifiedEntry {
4141
{
4242
iter = entry;
4343
nSizeWithAncestors = entry->GetSizeWithAncestors();
44+
discountSizeWithAncestors = entry->GetDiscountSizeWithAncestors();
4445
nModFeesWithAncestors = entry->GetModFeesWithAncestors();
4546
nSigOpCostWithAncestors = entry->GetSigOpCostWithAncestors();
4647
}
4748

4849
CAmount GetModifiedFee() const { return iter->GetModifiedFee(); }
4950
uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; }
51+
uint64_t GetDiscountSizeWithAncestors() const { return discountSizeWithAncestors; }
5052
CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
5153
size_t GetTxSize() const { return iter->GetTxSize(); }
54+
size_t GetDiscountTxSize() const { return iter->GetDiscountTxSize(); }
5255
const CTransaction& GetTx() const { return iter->GetTx(); }
5356

5457
CTxMemPool::txiter iter;
5558
uint64_t nSizeWithAncestors;
59+
uint64_t discountSizeWithAncestors;
5660
CAmount nModFeesWithAncestors;
5761
int64_t nSigOpCostWithAncestors;
5862
};
@@ -103,12 +107,19 @@ typedef boost::multi_index_container<
103107
boost::multi_index::tag<ancestor_score>,
104108
boost::multi_index::identity<CTxMemPoolModifiedEntry>,
105109
CompareTxMemPoolEntryByAncestorFee
110+
>,
111+
// ELEMENTS
112+
boost::multi_index::ordered_non_unique<
113+
boost::multi_index::tag<confidential_score>,
114+
boost::multi_index::identity<CTxMemPoolModifiedEntry>,
115+
CompareTxMemPoolEntryByConfidentialFee
106116
>
107117
>
108118
> indexed_modified_transaction_set;
109119

110120
typedef indexed_modified_transaction_set::nth_index<0>::type::iterator modtxiter;
111121
typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator modtxscoreiter;
122+
typedef indexed_modified_transaction_set::index<confidential_score>::type::iterator modconftxscoreiter; // ELEMENTS
112123

113124
struct update_for_parent_inclusion
114125
{

src/policy/discount.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) 2009-2010 Satoshi Nakamoto
2+
// Copyright (c) 2009-2021 The Bitcoin Core developers
3+
// Distributed under the MIT software license, see the accompanying
4+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#ifndef BITCOIN_POLICY_DISCOUNT_H
7+
#define BITCOIN_POLICY_DISCOUNT_H
8+
9+
#include <consensus/consensus.h>
10+
#include <cstdint>
11+
#include <primitives/transaction.h>
12+
#include <version.h>
13+
14+
/**
15+
* Calculate a smaller virtual size for discounted Confidential Transactions.
16+
*/
17+
static inline int64_t GetDiscountVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost = 0, unsigned int bytes_per_sig_op = 0)
18+
{
19+
int64_t size_bytes = ::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, PROTOCOL_VERSION);
20+
int64_t sigop_bytes = nSigOpCost * bytes_per_sig_op;
21+
22+
int64_t weight = std::max(size_bytes, sigop_bytes);
23+
24+
// for each confidential output
25+
for (size_t i = 0; i < tx.vout.size(); ++i) {
26+
const CTxOut& output = tx.vout[i];
27+
if (i < tx.witness.vtxoutwit.size()) {
28+
// subtract the weight of the output witness, except the 2 bytes used to serialize the empty proofs
29+
size_t witness_size = ::GetSerializeSize(tx.witness.vtxoutwit[i], PROTOCOL_VERSION);
30+
assert(witness_size >= 2);
31+
weight -= (witness_size - 2);
32+
}
33+
if (output.nValue.IsCommitment()) {
34+
// subtract the weight difference of amount commitment (33) vs explicit amount (9)
35+
weight -= (33 - 9);
36+
}
37+
if (output.nNonce.IsCommitment()) {
38+
// subtract the weight difference of nonce commitment (33) vs no nonce (1)
39+
weight -= 32;
40+
}
41+
}
42+
assert(weight > 0);
43+
44+
size_t discountvsize = (weight + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
45+
46+
assert(discountvsize > 0);
47+
return discountvsize;
48+
}
49+
50+
#endif // BITCOIN_POLICY_DISCOUNT_H

src/policy/policy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define BITCOIN_POLICY_POLICY_H
88

99
#include <consensus/consensus.h>
10+
#include <policy/discount.h>
1011
#include <policy/feerate.h>
1112
#include <script/interpreter.h>
1213
#include <script/standard.h>

0 commit comments

Comments
 (0)