Skip to content

Commit c51e7d3

Browse files
committed
Update files
1 parent a650fec commit c51e7d3

File tree

7 files changed

+80
-36
lines changed

7 files changed

+80
-36
lines changed

src/init.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <init.h>
99

1010
#include <kernel/checks.h>
11-
#include <node/mempool_persist.h>
1211
#include <kernel/validation_cache_sizes.h>
1312

1413
#include <addrman.h>
@@ -52,6 +51,7 @@
5251
#include <node/kernel_notifications.h>
5352
#include <node/mempool_args.h>
5453
#include <node/mempool_persist_args.h>
54+
#include <node/mempool_persist.h>
5555
#include <node/miner.h>
5656
#include <node/peerman_args.h>
5757
#include <node/validation_cache_args.h>
@@ -119,8 +119,6 @@
119119
using common::AmountErrMsg;
120120
using common::InvalidPortErrMsg;
121121
using common::ResolveErrMsg;
122-
using node::DumpMempool;
123-
using node::LoadMempool;
124122
using kernel::ValidationCacheSizes;
125123

126124
using node::ApplyArgsManOptions;
@@ -137,6 +135,8 @@ using node::NodeContext;
137135
using node::ShouldPersistMempool;
138136
using node::ImportBlocks;
139137
using node::VerifyLoadedChainstate;
138+
using node::DumpMempool;
139+
using node::LoadMempool;
140140
using util::Join;
141141
using util::ReplaceAll;
142142
using util::ToString;

src/rpc/mining.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ static RPCHelpMan generatetoaddress()
273273
RPCExamples{
274274
"\nGenerate 11 blocks to myaddress\n"
275275
+ HelpExampleCli("generatetoaddress", "11 \"myaddress\"")
276-
+ "If you are using the " PACKAGE_NAME " wallet, you can get a new address to send the newly generated bitcoin to with:\n"
276+
+ "If you are using the " PACKAGE_NAME " wallet, you can get a new address to send the newly generated BGL to with:\n"
277277
+ HelpExampleCli("getnewaddress", "")
278278
},
279279
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue

src/univalue/lib/univalue.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright 2014 BitPay Inc.
2-
// Copyright 2015 BGL Core Developers
2+
// Copyright 2015 Bitcoin Core Developers
33
// Distributed under the MIT software license, see the accompanying
44
// file COPYING or https://opensource.org/licenses/mit-license.php.
55

@@ -239,4 +239,3 @@ const UniValue& UniValue::find_value(std::string_view key) const
239239
}
240240
return NullUniValue;
241241
}
242-

src/univalue/lib/univalue_get.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright 2014 BitPay Inc.
2-
// Copyright 2015 BGL Core Developers
2+
// Copyright 2015 Bitcoin Core Developers
33
// Distributed under the MIT software license, see the accompanying
44
// file COPYING or https://opensource.org/licenses/mit-license.php.
55

src/univalue/lib/univalue_read.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,9 @@ bool UniValue::read(std::string_view str_in)
336336
stack.push_back(newTop);
337337
}
338338

339+
if (stack.size() > MAX_JSON_DEPTH)
340+
return false;
341+
339342
if (utyp == VOBJ)
340343
setExpect(OBJ_NAME);
341344
else
@@ -459,4 +462,3 @@ bool UniValue::read(std::string_view str_in)
459462

460463
return true;
461464
}
462-

src/validation.cpp

