Skip to content

Commit

Permalink
Update files
Browse files Browse the repository at this point in the history
  • Loading branch information
janus committed Aug 27, 2024
1 parent a650fec commit c51e7d3
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 36 deletions.
6 changes: 3 additions & 3 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <init.h>

#include <kernel/checks.h>
#include <node/mempool_persist.h>
#include <kernel/validation_cache_sizes.h>

#include <addrman.h>
Expand Down Expand Up @@ -52,6 +51,7 @@
#include <node/kernel_notifications.h>
#include <node/mempool_args.h>
#include <node/mempool_persist_args.h>
#include <node/mempool_persist.h>
#include <node/miner.h>
#include <node/peerman_args.h>
#include <node/validation_cache_args.h>
Expand Down Expand Up @@ -119,8 +119,6 @@
using common::AmountErrMsg;
using common::InvalidPortErrMsg;
using common::ResolveErrMsg;
using node::DumpMempool;
using node::LoadMempool;
using kernel::ValidationCacheSizes;

using node::ApplyArgsManOptions;
Expand All @@ -137,6 +135,8 @@ using node::NodeContext;
using node::ShouldPersistMempool;
using node::ImportBlocks;
using node::VerifyLoadedChainstate;
using node::DumpMempool;
using node::LoadMempool;
using util::Join;
using util::ReplaceAll;
using util::ToString;
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ static RPCHelpMan generatetoaddress()
RPCExamples{
"\nGenerate 11 blocks to myaddress\n"
+ HelpExampleCli("generatetoaddress", "11 \"myaddress\"")
+ "If you are using the " PACKAGE_NAME " wallet, you can get a new address to send the newly generated bitcoin to with:\n"
+ "If you are using the " PACKAGE_NAME " wallet, you can get a new address to send the newly generated BGL to with:\n"
+ HelpExampleCli("getnewaddress", "")
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
Expand Down
3 changes: 1 addition & 2 deletions src/univalue/lib/univalue.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2014 BitPay Inc.
// Copyright 2015 BGL Core Developers
// Copyright 2015 Bitcoin Core Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -239,4 +239,3 @@ const UniValue& UniValue::find_value(std::string_view key) const
}
return NullUniValue;
}

2 changes: 1 addition & 1 deletion src/univalue/lib/univalue_get.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2014 BitPay Inc.
// Copyright 2015 BGL Core Developers
// Copyright 2015 Bitcoin Core Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

Expand Down
4 changes: 3 additions & 1 deletion src/univalue/lib/univalue_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,9 @@ bool UniValue::read(std::string_view str_in)
stack.push_back(newTop);
}

if (stack.size() > MAX_JSON_DEPTH)
return false;

if (utyp == VOBJ)
setExpect(OBJ_NAME);
else
Expand Down Expand Up @@ -459,4 +462,3 @@ bool UniValue::read(std::string_view str_in)

return true;
}

95 changes: 69 additions & 26 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,6 @@ class MemPoolAccept
/** Mempool entry constructed for this transaction. Constructed in PreChecks() but not
* inserted into the mempool until Finalize(). */
std::unique_ptr<CTxMemPoolEntry> m_entry;
/** Pointers to the transactions that have been removed from the mempool and replaced by
* this transaction (everything in m_all_conflicting), used to return to the MemPoolAccept caller. Only populated if
* validation is successful and the original transactions are removed. */
std::list<CTransactionRef> m_replaced_transactions;
/** Whether RBF-related data structures (m_conflicts, m_iters_conflicting, m_all_conflicting,
* m_replaced_transactions) include a sibling in addition to txns with conflicting inputs. */
bool m_sibling_eviction{false};
Expand Down Expand Up @@ -1566,21 +1562,21 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
// a child that is below mempool minimum feerate. To avoid these behaviors, callers of
// AcceptMultipleTransactions need to restrict txns topology (e.g. to ancestor sets) and check
// the feerates of individuals and subsets.
const auto m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0},
m_subpackage.m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0},
[](int64_t sum, auto& ws) { return sum + ws.m_vsize; });
const auto m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(), CAmount{0},
m_subpackage.m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(), CAmount{0},
[](CAmount sum, auto& ws) { return sum + ws.m_modified_fees; });
const CFeeRate package_feerate(m_total_modified_fees, m_total_vsize);
const CFeeRate package_feerate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize);
std::vector<Wtxid> all_package_wtxids;
all_package_wtxids.reserve(workspaces.size());
std::transform(workspaces.cbegin(), workspaces.cend(), std::back_inserter(all_package_wtxids),
[](const auto& ws) { return ws.m_ptx->GetWitnessHash(); });
TxValidationState placeholder_state;
if (args.m_package_feerates &&
!CheckFeeRate(m_total_vsize, m_total_modified_fees, placeholder_state)) {
!CheckFeeRate(m_subpackage.m_total_vsize, m_subpackage.m_total_modified_fees, placeholder_state)) {
package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed");
return PackageMempoolAcceptResult(package_state, {{workspaces.back().m_ptx->GetWitnessHash(),
MempoolAcceptResult::FeeFailure(placeholder_state, CFeeRate(m_total_modified_fees, m_total_vsize), all_package_wtxids)}});
MempoolAcceptResult::FeeFailure(placeholder_state, CFeeRate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize), all_package_wtxids)}});
}

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

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

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

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

bool ChainstateManager::ShouldCheckBlockIndex() const
{
// Assert to verify Flatten() has been called.
if (!*Assert(m_options.check_block_index)) return false;
if (GetRand(*m_options.check_block_index) >= 1) return false;
return true;
}

