Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

elements-23.x: merge master to prep release #1337

Merged
merged 30 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
98c8e4f
test: fix tests broken by change to getpeginaddress
delta1 Apr 24, 2024
7ff33d4
Merge pull request #1330 from delta1/test-fix-getpeginaddress
delta1 May 7, 2024
c1661b2
discount: introduce config args
delta1 May 9, 2024
9cbd3e0
discount: add policy/discount.h
delta1 May 9, 2024
b7b2288
discount: implement mempool logic
delta1 May 9, 2024
c85f0d4
discount: implement net processing
delta1 May 9, 2024
4807f3e
discount: change miner tx ordering
delta1 May 9, 2024
52962c1
discount: allow wallet to create discount txs
delta1 May 9, 2024
3ebc353
discount: add functional tests
delta1 May 9, 2024
a4d7ac7
Merge pull request #1317 from delta1/ct-fees-discount
psgreco May 14, 2024
31835f2
Prepare access to untrim headers
psgreco Jun 29, 2023
283f47b
Move initialization of setTrimmableBlockIndex
psgreco Jun 29, 2023
423715b
Avoid pruning headers that have not been saved to disk yet
psgreco Jun 29, 2023
d8e1fe7
Avoid trimming on shutdown
psgreco Jun 29, 2023
f89728c
Validate trimmed headers too while loading
psgreco Jun 29, 2023
afc16e8
Allow gaps while trimming headers
psgreco Jun 29, 2023
4259278
Reload trimmed header from index instead of block, block may have bee…
psgreco Jun 29, 2023
c28c5ce
Allow untrimming headers when needed
psgreco Sep 29, 2023
1722d4a
Reduce the number of untrimmed headers in memory, since they can be u…
psgreco Jun 29, 2023
6367320
Restore NODE_NETWORK functionality with trim_headers
psgreco Jun 29, 2023
5a40926
Extreme trimming on startup
psgreco Jul 4, 2023
6fb780d
CI: fix linting errors
jamesdorfman May 6, 2024
90e5bab
CI: fix msan issue
jamesdorfman May 6, 2024
73ed5dd
CI: fix benchmark + QT tests by properly initializing CBlockIndex by …
jamesdorfman May 8, 2024
c6aba4a
CI: fix integer underflow bug
jamesdorfman May 10, 2024
b4185c7
CI: fix asan lock issues
jamesdorfman May 8, 2024
46a3ee2
improve efficiency by gating locks with
jamesdorfman May 27, 2024
4171939
test: add trim_headers functional test
delta1 May 30, 2024
eed85dc
getblockchaininfo: add trim_headers field
delta1 Jun 5, 2024
cdcc74b
Merge pull request #1270 from psgreco/master-trim-headers-v2
delta1 Jun 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ BITCOIN_CORE_H = \
noui.h \
outputtype.h \
pegins.h \
policy/discount.h \
policy/feerate.h \
policy/fees.h \
policy/packages.h \
Expand Down
3 changes: 2 additions & 1 deletion src/bench/rpc_blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace {

struct TestBlockAndIndex {
const std::unique_ptr<const TestingSetup> testing_setup{MakeNoLogFileContext<const TestingSetup>(CBaseChainParams::MAIN)};
std::unique_ptr<TestingSetup> testing_setup{MakeNoLogFileContext<TestingSetup>(CBaseChainParams::MAIN)};
CBlock block{};
uint256 blockHash{};
CBlockIndex blockindex{};
Expand All @@ -28,6 +28,7 @@ struct TestBlockAndIndex {

stream >> block;

CBlockIndex::SetNodeContext(&(testing_setup->m_node));
blockHash = block.GetHash();
blockindex.phashBlock = &blockHash;
blockindex.nBits = 403014710;
Expand Down
26 changes: 26 additions & 0 deletions src/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

#include <chain.h>
#include <util/time.h>
#include <validation.h>
#include <node/context.h>


node::NodeContext *CBlockIndex::m_pcontext;

std::string CBlockFileInfo::ToString() const
{
Expand Down Expand Up @@ -51,6 +56,27 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
return CBlockLocator(vHave);
}

void CBlockIndex::untrim() EXCLUSIVE_LOCKS_REQUIRED(::cs_main){
AssertLockHeld(::cs_main);
if (!trimmed())
return;
CBlockIndex tmp;
const CBlockIndex *pindexfull = untrim_to(&tmp);
assert(pindexfull!=this);
m_trimmed = false;
set_stored();
proof = pindexfull->proof;
m_dynafed_params = pindexfull->m_dynafed_params;
m_signblock_witness = pindexfull->m_signblock_witness;
m_pcontext->chainman->m_blockman.m_dirty_blockindex.insert(this);
}

const CBlockIndex *CBlockIndex::untrim_to(CBlockIndex *pindexNew) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
{
AssertLockHeld(::cs_main);
return m_pcontext->chainman->m_blockman.m_block_tree_db->RegenerateFullIndex(this, pindexNew);
}

const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
if (pindex == nullptr) {
return nullptr;
Expand Down
23 changes: 22 additions & 1 deletion src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

#include <vector>

namespace node {
struct NodeContext;
}
/**
* Maximum amount of time that a block timestamp is allowed to exceed the
* current network-adjusted time before the block will be accepted.
Expand Down Expand Up @@ -215,26 +218,41 @@ class CBlockIndex

bool m_trimmed{false};
bool m_trimmed_dynafed_block{false};
bool m_stored_lvl{false};

friend class CBlockTreeDB;

static node::NodeContext *m_pcontext;

public:
static void SetNodeContext(node::NodeContext *context) {m_pcontext = context;};

// Irrevocably remove blocksigning and dynafed-related stuff from this
// in-memory copy of the block header.
void trim() {
bool trim() {
assert_untrimmed();
if (!m_stored_lvl) {
// We can't trim in-memory data if it's not on disk yet, but we can if it's already been recovered once
return false;
}
m_trimmed = true;
m_trimmed_dynafed_block = !m_dynafed_params.value().IsNull();
proof = std::nullopt;
m_dynafed_params = std::nullopt;
m_signblock_witness = std::nullopt;
return true;
}

void untrim();
const CBlockIndex * untrim_to(CBlockIndex *pindexNew) const;

inline bool trimmed() const {
return m_trimmed;
}

inline void set_stored() {
m_stored_lvl = true;
}
inline void assert_untrimmed() const {
assert(!m_trimmed);
}
Expand Down Expand Up @@ -501,6 +519,9 @@ class CDiskBlockIndex : public CBlockIndex

// For compatibility with elements 0.14 based chains
if (g_signed_blocks) {
if (!ser_action.ForRead()) {
obj.assert_untrimmed();
}
if (is_dyna) {
READWRITE(obj.m_dynafed_params.value());
READWRITE(obj.m_signblock_witness.value().stack);
Expand Down
20 changes: 17 additions & 3 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ class CMainParams : public CChainParams {
anyonecanspend_aremine = false;
enforce_pak = false;
multi_data_permitted = false;
accept_discount_ct = false;
create_discount_ct = false;
consensus.has_parent_chain = false;
g_signed_blocks = false;
g_con_elementsmode = false;
Expand Down Expand Up @@ -361,6 +363,8 @@ class CTestNetParams : public CChainParams {
anyonecanspend_aremine = false;
enforce_pak = false;
multi_data_permitted = false;
accept_discount_ct = false;
create_discount_ct = false;
consensus.has_parent_chain = false;
g_signed_blocks = false;
g_con_elementsmode = false;
Expand Down Expand Up @@ -517,6 +521,8 @@ class SigNetParams : public CChainParams {
anyonecanspend_aremine = false;
enforce_pak = false;
multi_data_permitted = false;
accept_discount_ct = false;
create_discount_ct = false;
consensus.has_parent_chain = false;
g_signed_blocks = false; // lol
g_con_elementsmode = false;
Expand Down Expand Up @@ -610,6 +616,8 @@ class CRegTestParams : public CChainParams {
anyonecanspend_aremine = false;
enforce_pak = false;
multi_data_permitted = false;
accept_discount_ct = false;
create_discount_ct = false;
consensus.has_parent_chain = false;
g_signed_blocks = false;
g_con_elementsmode = false;
Expand Down Expand Up @@ -887,6 +895,8 @@ class CCustomParams : public CRegTestParams {
const CScript default_script(CScript() << OP_TRUE);
consensus.fedpegScript = StrHexToScriptWithDefault(args.GetArg("-fedpegscript", ""), default_script);
consensus.start_p2wsh_script = args.GetIntArg("-con_start_p2wsh_script", consensus.start_p2wsh_script);
create_discount_ct = args.GetBoolArg("-creatediscountct", false);
accept_discount_ct = args.GetBoolArg("-acceptdiscountct", create_discount_ct);

// Calculate pegged Bitcoin asset
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID);
Expand Down Expand Up @@ -1023,7 +1033,7 @@ class CLiquidTestNetParams : public CCustomParams {
*/
class CLiquidV1Params : public CChainParams {
public:
CLiquidV1Params()
explicit CLiquidV1Params(const ArgsManager& args)
{

strNetworkID = "liquidv1";
Expand Down Expand Up @@ -1118,6 +1128,8 @@ class CLiquidV1Params : public CChainParams {
enforce_pak = true;

multi_data_permitted = true;
create_discount_ct = args.GetBoolArg("-creatediscountct", false);
accept_discount_ct = args.GetBoolArg("-acceptdiscountct", false);

parentGenesisBlockHash = uint256S("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
const bool parent_genesis_is_null = parentGenesisBlockHash == uint256();
Expand Down Expand Up @@ -1261,7 +1273,7 @@ class CLiquidV1Params : public CChainParams {
*/
class CLiquidV1TestParams : public CLiquidV1Params {
public:
explicit CLiquidV1TestParams(const ArgsManager& args)
explicit CLiquidV1TestParams(const ArgsManager& args) : CLiquidV1Params(args)
{
// 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.

Expand Down Expand Up @@ -1466,6 +1478,8 @@ class CLiquidV1TestParams : public CLiquidV1Params {
enforce_pak = args.GetBoolArg("-enforce_pak", enforce_pak);

multi_data_permitted = args.GetBoolArg("-multi_data_permitted", multi_data_permitted);
create_discount_ct = args.GetBoolArg("-creatediscountct", create_discount_ct);
accept_discount_ct = args.GetBoolArg("-acceptdiscountct", accept_discount_ct || create_discount_ct);

if (args.IsArgSet("-parentgenesisblockhash")) {
parentGenesisBlockHash = uint256S(args.GetArg("-parentgenesisblockhash", ""));
Expand Down Expand Up @@ -1557,7 +1571,7 @@ std::unique_ptr<const CChainParams> CreateChainParams(const ArgsManager& args, c
} else if (chain == CBaseChainParams::REGTEST) {
return std::unique_ptr<CChainParams>(new CRegTestParams(args));
} else if (chain == CBaseChainParams::LIQUID1) {
return std::unique_ptr<CChainParams>(new CLiquidV1Params());
return std::unique_ptr<CChainParams>(new CLiquidV1Params(args));
} else if (chain == CBaseChainParams::LIQUID1TEST) {
return std::unique_ptr<CChainParams>(new CLiquidV1TestParams(args));
} else if (chain == CBaseChainParams::LIQUIDTESTNET) {
Expand Down
4 changes: 4 additions & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class CChainParams
const std::string& ParentBlech32HRP() const { return parent_blech32_hrp; }
bool GetEnforcePak() const { return enforce_pak; }
bool GetMultiDataPermitted() const { return multi_data_permitted; }
bool GetAcceptDiscountCT() const { return accept_discount_ct; }
bool GetCreateDiscountCT() const { return create_discount_ct; }

protected:
CChainParams() {}
Expand Down Expand Up @@ -167,6 +169,8 @@ class CChainParams
std::string parent_blech32_hrp;
bool enforce_pak;
bool multi_data_permitted;
bool accept_discount_ct;
bool create_discount_ct;
};

/**
Expand Down
5 changes: 5 additions & 0 deletions src/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <consensus/validation.h>
#include <issuance.h>
#include <key_io.h>
#include <policy/discount.h> // ELEMENTS
#include <script/descriptor.h>
#include <script/script.h>
#include <script/sign.h>
Expand Down Expand Up @@ -236,6 +237,10 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
entry.pushKV("version", static_cast<int64_t>(static_cast<uint32_t>(tx.nVersion)));
entry.pushKV("size", (int)::GetSerializeSize(tx, PROTOCOL_VERSION));
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
// ELEMENTS: add discountvsize
if (Params().GetAcceptDiscountCT()) {
entry.pushKV("discountvsize", GetDiscountVirtualTransactionSize(tx));
}
entry.pushKV("weight", GetTransactionWeight(tx));
entry.pushKV("locktime", (int64_t)tx.nLockTime);

Expand Down
14 changes: 14 additions & 0 deletions src/dynafed.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

#include <dynafed.h>
#include <hash.h>
#include <validation.h>
#include <node/context.h>

bool NextBlockIsParameterTransition(const CBlockIndex* pindexPrev, const Consensus::Params& consensus, DynaFedParamEntry& winning_entry)
{
Expand All @@ -15,6 +17,10 @@ bool NextBlockIsParameterTransition(const CBlockIndex* pindexPrev, const Consens
for (int32_t height = next_height - 1; height >= (int32_t)(next_height - consensus.dynamic_epoch_length); --height) {
const CBlockIndex* p_epoch_walk = pindexPrev->GetAncestor(height);
assert(p_epoch_walk);
if (node::fTrimHeaders) {
LOCK(cs_main);
ForceUntrimHeader(p_epoch_walk);
}
const DynaFedParamEntry& proposal = p_epoch_walk->dynafed_params().m_proposed;
const uint256 proposal_root = proposal.CalculateRoot();
vote_tally[proposal_root]++;
Expand Down Expand Up @@ -60,6 +66,10 @@ DynaFedParamEntry ComputeNextBlockFullCurrentParameters(const CBlockIndex* pinde
// may be pre-dynafed params
const CBlockIndex* p_epoch_start = pindexPrev->GetAncestor(epoch_start_height);
assert(p_epoch_start);
if (node::fTrimHeaders) {
LOCK(cs_main);
ForceUntrimHeader(p_epoch_start);
}
if (p_epoch_start->dynafed_params().IsNull()) {
// We need to construct the "full" current parameters of pre-dynafed
// consensus
Expand Down Expand Up @@ -93,6 +103,10 @@ DynaFedParamEntry ComputeNextBlockCurrentParameters(const CBlockIndex* pindexPre
{
assert(pindexPrev);

if (node::fTrimHeaders) {
LOCK(cs_main);
ForceUntrimHeader(pindexPrev);
}
DynaFedParamEntry entry = ComputeNextBlockFullCurrentParameters(pindexPrev, consensus);

uint32_t next_height = pindexPrev->nHeight+1;
Expand Down
14 changes: 6 additions & 8 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-initialreissuancetokens=<n>", "The amount of reissuance tokens created in the genesis block. (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
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);
argsman.AddArg("-ct_exponent", strprintf("The hiding exponent. (default: %s)", 0), ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-acceptdiscountct", "Accept discounted fees for Confidential Transactions (default: true for liquidv1, false for other chains)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
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);

#if defined(USE_SYSCALL_SANDBOX)
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);
Expand Down Expand Up @@ -1009,13 +1011,13 @@ bool AppInitParameterInteraction(const ArgsManager& args)
}

if (args.GetBoolArg("-trim_headers", false)) {
LogPrintf("Configured for header-trimming mode. This will reduce memory usage substantially, but we will be unable to serve as a full P2P peer, and certain header fields may be missing from JSON RPC output.\n");
LogPrintf("Configured for header-trimming mode. This will reduce memory usage substantially, but will increase IO usage when the headers need to be temporarily untrimmed.\n");
node::fTrimHeaders = true;
// This calculation is driven by GetValidFedpegScripts in pegins.cpp, which walks the chain
// back to current epoch start, and then an additional total_valid_epochs on top of that.
// We add one epoch here for the current partial epoch, and then another one for good luck.

node::nMustKeepFullHeaders = (chainparams.GetConsensus().total_valid_epochs + 2) * epoch_length;
node::nMustKeepFullHeaders = chainparams.GetConsensus().total_valid_epochs * epoch_length;
// This is the number of headers we can have in flight downloading at a time, beyond the
// set of blocks we've already validated. Capping this is necessary to keep memory usage
// bounded during IBD.
Expand Down Expand Up @@ -1241,6 +1243,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
const ArgsManager& args = *Assert(node.args);
const CChainParams& chainparams = Params();

CBlockIndex::SetNodeContext(&node);
auto opt_max_upload = ParseByteUnits(args.GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET), ByteUnit::M);
if (!opt_max_upload) {
return InitError(strprintf(_("Unable to parse -maxuploadtarget: '%s'"), args.GetArg("-maxuploadtarget", "")));
Expand Down Expand Up @@ -1710,7 +1713,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)

// if pruning, unset the service bit and perform the initial blockstore prune
// after any wallet rescanning has taken place.
if (fPruneMode || node::fTrimHeaders) {
if (fPruneMode) {
LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK);
if (!fReindex) {
Expand All @@ -1722,11 +1725,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
}
}

if (node::fTrimHeaders) {
LogPrintf("Unsetting NODE_NETWORK_LIMITED on header trim mode\n");
nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK_LIMITED);
}

// ********************************************************* Step 11: import blocks

if (!CheckDiskSpace(gArgs.GetDataDirNet())) {
Expand Down
15 changes: 9 additions & 6 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3305,12 +3305,13 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex))
{
if (pindex->trimmed()) {
// For simplicity, if any of the headers they're asking for are trimmed,
// just drop the request.
LogPrint(BCLog::NET, "%s: ignoring getheaders from peer=%i which would return at least one trimmed header\n", __func__, pfrom.GetId());
return;
// Header is trimmed, reload from disk before sending
CBlockIndex tmpBlockIndexFull;
const CBlockIndex* pindexfull = pindex->untrim_to(&tmpBlockIndexFull);
vHeaders.push_back(pindexfull->GetBlockHeader());
} else {
vHeaders.push_back(pindex->GetBlockHeader());
}
vHeaders.push_back(pindex->GetBlockHeader());
if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
break;
}
Expand Down Expand Up @@ -4964,7 +4965,9 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
auto txid = txinfo.tx->GetHash();
auto wtxid = txinfo.tx->GetWitnessHash();
// Peer told you to not send transactions at that feerate? Don't bother sending it.
if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
// ELEMENTS: use the discounted vsize here so that discounted CTs are relayed.
// discountvsize only differs from vsize if accept_discount_ct is true.
if (txinfo.fee < filterrate.GetFee(txinfo.discountvsize)) {
continue;
}
if (pto->m_tx_relay->pfilter && !pto->m_tx_relay->pfilter->IsRelevantAndUpdate(*txinfo.tx)) continue;
Expand Down
Loading