Skip to content

Commit 61b0543

Browse files
committed
Merge cdcc74b into merged_master (Elements PR ElementsProject#1270)
2 parents 901c7c1 + cdcc74b commit 61b0543

20 files changed

+508
-127
lines changed

src/bench/rpc_blockchain.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
namespace {
1616

1717
struct TestBlockAndIndex {
18-
const std::unique_ptr<const TestingSetup> testing_setup{MakeNoLogFileContext<const TestingSetup>(CBaseChainParams::MAIN)};
18+
std::unique_ptr<TestingSetup> testing_setup{MakeNoLogFileContext<TestingSetup>(CBaseChainParams::MAIN)};
1919
CBlock block{};
2020
uint256 blockHash{};
2121
CBlockIndex blockindex{};
@@ -28,6 +28,7 @@ struct TestBlockAndIndex {
2828

2929
stream >> block;
3030

31+
CBlockIndex::SetNodeContext(&(testing_setup->m_node));
3132
blockHash = block.GetHash();
3233
blockindex.phashBlock = &blockHash;
3334
blockindex.nBits = 403014710;

src/chain.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
#include <chain.h>
77
#include <util/time.h>
8+
#include <validation.h>
9+
#include <node/context.h>
10+
11+
12+
node::NodeContext *CBlockIndex::m_pcontext;
813

914
std::string CBlockFileInfo::ToString() const
1015
{
@@ -51,6 +56,27 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
5156
return CBlockLocator(vHave);
5257
}
5358

59+
void CBlockIndex::untrim() EXCLUSIVE_LOCKS_REQUIRED(::cs_main){
60+
AssertLockHeld(::cs_main);
61+
if (!trimmed())
62+
return;
63+
CBlockIndex tmp;
64+
const CBlockIndex *pindexfull = untrim_to(&tmp);
65+
assert(pindexfull!=this);
66+
m_trimmed = false;
67+
set_stored();
68+
proof = pindexfull->proof;
69+
m_dynafed_params = pindexfull->m_dynafed_params;
70+
m_signblock_witness = pindexfull->m_signblock_witness;
71+
m_pcontext->chainman->m_blockman.m_dirty_blockindex.insert(this);
72+
}
73+
74+
const CBlockIndex *CBlockIndex::untrim_to(CBlockIndex *pindexNew) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
75+
{
76+
AssertLockHeld(::cs_main);
77+
return m_pcontext->chainman->m_blockman.m_block_tree_db->RegenerateFullIndex(this, pindexNew);
78+
}
79+
5480
const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
5581
if (pindex == nullptr) {
5682
return nullptr;

src/chain.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
#include <vector>
1818

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

216219
bool m_trimmed{false};
217220
bool m_trimmed_dynafed_block{false};
221+
bool m_stored_lvl{false};
218222

219223
friend class CBlockTreeDB;
220224

225+
static node::NodeContext *m_pcontext;
226+
221227
public:
228+
static void SetNodeContext(node::NodeContext *context) {m_pcontext = context;};
222229

223230
// Irrevocably remove blocksigning and dynafed-related stuff from this
224231
// in-memory copy of the block header.
225-
void trim() {
232+
bool trim() {
226233
assert_untrimmed();
234+
if (!m_stored_lvl) {
235+
// We can't trim in-memory data if it's not on disk yet, but we can if it's already been recovered once
236+
return false;
237+
}
227238
m_trimmed = true;
228239
m_trimmed_dynafed_block = !m_dynafed_params.value().IsNull();
229240
proof = std::nullopt;
230241
m_dynafed_params = std::nullopt;
231242
m_signblock_witness = std::nullopt;
243+
return true;
232244
}
233245

246+
void untrim();
247+
const CBlockIndex * untrim_to(CBlockIndex *pindexNew) const;
248+
234249
inline bool trimmed() const {
235250
return m_trimmed;
236251
}
237252

253+
inline void set_stored() {
254+
m_stored_lvl = true;
255+
}
238256
inline void assert_untrimmed() const {
239257
assert(!m_trimmed);
240258
}
@@ -501,6 +519,9 @@ class CDiskBlockIndex : public CBlockIndex
501519

502520
// For compatibility with elements 0.14 based chains
503521
if (g_signed_blocks) {
522+
if (!ser_action.ForRead()) {
523+
obj.assert_untrimmed();
524+
}
504525
if (is_dyna) {
505526
READWRITE(obj.m_dynafed_params.value());
506527
READWRITE(obj.m_signblock_witness.value().stack);

src/dynafed.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
#include <dynafed.h>
33
#include <hash.h>
4+
#include <validation.h>
5+
#include <node/context.h>
46

57
bool NextBlockIsParameterTransition(const CBlockIndex* pindexPrev, const Consensus::Params& consensus, DynaFedParamEntry& winning_entry)
68
{
@@ -15,6 +17,10 @@ bool NextBlockIsParameterTransition(const CBlockIndex* pindexPrev, const Consens
1517
for (int32_t height = next_height - 1; height >= (int32_t)(next_height - consensus.dynamic_epoch_length); --height) {
1618
const CBlockIndex* p_epoch_walk = pindexPrev->GetAncestor(height);
1719
assert(p_epoch_walk);
20+
if (node::fTrimHeaders) {
21+
LOCK(cs_main);
22+
ForceUntrimHeader(p_epoch_walk);
23+
}
1824
const DynaFedParamEntry& proposal = p_epoch_walk->dynafed_params().m_proposed;
1925
const uint256 proposal_root = proposal.CalculateRoot();
2026
vote_tally[proposal_root]++;
@@ -60,6 +66,10 @@ DynaFedParamEntry ComputeNextBlockFullCurrentParameters(const CBlockIndex* pinde
6066
// may be pre-dynafed params
6167
const CBlockIndex* p_epoch_start = pindexPrev->GetAncestor(epoch_start_height);
6268
assert(p_epoch_start);
69+
if (node::fTrimHeaders) {
70+
LOCK(cs_main);
71+
ForceUntrimHeader(p_epoch_start);
72+
}
6373
if (p_epoch_start->dynafed_params().IsNull()) {
6474
// We need to construct the "full" current parameters of pre-dynafed
6575
// consensus
@@ -93,6 +103,10 @@ DynaFedParamEntry ComputeNextBlockCurrentParameters(const CBlockIndex* pindexPre
93103
{
94104
assert(pindexPrev);
95105

106+
if (node::fTrimHeaders) {
107+
LOCK(cs_main);
108+
ForceUntrimHeader(pindexPrev);
109+
}
96110
DynaFedParamEntry entry = ComputeNextBlockFullCurrentParameters(pindexPrev, consensus);
97111

98112
uint32_t next_height = pindexPrev->nHeight+1;

src/init.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,13 +1012,13 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
10121012
}
10131013

10141014
if (args.GetBoolArg("-trim_headers", false)) {
1015-
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");
1015+
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");
10161016
node::fTrimHeaders = true;
10171017
// This calculation is driven by GetValidFedpegScripts in pegins.cpp, which walks the chain
10181018
// back to current epoch start, and then an additional total_valid_epochs on top of that.
10191019
// We add one epoch here for the current partial epoch, and then another one for good luck.
10201020

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

1272+
CBlockIndex::SetNodeContext(&node);
12721273
auto opt_max_upload = ParseByteUnits(args.GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET), ByteUnit::M);
12731274
if (!opt_max_upload) {
12741275
return InitError(strprintf(_("Unable to parse -maxuploadtarget: '%s'"), args.GetArg("-maxuploadtarget", "")));
@@ -1756,7 +1757,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
17561757

17571758
// if pruning, unset the service bit and perform the initial blockstore prune
17581759
// after any wallet rescanning has taken place.
1759-
if (fPruneMode || node::fTrimHeaders) {
1760+
if (fPruneMode) {
17601761
LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
17611762
nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK);
17621763
if (!fReindex) {
@@ -1768,11 +1769,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
17681769
}
17691770
}
17701771

1771-
if (node::fTrimHeaders) {
1772-
LogPrintf("Unsetting NODE_NETWORK_LIMITED on header trim mode\n");
1773-
nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK_LIMITED);
1774-
}
1775-
17761772
// ********************************************************* Step 11: import blocks
17771773

17781774
if (!CheckDiskSpace(gArgs.GetDataDirNet())) {

src/net_processing.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3401,12 +3401,13 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
34013401
for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex))
34023402
{
34033403
if (pindex->trimmed()) {
3404-
// For simplicity, if any of the headers they're asking for are trimmed,
3405-
// just drop the request.
3406-
LogPrint(BCLog::NET, "%s: ignoring getheaders from peer=%i which would return at least one trimmed header\n", __func__, pfrom.GetId());
3407-
return;
3404+
// Header is trimmed, reload from disk before sending
3405+
CBlockIndex tmpBlockIndexFull;
3406+
const CBlockIndex* pindexfull = pindex->untrim_to(&tmpBlockIndexFull);
3407+
vHeaders.push_back(pindexfull->GetBlockHeader());
3408+
} else {
3409+
vHeaders.push_back(pindex->GetBlockHeader());
34083410
}
3409-
vHeaders.push_back(pindex->GetBlockHeader());
34103411
if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
34113412
break;
34123413
}

src/node/blockstorage.cpp

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -261,15 +261,7 @@ bool BlockManager::LoadBlockIndex(const Consensus::Params& consensus_params)
261261
{
262262
int trim_below_height = 0;
263263
if (fTrimHeaders) {
264-
int max_height = 0;
265-
if (!m_block_tree_db->WalkBlockIndexGutsForMaxHeight(&max_height)) {
266-
LogPrintf("LoadBlockIndex: Failed to WalkBlockIndexGutsForMaxHeight.\n");
267-
return false;
268-
}
269-
270-
int must_keep_headers = (consensus_params.total_valid_epochs + 2) * consensus_params.dynamic_epoch_length;
271-
int extra_headers_buffer = consensus_params.dynamic_epoch_length * 2; // XXX arbitrary
272-
trim_below_height = max_height - must_keep_headers - extra_headers_buffer;
264+
trim_below_height = std::numeric_limits<int>::max();
273265
}
274266
if (!m_block_tree_db->LoadBlockIndexGuts(consensus_params, [this](const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return this->InsertBlockIndex(hash); }, trim_below_height)) {
275267
return false;
@@ -310,6 +302,9 @@ bool BlockManager::LoadBlockIndex(const Consensus::Params& consensus_params)
310302
}
311303
}
312304

305+
if (pindexBestHeader) {
306+
ForceUntrimHeader(pindexBestHeader);
307+
}
313308
return true;
314309
}
315310

@@ -769,23 +764,6 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus
769764
return true;
770765
}
771766

772-
bool ReadBlockHeaderFromDisk(CBlockHeader& header, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
773-
{
774-
// Not very efficient: read a block and throw away all but the header.
775-
CBlock tmp;
776-
if (!ReadBlockFromDisk(tmp, pindex, consensusParams)) {
777-
return false;
778-
}
779-
const FlatFilePos block_pos{WITH_LOCK(cs_main, return pindex->GetBlockPos())};
780-
781-
header = tmp.GetBlockHeader();
782-
if (tmp.GetHash() != pindex->GetBlockHash()) {
783-
return error("ReadBlockheaderFromDisk(CBlockHeader&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
784-
pindex->ToString(), block_pos.ToString());
785-
}
786-
return true;
787-
}
788-
789767
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start)
790768
{
791769
FlatFilePos hpos = pos;

src/node/blockstorage.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class BlockManager
8989
{
9090
friend CChainState;
9191
friend ChainstateManager;
92+
friend CBlockIndex;
9293

9394
private:
9495
/**
@@ -216,7 +217,6 @@ bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::P
216217
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
217218
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
218219
// ELEMENTS:
219-
bool ReadBlockHeaderFromDisk(class CBlockHeader& header, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
220220

221221
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
222222

src/pegins.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
// ELEMENTS
2727
//
2828

29+
#include <validation.h>
30+
2931
namespace {
3032
static secp256k1_context* secp256k1_ctx_validation;
3133

@@ -487,6 +489,10 @@ std::vector<std::pair<CScript, CScript>> GetValidFedpegScripts(const CBlockIndex
487489
break;
488490
}
489491

492+
if (node::fTrimHeaders) {
493+
LOCK(cs_main);
494+
ForceUntrimHeader(p_epoch_start);
495+
}
490496
if (!p_epoch_start->dynafed_params().IsNull()) {
491497
fedpegscripts.push_back(std::make_pair(p_epoch_start->dynafed_params().m_current.m_fedpeg_program, p_epoch_start->dynafed_params().m_current.m_fedpegscript));
492498
} else {

src/qt/test/rpcnestedtests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void RPCNestedTests::rpcNestedTests()
4848

4949
TestingSetup test;
5050
m_node.setContext(&test.m_node);
51+
CBlockIndex::SetNodeContext(&test.m_node);
5152

5253
if (RPCIsInWarmup(nullptr)) SetRPCWarmupFinished();
5354

src/rest.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,10 @@ static bool rest_headers(const std::any& context,
238238
case RESTResponseFormat::BINARY: {
239239
CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
240240
for (const CBlockIndex *pindex : headers) {
241-
if (pindex->trimmed()) {
242-
CBlockHeader tmp;
243-
node::ReadBlockHeaderFromDisk(tmp, pindex, Params().GetConsensus());
244-
ssHeader << tmp;
245-
} else {
246-
ssHeader << pindex->GetBlockHeader();
247-
}
241+
LOCK(cs_main);
242+
CBlockIndex tmpBlockIndexFull;
243+
const CBlockIndex* pindexfull=pindex->untrim_to(&tmpBlockIndexFull);
244+
ssHeader << pindexfull->GetBlockHeader();
248245
}
249246

250247
std::string binaryHeader = ssHeader.str();
@@ -256,14 +253,10 @@ static bool rest_headers(const std::any& context,
256253
case RESTResponseFormat::HEX: {
257254
CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
258255
for (const CBlockIndex *pindex : headers) {
259-
if (pindex->trimmed()) {
260-
CBlockHeader tmp;
261-
node::ReadBlockHeaderFromDisk(tmp, pindex, Params().GetConsensus());
262-
ssHeader << tmp;
263-
264-
} else {
265-
ssHeader << pindex->GetBlockHeader();
266-
}
256+
LOCK(cs_main);
257+
CBlockIndex tmpBlockIndexFull;
258+
const CBlockIndex* pindexfull=pindex->untrim_to(&tmpBlockIndexFull);
259+
ssHeader << pindexfull->GetBlockHeader();
267260
}
268261

269262
std::string strHex = HexStr(ssHeader) + "\n";

0 commit comments

Comments
 (0)