void ChainstateManager::CheckBlockIndex()
{
if (!ShouldCheckBlockIndex()) {
Expand All @@ -5217,19 +5235,30 @@ void ChainstateManager::CheckBlockIndex()
return;
}

// Build forward-pointing map of the entire block tree.
// Build forward-pointing data structure for the entire block tree.
// For performance reasons, indexes of the best header chain are stored in a vector (within CChain).
// All remaining blocks are stored in a multimap.
// The best header chain can differ from the active chain: E.g. its entries may belong to blocks that
// are not yet validated.
CChain best_hdr_chain;
assert(m_best_header);
best_hdr_chain.SetTip(*m_best_header);

std::multimap<CBlockIndex*,CBlockIndex*> forward;
for (auto& [_, block_index] : m_blockman.m_block_index) {
// Only save indexes in forward that are not part of the best header chain.
if (!best_hdr_chain.Contains(&block_index)) {
// Only genesis, which must be part of the best header chain, can have a nullptr parent.
assert(block_index.pprev);
forward.emplace(block_index.pprev, &block_index);
forward.emplace(block_index.pprev, &block_index);
forward.emplace(block_index.pprev, &block_index);
}
}
assert(forward.size() + best_hdr_chain.Height() + 1 == m_blockman.m_block_index.size());

assert(forward.size() == m_blockman.m_block_index.size());

std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(nullptr);
CBlockIndex *pindex = rangeGenesis.first->second;
rangeGenesis.first++;
assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent nullptr.

CBlockIndex* pindex = best_hdr_chain[0];
assert(pindex);
// Iterate over the entire block tree, using depth-first search.
// Along the way, remember whether there are blocks on the path from genesis
// block being explored which are the first to have certain properties.
Expand Down Expand Up @@ -5441,14 +5470,21 @@ void ChainstateManager::CheckBlockIndex()
// assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
// End: actual consistency checks.

// Try descending into the first subnode.

// Try descending into the first subnode. Always process forks first and the best header chain after.
snap_update_firsts();
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
if (range.first != range.second) {
// A subnode was found.
// A subnode not part of the best header chain was found.
pindex = range.first->second;
nHeight++;
continue;
} else if (best_hdr_chain.Contains(pindex)) {
// Descend further into best header chain.
nHeight++;
pindex = best_hdr_chain[nHeight];
if (!pindex) break; // we are finished, since the best header chain is always processed last
continue;
}
// This is a leaf node.
// Move upwards until we reach a node of which we have not yet visited the last child.
Expand All @@ -5474,9 +5510,15 @@ void ChainstateManager::CheckBlockIndex()
// Proceed to the next one.
rangePar.first++;
if (rangePar.first != rangePar.second) {
// Move to the sibling.
// Move to a sibling not part of the best header chain.
pindex = rangePar.first->second;
break;
} else if (pindexPar == best_hdr_chain[nHeight - 1]) {
// Move to pindex's sibling on the best-chain, if it has one.
pindex = best_hdr_chain[nHeight];
// There will not be a next block if (and only if) parent block is the best header.
assert((pindex == nullptr) == (pindexPar == best_hdr_chain.Tip()));
break;
} else {
// Move up further.
pindex = pindexPar;
Expand All @@ -5486,8 +5528,8 @@ void ChainstateManager::CheckBlockIndex()
}
}

// Check that we actually traversed the entire map.
assert(nNodes == forward.size());
// Check that we actually traversed the entire block index.
assert(nNodes == forward.size() + best_hdr_chain.Height() + 1);
}

std::string Chainstate::ToString()
Expand Down Expand Up @@ -6337,13 +6379,14 @@ bool ChainstateManager::DeleteSnapshotChainstate()
Assert(m_snapshot_chainstate);
Assert(m_ibd_chainstate);

fs::path snapshot_datadir = GetSnapshotCoinsDBPath(*m_snapshot_chainstate);
fs::path snapshot_datadir = Assert(node::FindSnapshotChainstateDir(m_options.datadir)).value();
if (!DeleteCoinsDBFromDisk(snapshot_datadir, /*is_snapshot=*/ true)) {
LogPrintf("Deletion of %s failed. Please remove it manually to continue reindexing.\n",
fs::PathToString(snapshot_datadir));
return false;
}
m_active_chainstate = m_ibd_chainstate.get();
m_active_chainstate->m_mempool = m_snapshot_chainstate->m_mempool;
m_snapshot_chainstate.reset();
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ enum class CoinsCacheSizeState
* current best chain.
*
* Eventually, the API here is targeted at being exposed externally as a
* consumable libconsensus library, so any functions added must only call
* consumable library, so any functions added must only call
* other class member functions, pure functions in other parts of the consensus
* library, callbacks via the validation interface, or read/write-to-disk
* functions (eventually this will also be via callbacks).
Expand Down Expand Up @@ -938,7 +938,7 @@ class ChainstateManager

const CChainParams& GetParams() const { return m_options.chainparams; }
const Consensus::Params& GetConsensus() const { return m_options.chainparams.GetConsensus(); }
bool ShouldCheckBlockIndex() const { return *Assert(m_options.check_block_index); }
bool ShouldCheckBlockIndex() const;
const arith_uint256& MinimumChainWork() const { return *Assert(m_options.minimum_chain_work); }
const uint256& AssumedValidBlock() const { return *Assert(m_options.assumed_valid_block); }
kernel::Notifications& GetNotifications() const { return m_options.notifications; };
Expand Down

0 comments on commit c51e7d3

Please sign in to comment.