+69-26
Original file line numberDiff line numberDiff line change
@@ -635,10 +635,6 @@ class MemPoolAccept
635635
/** Mempool entry constructed for this transaction. Constructed in PreChecks() but not
636636
* inserted into the mempool until Finalize(). */
637637
std::unique_ptr<CTxMemPoolEntry> m_entry;
638-
/** Pointers to the transactions that have been removed from the mempool and replaced by
639-
* this transaction (everything in m_all_conflicting), used to return to the MemPoolAccept caller. Only populated if
640-
* validation is successful and the original transactions are removed. */
641-
std::list<CTransactionRef> m_replaced_transactions;
642638
/** Whether RBF-related data structures (m_conflicts, m_iters_conflicting, m_all_conflicting,
643639
* m_replaced_transactions) include a sibling in addition to txns with conflicting inputs. */
644640
bool m_sibling_eviction{false};
@@ -1566,21 +1562,21 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
15661562
// a child that is below mempool minimum feerate. To avoid these behaviors, callers of
15671563
// AcceptMultipleTransactions need to restrict txns topology (e.g. to ancestor sets) and check
15681564
// the feerates of individuals and subsets.
1569-
const auto m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0},
1565+
m_subpackage.m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0},
15701566
[](int64_t sum, auto& ws) { return sum + ws.m_vsize; });
1571-
const auto m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(), CAmount{0},
1567+
m_subpackage.m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(), CAmount{0},
15721568
[](CAmount sum, auto& ws) { return sum + ws.m_modified_fees; });
1573-
const CFeeRate package_feerate(m_total_modified_fees, m_total_vsize);
1569+
const CFeeRate package_feerate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize);
15741570
std::vector<Wtxid> all_package_wtxids;
15751571
all_package_wtxids.reserve(workspaces.size());
15761572
std::transform(workspaces.cbegin(), workspaces.cend(), std::back_inserter(all_package_wtxids),
15771573
[](const auto& ws) { return ws.m_ptx->GetWitnessHash(); });
15781574
TxValidationState placeholder_state;
15791575
if (args.m_package_feerates &&
1580-
!CheckFeeRate(m_total_vsize, m_total_modified_fees, placeholder_state)) {
1576+
!CheckFeeRate(m_subpackage.m_total_vsize, m_subpackage.m_total_modified_fees, placeholder_state)) {
15811577
package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed");
15821578
return PackageMempoolAcceptResult(package_state, {{workspaces.back().m_ptx->GetWitnessHash(),
1583-
MempoolAcceptResult::FeeFailure(placeholder_state, CFeeRate(m_total_modified_fees, m_total_vsize), all_package_wtxids)}});
1579+
MempoolAcceptResult::FeeFailure(placeholder_state, CFeeRate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize), all_package_wtxids)}});
15841580
}
15851581

15861582
// Apply package mempool ancestor/descendant limits. Skip if there is only one transaction,
@@ -1603,7 +1599,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
16031599
const auto effective_feerate_wtxids = args.m_package_feerates ? all_package_wtxids :
16041600
std::vector<Wtxid>{ws.m_ptx->GetWitnessHash()};
16051601
results.emplace(ws.m_ptx->GetWitnessHash(),
1606-
MempoolAcceptResult::Success(std::move(ws.m_replaced_transactions),
1602+
MempoolAcceptResult::Success(std::move(m_subpackage.m_replaced_transactions),
16071603
ws.m_vsize, ws.m_base_fees, effective_feerate,
16081604
effective_feerate_wtxids));
16091605
}
@@ -1853,6 +1849,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package,
18531849

18541850
MempoolAcceptResult AcceptToMemoryPool(Chainstate& active_chainstate, const CTransactionRef& tx,
18551851
int64_t accept_time, bool bypass_limits, bool test_accept)
1852+
EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
18561853
{
18571854
AssertLockHeld(::cs_main);
18581855
const CChainParams& chainparams{active_chainstate.m_chainman.GetParams()};
@@ -2918,8 +2915,10 @@ bool Chainstate::FlushStateToDisk(
29182915
return FatalError(m_chainman.GetNotifications(), state, _("Disk space is too low!"));
29192916
}
29202917
// Flush the chainstate (which may refer to block index entries).
2921-
if (!CoinsTip().Flush())
2918+
const auto empty_cache{(mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fFlushForPrune};
2919+
if (empty_cache ? !CoinsTip().Flush() : !CoinsTip().Sync()) {
29222920
return FatalError(m_chainman.GetNotifications(), state, _("Failed to write to coin database."));
2921+
}
29232922
m_last_flush = nNow;
29242923
full_flush_completed = true;
29252924
TRACE5(utxocache, flush,
@@ -4135,7 +4134,18 @@ bool IsBlockMutated(const CBlock& block, bool check_witness_root)
41354134
}
41364135

41374136
if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) {
4138-
return false;
4137+
// Consider the block mutated if any transaction is 64 bytes in size (see 3.1
4138+
// in "Weaknesses in Bitcoin’s Merkle Root Construction":
4139+
// https://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20190225/a27d8837/attachment-0001.pdf).
4140+
//
4141+
// Note: This is not a consensus change as this only applies to blocks that
4142+
// don't have a coinbase transaction and would therefore already be invalid.
4143+
return std::any_of(block.vtx.begin(), block.vtx.end(),
4144+
[](auto& tx) { return GetSerializeSize(TX_NO_WITNESS(tx)) == 64; });
4145+
} else {
4146+
// Theoretically it is still possible for a block with a 64 byte
4147+
// coinbase transaction to be mutated but we neglect that possibility
4148+
// here as it requires at least 224 bits of work.
41394149
}
41404150

41414151
if (!CheckWitnessMalleation(block, check_witness_root, state, 0)) {
@@ -5201,6 +5211,14 @@ void ChainstateManager::LoadExternalBlockFile(
52015211
LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
52025212
}
52035213

5214+
bool ChainstateManager::ShouldCheckBlockIndex() const
5215+
{
5216+
// Assert to verify Flatten() has been called.
5217+
if (!*Assert(m_options.check_block_index)) return false;
5218+
if (GetRand(*m_options.check_block_index) >= 1) return false;
5219+
return true;
5220+
}
5221+
52045222
void ChainstateManager::CheckBlockIndex()
52055223
{
52065224
if (!ShouldCheckBlockIndex()) {
@@ -5217,19 +5235,30 @@ void ChainstateManager::CheckBlockIndex()
52175235
return;
52185236
}
52195237

5220-
// Build forward-pointing map of the entire block tree.
5238+
// Build forward-pointing data structure for the entire block tree.
5239+
// For performance reasons, indexes of the best header chain are stored in a vector (within CChain).
5240+
// All remaining blocks are stored in a multimap.
5241+
// The best header chain can differ from the active chain: E.g. its entries may belong to blocks that
5242+
// are not yet validated.
5243+
CChain best_hdr_chain;
5244+
assert(m_best_header);
5245+
best_hdr_chain.SetTip(*m_best_header);
5246+
52215247
std::multimap<CBlockIndex*,CBlockIndex*> forward;
52225248
for (auto& [_, block_index] : m_blockman.m_block_index) {
5249+
// Only save indexes in forward that are not part of the best header chain.
5250+
if (!best_hdr_chain.Contains(&block_index)) {
5251+
// Only genesis, which must be part of the best header chain, can have a nullptr parent.
5252+
assert(block_index.pprev);
5253+
forward.emplace(block_index.pprev, &block_index);
52235254
forward.emplace(block_index.pprev, &block_index);
5255+
forward.emplace(block_index.pprev, &block_index);
5256+
}
52245257
}
5258+
assert(forward.size() + best_hdr_chain.Height() + 1 == m_blockman.m_block_index.size());
52255259

5226-
assert(forward.size() == m_blockman.m_block_index.size());
5227-
5228-
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(nullptr);
5229-
CBlockIndex *pindex = rangeGenesis.first->second;
5230-
rangeGenesis.first++;
5231-
assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent nullptr.
5232-
5260+
CBlockIndex* pindex = best_hdr_chain[0];
5261+
assert(pindex);
52335262
// Iterate over the entire block tree, using depth-first search.
52345263
// Along the way, remember whether there are blocks on the path from genesis
52355264
// block being explored which are the first to have certain properties.
@@ -5441,14 +5470,21 @@ void ChainstateManager::CheckBlockIndex()
54415470
// assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
54425471
// End: actual consistency checks.
54435472

5444-
// Try descending into the first subnode.
5473+
5474+
// Try descending into the first subnode. Always process forks first and the best header chain after.
54455475
snap_update_firsts();
54465476
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
54475477
if (range.first != range.second) {
5448-
// A subnode was found.
5478+
// A subnode not part of the best header chain was found.
54495479
pindex = range.first->second;
54505480
nHeight++;
54515481
continue;
5482+
} else if (best_hdr_chain.Contains(pindex)) {
5483+
// Descend further into best header chain.
5484+
nHeight++;
5485+
pindex = best_hdr_chain[nHeight];
5486+
if (!pindex) break; // we are finished, since the best header chain is always processed last
5487+
continue;
54525488
}
54535489
// This is a leaf node.
54545490
// Move upwards until we reach a node of which we have not yet visited the last child.
@@ -5474,9 +5510,15 @@ void ChainstateManager::CheckBlockIndex()
54745510
// Proceed to the next one.
54755511
rangePar.first++;
54765512
if (rangePar.first != rangePar.second) {
5477-
// Move to the sibling.
5513+
// Move to a sibling not part of the best header chain.
54785514
pindex = rangePar.first->second;
54795515
break;
5516+
} else if (pindexPar == best_hdr_chain[nHeight - 1]) {
5517+
// Move to pindex's sibling on the best-chain, if it has one.
5518+
pindex = best_hdr_chain[nHeight];
5519+
// There will not be a next block if (and only if) parent block is the best header.
5520+
assert((pindex == nullptr) == (pindexPar == best_hdr_chain.Tip()));
5521+
break;
54805522
} else {
54815523
// Move up further.
54825524
pindex = pindexPar;
@@ -5486,8 +5528,8 @@ void ChainstateManager::CheckBlockIndex()
54865528
}
54875529
}
54885530

5489-
// Check that we actually traversed the entire map.
5490-
assert(nNodes == forward.size());
5531+
// Check that we actually traversed the entire block index.
5532+
assert(nNodes == forward.size() + best_hdr_chain.Height() + 1);
54915533
}
54925534

54935535
std::string Chainstate::ToString()
@@ -6337,13 +6379,14 @@ bool ChainstateManager::DeleteSnapshotChainstate()
63376379
Assert(m_snapshot_chainstate);
63386380
Assert(m_ibd_chainstate);
63396381

6340-
fs::path snapshot_datadir = GetSnapshotCoinsDBPath(*m_snapshot_chainstate);
6382+
fs::path snapshot_datadir = Assert(node::FindSnapshotChainstateDir(m_options.datadir)).value();
63416383
if (!DeleteCoinsDBFromDisk(snapshot_datadir, /*is_snapshot=*/ true)) {
63426384
LogPrintf("Deletion of %s failed. Please remove it manually to continue reindexing.\n",
63436385
fs::PathToString(snapshot_datadir));
63446386
return false;
63456387
}
63466388
m_active_chainstate = m_ibd_chainstate.get();
6389+
m_active_chainstate->m_mempool = m_snapshot_chainstate->m_mempool;
63476390
m_snapshot_chainstate.reset();
63486391
return true;
63496392
}

src/validation.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ enum class CoinsCacheSizeState
477477
* current best chain.
478478
*
479479
* Eventually, the API here is targeted at being exposed externally as a
480-
* consumable libconsensus library, so any functions added must only call
480+
* consumable library, so any functions added must only call
481481
* other class member functions, pure functions in other parts of the consensus
482482
* library, callbacks via the validation interface, or read/write-to-disk
483483
* functions (eventually this will also be via callbacks).
@@ -938,7 +938,7 @@ class ChainstateManager
938938

939939
const CChainParams& GetParams() const { return m_options.chainparams; }
940940
const Consensus::Params& GetConsensus() const { return m_options.chainparams.GetConsensus(); }
941-
bool ShouldCheckBlockIndex() const { return *Assert(m_options.check_block_index); }
941+
bool ShouldCheckBlockIndex() const;
942942
const arith_uint256& MinimumChainWork() const { return *Assert(m_options.minimum_chain_work); }
943943
const uint256& AssumedValidBlock() const { return *Assert(m_options.assumed_valid_block); }
944944
kernel::Notifications& GetNotifications() const { return m_options.notifications; };

0 commit comments

Comments
 (0)