mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 10:43:19 -03:00
Merge bitcoin/bitcoin#24595: deploymentstatus: move g_versionbitscache global to ChainstateManager
bb5c24b120
validation: move g_versionbitscache into ChainstateManager (Anthony Towns)eca22c726a
test/versionbits: make versionbitscache a parameter (Anthony Towns)d603f1d8a7
deploymentstatus: make versionbitscache a parameter (Anthony Towns)78adef1753
refactor: use chainman instead of chainParams for DeploymentActive* (Anthony Towns)deffe0df6c
deploymentstatus: allow chainman in place of consensusParams (Anthony Towns)eaa2e3f25c
validation: move UpdateUncommittedBlockStructures and GenerateCoinbaseCommitment into ChainstateManager (Anthony Towns)5c67e84d37
validation: replace ::Params() calls with chainstate/chainman member (Anthony Towns)38860f93b6
validation: remove redundant CChainParams params from ChainstateManager methods (Anthony Towns)69675ea4e7
validation: add CChainParams to ChainstateManager (Anthony Towns) Pull request description: Gives `ChainstateManager` a reference to the `CChainParams` its working on, and simplifies some of the functions that would otherwise take that as a parameter. Removes the `g_versionbitscache` global by moving it into `ChainstateManager`. ACKs for top commit: dongcarl: reACKbb5c24b120
MarcoFalke: review ACKbb5c24b120
📙 Tree-SHA512: 3fa74905e5df561e3e74bb0b8fce6085c5311e6633e7d74c0fb0c82a907f5bbb1fd4ebc5d11d4f0b1c019bb51eabb9f6e4bcc4652a696d36a5878c807b85f121
This commit is contained in:
commit
25dd4d8513
18 changed files with 200 additions and 170 deletions
|
@ -70,7 +70,7 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
|
|
||||||
// SETUP: Chainstate
|
// SETUP: Chainstate
|
||||||
ChainstateManager chainman;
|
ChainstateManager chainman{chainparams};
|
||||||
|
|
||||||
auto rv = node::LoadChainstate(false,
|
auto rv = node::LoadChainstate(false,
|
||||||
std::ref(chainman),
|
std::ref(chainman),
|
||||||
|
@ -163,7 +163,7 @@ int main(int argc, char* argv[])
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
|
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
|
||||||
if (pindex) {
|
if (pindex) {
|
||||||
UpdateUncommittedBlockStructures(block, pindex, chainparams.GetConsensus());
|
chainman.UpdateUncommittedBlockStructures(block, pindex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ int main(int argc, char* argv[])
|
||||||
bool new_block;
|
bool new_block;
|
||||||
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
||||||
RegisterSharedValidationInterface(sc);
|
RegisterSharedValidationInterface(sc);
|
||||||
bool accepted = chainman.ProcessNewBlock(chainparams, blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
|
bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
|
||||||
UnregisterSharedValidationInterface(sc);
|
UnregisterSharedValidationInterface(sc);
|
||||||
if (!new_block && accepted) {
|
if (!new_block && accepted) {
|
||||||
std::cerr << "duplicate" << std::endl;
|
std::cerr << "duplicate" << std::endl;
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
VersionBitsCache g_versionbitscache;
|
|
||||||
|
|
||||||
/* Basic sanity checking for BuriedDeployment/DeploymentPos enums and
|
/* Basic sanity checking for BuriedDeployment/DeploymentPos enums and
|
||||||
* ValidDeployment check */
|
* ValidDeployment check */
|
||||||
|
|
||||||
|
|
|
@ -10,33 +10,30 @@
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
/** Global cache for versionbits deployment status */
|
|
||||||
extern VersionBitsCache g_versionbitscache;
|
|
||||||
|
|
||||||
/** Determine if a deployment is active for the next block */
|
/** Determine if a deployment is active for the next block */
|
||||||
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep)
|
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache& versionbitscache)
|
||||||
{
|
{
|
||||||
assert(Consensus::ValidDeployment(dep));
|
assert(Consensus::ValidDeployment(dep));
|
||||||
return (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1) >= params.DeploymentHeight(dep);
|
return (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1) >= params.DeploymentHeight(dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep)
|
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep, VersionBitsCache& versionbitscache)
|
||||||
{
|
{
|
||||||
assert(Consensus::ValidDeployment(dep));
|
assert(Consensus::ValidDeployment(dep));
|
||||||
return ThresholdState::ACTIVE == g_versionbitscache.State(pindexPrev, params, dep);
|
return ThresholdState::ACTIVE == versionbitscache.State(pindexPrev, params, dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determine if a deployment is active for this block */
|
/** Determine if a deployment is active for this block */
|
||||||
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep)
|
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache& versionbitscache)
|
||||||
{
|
{
|
||||||
assert(Consensus::ValidDeployment(dep));
|
assert(Consensus::ValidDeployment(dep));
|
||||||
return index.nHeight >= params.DeploymentHeight(dep);
|
return index.nHeight >= params.DeploymentHeight(dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::DeploymentPos dep)
|
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::DeploymentPos dep, VersionBitsCache& versionbitscache)
|
||||||
{
|
{
|
||||||
assert(Consensus::ValidDeployment(dep));
|
assert(Consensus::ValidDeployment(dep));
|
||||||
return DeploymentActiveAfter(index.pprev, params, dep);
|
return DeploymentActiveAfter(index.pprev, params, dep, versionbitscache);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determine if a deployment is enabled (can ever be active) */
|
/** Determine if a deployment is enabled (can ever be active) */
|
||||||
|
|
|
@ -1424,7 +1424,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) {
|
for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) {
|
||||||
node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), mempool_check_ratio);
|
node.mempool = std::make_unique<CTxMemPool>(node.fee_estimator.get(), mempool_check_ratio);
|
||||||
|
|
||||||
node.chainman = std::make_unique<ChainstateManager>();
|
node.chainman = std::make_unique<ChainstateManager>(chainparams);
|
||||||
ChainstateManager& chainman = *node.chainman;
|
ChainstateManager& chainman = *node.chainman;
|
||||||
|
|
||||||
const bool fReset = fReindex;
|
const bool fReset = fReindex;
|
||||||
|
|
|
@ -1110,7 +1110,6 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
|
||||||
if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
|
if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Consensus::Params& consensusParams = m_chainparams.GetConsensus();
|
|
||||||
std::vector<const CBlockIndex*> vToFetch;
|
std::vector<const CBlockIndex*> vToFetch;
|
||||||
const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
|
const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
|
||||||
// Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
|
// Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
|
||||||
|
@ -1140,7 +1139,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
|
||||||
// We consider the chain that this peer is on invalid.
|
// We consider the chain that this peer is on invalid.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
|
if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||||
// We wouldn't download this block or its descendants from this peer.
|
// We wouldn't download this block or its descendants from this peer.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1641,7 +1640,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
|
||||||
return;
|
return;
|
||||||
m_highest_fast_announce = pindex->nHeight;
|
m_highest_fast_announce = pindex->nHeight;
|
||||||
|
|
||||||
bool fWitnessEnabled = DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT);
|
bool fWitnessEnabled = DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT);
|
||||||
uint256 hashBlock(pblock->GetHash());
|
uint256 hashBlock(pblock->GetHash());
|
||||||
const std::shared_future<CSerializedNetMsg> lazy_ser{
|
const std::shared_future<CSerializedNetMsg> lazy_ser{
|
||||||
std::async(std::launch::deferred, [&] { return msgMaker.Make(NetMsgType::CMPCTBLOCK, *pcmpctblock); })};
|
std::async(std::launch::deferred, [&] { return msgMaker.Make(NetMsgType::CMPCTBLOCK, *pcmpctblock); })};
|
||||||
|
@ -2214,7 +2213,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
if (!m_chainman.ProcessNewBlockHeaders(headers, state, m_chainparams, &pindexLast)) {
|
if (!m_chainman.ProcessNewBlockHeaders(headers, state, &pindexLast)) {
|
||||||
if (state.IsInvalid()) {
|
if (state.IsInvalid()) {
|
||||||
MaybePunishNodeForBlock(pfrom.GetId(), state, via_compact_block, "invalid header received");
|
MaybePunishNodeForBlock(pfrom.GetId(), state, via_compact_block, "invalid header received");
|
||||||
return;
|
return;
|
||||||
|
@ -2258,7 +2257,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||||
while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||||
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
|
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
|
||||||
!IsBlockRequested(pindexWalk->GetBlockHash()) &&
|
!IsBlockRequested(pindexWalk->GetBlockHash()) &&
|
||||||
(!DeploymentActiveAt(*pindexWalk, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
|
(!DeploymentActiveAt(*pindexWalk, m_chainman, Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
|
||||||
// We don't have this block, and it's not yet in flight.
|
// We don't have this block, and it's not yet in flight.
|
||||||
vToFetch.push_back(pindexWalk);
|
vToFetch.push_back(pindexWalk);
|
||||||
}
|
}
|
||||||
|
@ -2591,7 +2590,7 @@ void PeerManagerImpl::ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv)
|
||||||
void PeerManagerImpl::ProcessBlock(CNode& node, const std::shared_ptr<const CBlock>& block, bool force_processing)
|
void PeerManagerImpl::ProcessBlock(CNode& node, const std::shared_ptr<const CBlock>& block, bool force_processing)
|
||||||
{
|
{
|
||||||
bool new_block{false};
|
bool new_block{false};
|
||||||
m_chainman.ProcessNewBlock(m_chainparams, block, force_processing, &new_block);
|
m_chainman.ProcessNewBlock(block, force_processing, &new_block);
|
||||||
if (new_block) {
|
if (new_block) {
|
||||||
node.m_last_block_time = GetTime<std::chrono::seconds>();
|
node.m_last_block_time = GetTime<std::chrono::seconds>();
|
||||||
} else {
|
} else {
|
||||||
|
@ -3569,7 +3568,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
|
|
||||||
const CBlockIndex *pindex = nullptr;
|
const CBlockIndex *pindex = nullptr;
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
if (!m_chainman.ProcessNewBlockHeaders({cmpctblock.header}, state, m_chainparams, &pindex)) {
|
if (!m_chainman.ProcessNewBlockHeaders({cmpctblock.header}, state, &pindex)) {
|
||||||
if (state.IsInvalid()) {
|
if (state.IsInvalid()) {
|
||||||
MaybePunishNodeForBlock(pfrom.GetId(), state, /*via_compact_block=*/true, "invalid header via cmpctblock");
|
MaybePunishNodeForBlock(pfrom.GetId(), state, /*via_compact_block=*/true, "invalid header via cmpctblock");
|
||||||
return;
|
return;
|
||||||
|
@ -3629,7 +3628,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) && !nodestate->fSupportsDesiredCmpctVersion) {
|
if (DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT) && !nodestate->fSupportsDesiredCmpctVersion) {
|
||||||
// Don't bother trying to process compact blocks from v1 peers
|
// Don't bother trying to process compact blocks from v1 peers
|
||||||
// after segwit activates.
|
// after segwit activates.
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -51,7 +51,7 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman)
|
||||||
block.vtx.at(0) = MakeTransactionRef(tx);
|
block.vtx.at(0) = MakeTransactionRef(tx);
|
||||||
|
|
||||||
const CBlockIndex* prev_block = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock));
|
const CBlockIndex* prev_block = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock));
|
||||||
GenerateCoinbaseCommitment(block, prev_block, Params().GetConsensus());
|
chainman.GenerateCoinbaseCommitment(block, prev_block);
|
||||||
|
|
||||||
block.hashMerkleRoot = BlockMerkleRoot(block);
|
block.hashMerkleRoot = BlockMerkleRoot(block);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||||
assert(pindexPrev != nullptr);
|
assert(pindexPrev != nullptr);
|
||||||
nHeight = pindexPrev->nHeight + 1;
|
nHeight = pindexPrev->nHeight + 1;
|
||||||
|
|
||||||
pblock->nVersion = g_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
|
pblock->nVersion = m_chainstate.m_chainman.m_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
|
||||||
// -regtest only: allow overriding block.nVersion with
|
// -regtest only: allow overriding block.nVersion with
|
||||||
// -blockversion=N to test forking scenarios
|
// -blockversion=N to test forking scenarios
|
||||||
if (chainparams.MineBlocksOnDemand()) {
|
if (chainparams.MineBlocksOnDemand()) {
|
||||||
|
@ -154,7 +154,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||||
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
|
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
|
||||||
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
||||||
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
|
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
|
||||||
pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
|
pblocktemplate->vchCoinbaseCommitment = m_chainstate.m_chainman.GenerateCoinbaseCommitment(*pblock, pindexPrev);
|
||||||
pblocktemplate->vTxFees[0] = -nFees;
|
pblocktemplate->vTxFees[0] = -nFees;
|
||||||
|
|
||||||
LogPrintf("CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops %d\n", GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost);
|
LogPrintf("CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops %d\n", GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost);
|
||||||
|
|
|
@ -1064,26 +1064,26 @@ static RPCHelpMan verifychain()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const Consensus::Params& params, Consensus::BuriedDeployment dep)
|
static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const ChainstateManager& chainman, Consensus::BuriedDeployment dep)
|
||||||
{
|
{
|
||||||
// For buried deployments.
|
// For buried deployments.
|
||||||
|
|
||||||
if (!DeploymentEnabled(params, dep)) return;
|
if (!DeploymentEnabled(chainman, dep)) return;
|
||||||
|
|
||||||
UniValue rv(UniValue::VOBJ);
|
UniValue rv(UniValue::VOBJ);
|
||||||
rv.pushKV("type", "buried");
|
rv.pushKV("type", "buried");
|
||||||
// getdeploymentinfo reports the softfork as active from when the chain height is
|
// getdeploymentinfo reports the softfork as active from when the chain height is
|
||||||
// one below the activation height
|
// one below the activation height
|
||||||
rv.pushKV("active", DeploymentActiveAfter(blockindex, params, dep));
|
rv.pushKV("active", DeploymentActiveAfter(blockindex, chainman, dep));
|
||||||
rv.pushKV("height", params.DeploymentHeight(dep));
|
rv.pushKV("height", chainman.GetConsensus().DeploymentHeight(dep));
|
||||||
softforks.pushKV(DeploymentName(dep), rv);
|
softforks.pushKV(DeploymentName(dep), rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
|
static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const ChainstateManager& chainman, Consensus::DeploymentPos id)
|
||||||
{
|
{
|
||||||
// For BIP9 deployments.
|
// For BIP9 deployments.
|
||||||
|
|
||||||
if (!DeploymentEnabled(consensusParams, id)) return;
|
if (!DeploymentEnabled(chainman, id)) return;
|
||||||
if (blockindex == nullptr) return;
|
if (blockindex == nullptr) return;
|
||||||
|
|
||||||
auto get_state_name = [](const ThresholdState state) -> std::string {
|
auto get_state_name = [](const ThresholdState state) -> std::string {
|
||||||
|
@ -1099,29 +1099,29 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
|
||||||
|
|
||||||
UniValue bip9(UniValue::VOBJ);
|
UniValue bip9(UniValue::VOBJ);
|
||||||
|
|
||||||
const ThresholdState next_state = g_versionbitscache.State(blockindex, consensusParams, id);
|
const ThresholdState next_state = chainman.m_versionbitscache.State(blockindex, chainman.GetConsensus(), id);
|
||||||
const ThresholdState current_state = g_versionbitscache.State(blockindex->pprev, consensusParams, id);
|
const ThresholdState current_state = chainman.m_versionbitscache.State(blockindex->pprev, chainman.GetConsensus(), id);
|
||||||
|
|
||||||
const bool has_signal = (ThresholdState::STARTED == current_state || ThresholdState::LOCKED_IN == current_state);
|
const bool has_signal = (ThresholdState::STARTED == current_state || ThresholdState::LOCKED_IN == current_state);
|
||||||
|
|
||||||
// BIP9 parameters
|
// BIP9 parameters
|
||||||
if (has_signal) {
|
if (has_signal) {
|
||||||
bip9.pushKV("bit", consensusParams.vDeployments[id].bit);
|
bip9.pushKV("bit", chainman.GetConsensus().vDeployments[id].bit);
|
||||||
}
|
}
|
||||||
bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
|
bip9.pushKV("start_time", chainman.GetConsensus().vDeployments[id].nStartTime);
|
||||||
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
|
bip9.pushKV("timeout", chainman.GetConsensus().vDeployments[id].nTimeout);
|
||||||
bip9.pushKV("min_activation_height", consensusParams.vDeployments[id].min_activation_height);
|
bip9.pushKV("min_activation_height", chainman.GetConsensus().vDeployments[id].min_activation_height);
|
||||||
|
|
||||||
// BIP9 status
|
// BIP9 status
|
||||||
bip9.pushKV("status", get_state_name(current_state));
|
bip9.pushKV("status", get_state_name(current_state));
|
||||||
bip9.pushKV("since", g_versionbitscache.StateSinceHeight(blockindex->pprev, consensusParams, id));
|
bip9.pushKV("since", chainman.m_versionbitscache.StateSinceHeight(blockindex->pprev, chainman.GetConsensus(), id));
|
||||||
bip9.pushKV("status_next", get_state_name(next_state));
|
bip9.pushKV("status_next", get_state_name(next_state));
|
||||||
|
|
||||||
// BIP9 signalling status, if applicable
|
// BIP9 signalling status, if applicable
|
||||||
if (has_signal) {
|
if (has_signal) {
|
||||||
UniValue statsUV(UniValue::VOBJ);
|
UniValue statsUV(UniValue::VOBJ);
|
||||||
std::vector<bool> signals;
|
std::vector<bool> signals;
|
||||||
BIP9Stats statsStruct = g_versionbitscache.Statistics(blockindex, consensusParams, id, &signals);
|
BIP9Stats statsStruct = chainman.m_versionbitscache.Statistics(blockindex, chainman.GetConsensus(), id, &signals);
|
||||||
statsUV.pushKV("period", statsStruct.period);
|
statsUV.pushKV("period", statsStruct.period);
|
||||||
statsUV.pushKV("elapsed", statsStruct.elapsed);
|
statsUV.pushKV("elapsed", statsStruct.elapsed);
|
||||||
statsUV.pushKV("count", statsStruct.count);
|
statsUV.pushKV("count", statsStruct.count);
|
||||||
|
@ -1142,7 +1142,7 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
|
||||||
UniValue rv(UniValue::VOBJ);
|
UniValue rv(UniValue::VOBJ);
|
||||||
rv.pushKV("type", "bip9");
|
rv.pushKV("type", "bip9");
|
||||||
if (ThresholdState::ACTIVE == next_state) {
|
if (ThresholdState::ACTIVE == next_state) {
|
||||||
rv.pushKV("height", g_versionbitscache.StateSinceHeight(blockindex, consensusParams, id));
|
rv.pushKV("height", chainman.m_versionbitscache.StateSinceHeight(blockindex, chainman.GetConsensus(), id));
|
||||||
}
|
}
|
||||||
rv.pushKV("active", ThresholdState::ACTIVE == next_state);
|
rv.pushKV("active", ThresholdState::ACTIVE == next_state);
|
||||||
rv.pushKV("bip9", bip9);
|
rv.pushKV("bip9", bip9);
|
||||||
|
@ -1152,7 +1152,7 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/* TODO: when -deprecatedrpc=softforks is removed, drop these */
|
/* TODO: when -deprecatedrpc=softforks is removed, drop these */
|
||||||
UniValue DeploymentInfo(const CBlockIndex* tip, const Consensus::Params& consensusParams);
|
UniValue DeploymentInfo(const CBlockIndex* tip, const ChainstateManager& chainman);
|
||||||
extern const std::vector<RPCResult> RPCHelpForDeployment;
|
extern const std::vector<RPCResult> RPCHelpForDeployment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1227,8 +1227,7 @@ RPCHelpMan getblockchaininfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDeprecatedRPCEnabled("softforks")) {
|
if (IsDeprecatedRPCEnabled("softforks")) {
|
||||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
obj.pushKV("softforks", DeploymentInfo(&tip, chainman));
|
||||||
obj.pushKV("softforks", DeploymentInfo(&tip, consensusParams));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.pushKV("warnings", GetWarnings(false).original);
|
obj.pushKV("warnings", GetWarnings(false).original);
|
||||||
|
@ -1263,16 +1262,16 @@ const std::vector<RPCResult> RPCHelpForDeployment{
|
||||||
}},
|
}},
|
||||||
};
|
};
|
||||||
|
|
||||||
UniValue DeploymentInfo(const CBlockIndex* blockindex, const Consensus::Params& consensusParams)
|
UniValue DeploymentInfo(const CBlockIndex* blockindex, const ChainstateManager& chainman)
|
||||||
{
|
{
|
||||||
UniValue softforks(UniValue::VOBJ);
|
UniValue softforks(UniValue::VOBJ);
|
||||||
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB);
|
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_HEIGHTINCB);
|
||||||
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_DERSIG);
|
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_DERSIG);
|
||||||
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_CLTV);
|
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_CLTV);
|
||||||
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_CSV);
|
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_CSV);
|
||||||
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_SEGWIT);
|
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_SEGWIT);
|
||||||
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
|
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TESTDUMMY);
|
||||||
SoftForkDescPushBack(blockindex, softforks, consensusParams, Consensus::DEPLOYMENT_TAPROOT);
|
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TAPROOT);
|
||||||
return softforks;
|
return softforks;
|
||||||
}
|
}
|
||||||
} // anon namespace
|
} // anon namespace
|
||||||
|
@ -1311,12 +1310,10 @@ static RPCHelpMan getdeploymentinfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
|
||||||
|
|
||||||
UniValue deploymentinfo(UniValue::VOBJ);
|
UniValue deploymentinfo(UniValue::VOBJ);
|
||||||
deploymentinfo.pushKV("hash", blockindex->GetBlockHash().ToString());
|
deploymentinfo.pushKV("hash", blockindex->GetBlockHash().ToString());
|
||||||
deploymentinfo.pushKV("height", blockindex->nHeight);
|
deploymentinfo.pushKV("height", blockindex->nHeight);
|
||||||
deploymentinfo.pushKV("deployments", DeploymentInfo(blockindex, consensusParams));
|
deploymentinfo.pushKV("deployments", DeploymentInfo(blockindex, chainman));
|
||||||
return deploymentinfo;
|
return deploymentinfo;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -133,7 +133,7 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t&
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
|
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
|
||||||
if (!chainman.ProcessNewBlock(chainparams, shared_pblock, true, nullptr)) {
|
if (!chainman.ProcessNewBlock(shared_pblock, true, nullptr)) {
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,7 +770,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
pblock->nNonce = 0;
|
pblock->nNonce = 0;
|
||||||
|
|
||||||
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
|
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
|
||||||
const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT);
|
const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_SEGWIT);
|
||||||
|
|
||||||
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
|
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
|
||||||
|
|
||||||
|
@ -836,7 +836,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
UniValue vbavailable(UniValue::VOBJ);
|
UniValue vbavailable(UniValue::VOBJ);
|
||||||
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
|
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
|
||||||
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
|
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
|
||||||
ThresholdState state = g_versionbitscache.State(pindexPrev, consensusParams, pos);
|
ThresholdState state = chainman.m_versionbitscache.State(pindexPrev, consensusParams, pos);
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ThresholdState::DEFINED:
|
case ThresholdState::DEFINED:
|
||||||
case ThresholdState::FAILED:
|
case ThresholdState::FAILED:
|
||||||
|
@ -844,7 +844,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
break;
|
break;
|
||||||
case ThresholdState::LOCKED_IN:
|
case ThresholdState::LOCKED_IN:
|
||||||
// Ensure bit is set in block version
|
// Ensure bit is set in block version
|
||||||
pblock->nVersion |= g_versionbitscache.Mask(consensusParams, pos);
|
pblock->nVersion |= chainman.m_versionbitscache.Mask(consensusParams, pos);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ThresholdState::STARTED:
|
case ThresholdState::STARTED:
|
||||||
{
|
{
|
||||||
|
@ -853,7 +853,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
|
if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
|
||||||
if (!vbinfo.gbt_force) {
|
if (!vbinfo.gbt_force) {
|
||||||
// If the client doesn't support this, don't indicate it in the [default] version
|
// If the client doesn't support this, don't indicate it in the [default] version
|
||||||
pblock->nVersion &= ~g_versionbitscache.Mask(consensusParams, pos);
|
pblock->nVersion &= ~chainman.m_versionbitscache.Mask(consensusParams, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -993,14 +993,14 @@ static RPCHelpMan submitblock()
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
|
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
|
||||||
if (pindex) {
|
if (pindex) {
|
||||||
UpdateUncommittedBlockStructures(block, pindex, Params().GetConsensus());
|
chainman.UpdateUncommittedBlockStructures(block, pindex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool new_block;
|
bool new_block;
|
||||||
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
||||||
RegisterSharedValidationInterface(sc);
|
RegisterSharedValidationInterface(sc);
|
||||||
bool accepted = chainman.ProcessNewBlock(Params(), blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
|
bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
|
||||||
UnregisterSharedValidationInterface(sc);
|
UnregisterSharedValidationInterface(sc);
|
||||||
if (!new_block && accepted) {
|
if (!new_block && accepted) {
|
||||||
return "duplicate";
|
return "duplicate";
|
||||||
|
@ -1042,7 +1042,7 @@ static RPCHelpMan submitheader()
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
chainman.ProcessNewBlockHeaders({h}, state, Params());
|
chainman.ProcessNewBlockHeaders({h}, state);
|
||||||
if (state.IsValid()) return NullUniValue;
|
if (state.IsValid()) return NullUniValue;
|
||||||
if (state.IsError()) {
|
if (state.IsError()) {
|
||||||
throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
|
throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
|
||||||
|
|
|
@ -101,7 +101,7 @@ bool BuildChainTestingSetup::BuildChain(const CBlockIndex* pindex,
|
||||||
CBlockHeader header = block->GetBlockHeader();
|
CBlockHeader header = block->GetBlockHeader();
|
||||||
|
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
if (!Assert(m_node.chainman)->ProcessNewBlockHeaders({header}, state, Params(), &pindex)) {
|
if (!Assert(m_node.chainman)->ProcessNewBlockHeaders({header}, state, &pindex)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
|
||||||
uint256 chainA_last_header = last_header;
|
uint256 chainA_last_header = last_header;
|
||||||
for (size_t i = 0; i < 2; i++) {
|
for (size_t i = 0; i < 2; i++) {
|
||||||
const auto& block = chainA[i];
|
const auto& block = chainA[i];
|
||||||
BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
|
BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(block, true, nullptr));
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < 2; i++) {
|
for (size_t i = 0; i < 2; i++) {
|
||||||
const auto& block = chainA[i];
|
const auto& block = chainA[i];
|
||||||
|
@ -196,7 +196,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
|
||||||
uint256 chainB_last_header = last_header;
|
uint256 chainB_last_header = last_header;
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
const auto& block = chainB[i];
|
const auto& block = chainB[i];
|
||||||
BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
|
BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(block, true, nullptr));
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
const auto& block = chainB[i];
|
const auto& block = chainB[i];
|
||||||
|
@ -227,7 +227,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
|
||||||
// Reorg back to chain A.
|
// Reorg back to chain A.
|
||||||
for (size_t i = 2; i < 4; i++) {
|
for (size_t i = 2; i < 4; i++) {
|
||||||
const auto& block = chainA[i];
|
const auto& block = chainA[i];
|
||||||
BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
|
BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(block, true, nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that chain A and B blocks can be retrieved.
|
// Check that chain A and B blocks can be retrieved.
|
||||||
|
|
|
@ -58,7 +58,7 @@ FUZZ_TARGET_INIT(utxo_snapshot, initialize_chain)
|
||||||
if (fuzzed_data_provider.ConsumeBool()) {
|
if (fuzzed_data_provider.ConsumeBool()) {
|
||||||
for (const auto& block : *g_chain) {
|
for (const auto& block : *g_chain) {
|
||||||
BlockValidationState dummy;
|
BlockValidationState dummy;
|
||||||
bool processed{chainman.ProcessNewBlockHeaders({*block}, dummy, ::Params())};
|
bool processed{chainman.ProcessNewBlockHeaders({*block}, dummy)};
|
||||||
Assert(processed);
|
Assert(processed);
|
||||||
const auto* index{WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block->GetHash()))};
|
const auto* index{WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block->GetHash()))};
|
||||||
Assert(index);
|
Assert(index);
|
||||||
|
|
|
@ -587,7 +587,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
pblock->nNonce = bi.nonce;
|
pblock->nNonce = bi.nonce;
|
||||||
}
|
}
|
||||||
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
|
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
|
||||||
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(chainparams, shared_pblock, true, nullptr));
|
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, true, nullptr));
|
||||||
pblock->hashPrevBlock = pblock->GetHash();
|
pblock->hashPrevBlock = pblock->GetHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
|
||||||
assert(block->nNonce);
|
assert(block->nNonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool processed{Assert(node.chainman)->ProcessNewBlock(Params(), block, true, nullptr)};
|
bool processed{Assert(node.chainman)->ProcessNewBlock(block, true, nullptr)};
|
||||||
assert(processed);
|
assert(processed);
|
||||||
|
|
||||||
return CTxIn{block->vtx[0]->GetHash(), 0};
|
return CTxIn{block->vtx[0]->GetHash(), 0};
|
||||||
|
|
|
@ -151,6 +151,8 @@ BasicTestingSetup::~BasicTestingSetup()
|
||||||
ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::vector<const char*>& extra_args)
|
ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::vector<const char*>& extra_args)
|
||||||
: BasicTestingSetup(chainName, extra_args)
|
: BasicTestingSetup(chainName, extra_args)
|
||||||
{
|
{
|
||||||
|
const CChainParams& chainparams = Params();
|
||||||
|
|
||||||
// We have to run a scheduler thread to prevent ActivateBestChain
|
// We have to run a scheduler thread to prevent ActivateBestChain
|
||||||
// from blocking due to queue overrun.
|
// from blocking due to queue overrun.
|
||||||
m_node.scheduler = std::make_unique<CScheduler>();
|
m_node.scheduler = std::make_unique<CScheduler>();
|
||||||
|
@ -162,7 +164,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
|
||||||
|
|
||||||
m_cache_sizes = CalculateCacheSizes(m_args);
|
m_cache_sizes = CalculateCacheSizes(m_args);
|
||||||
|
|
||||||
m_node.chainman = std::make_unique<ChainstateManager>();
|
m_node.chainman = std::make_unique<ChainstateManager>(chainparams);
|
||||||
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(m_cache_sizes.block_tree_db, true);
|
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(m_cache_sizes.block_tree_db, true);
|
||||||
|
|
||||||
// Start script-checking threads. Set g_parallel_script_checks to true so they are used.
|
// Start script-checking threads. Set g_parallel_script_checks to true so they are used.
|
||||||
|
@ -298,10 +300,9 @@ CBlock TestChain100Setup::CreateAndProcessBlock(
|
||||||
chainstate = &Assert(m_node.chainman)->ActiveChainstate();
|
chainstate = &Assert(m_node.chainman)->ActiveChainstate();
|
||||||
}
|
}
|
||||||
|
|
||||||
const CChainParams& chainparams = Params();
|
|
||||||
const CBlock block = this->CreateBlock(txns, scriptPubKey, *chainstate);
|
const CBlock block = this->CreateBlock(txns, scriptPubKey, *chainstate);
|
||||||
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
|
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
|
||||||
Assert(m_node.chainman)->ProcessNewBlock(chainparams, shared_pblock, true, nullptr);
|
Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, true, nullptr);
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
|
||||||
std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock> pblock)
|
std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock> pblock)
|
||||||
{
|
{
|
||||||
const CBlockIndex* prev_block{WITH_LOCK(::cs_main, return m_node.chainman->m_blockman.LookupBlockIndex(pblock->hashPrevBlock))};
|
const CBlockIndex* prev_block{WITH_LOCK(::cs_main, return m_node.chainman->m_blockman.LookupBlockIndex(pblock->hashPrevBlock))};
|
||||||
GenerateCoinbaseCommitment(*pblock, prev_block, Params().GetConsensus());
|
m_node.chainman->GenerateCoinbaseCommitment(*pblock, prev_block);
|
||||||
|
|
||||||
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock>
|
||||||
// submit block header, so that miner can get the block height from the
|
// submit block header, so that miner can get the block height from the
|
||||||
// global state and the node has the topology of the chain
|
// global state and the node has the topology of the chain
|
||||||
BlockValidationState ignored;
|
BlockValidationState ignored;
|
||||||
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlockHeaders({pblock->GetBlockHeader()}, ignored, Params()));
|
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlockHeaders({pblock->GetBlockHeader()}, ignored));
|
||||||
|
|
||||||
return pblock;
|
return pblock;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
|
||||||
|
|
||||||
bool ignored;
|
bool ignored;
|
||||||
// Connect the genesis block and drain any outstanding events
|
// Connect the genesis block and drain any outstanding events
|
||||||
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
|
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
|
||||||
SyncWithValidationInterfaceQueue();
|
SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
// subscribe to events (this subscriber will validate event ordering)
|
// subscribe to events (this subscriber will validate event ordering)
|
||||||
|
@ -179,13 +179,13 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
|
||||||
FastRandomContext insecure;
|
FastRandomContext insecure;
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
auto block = blocks[insecure.randrange(blocks.size() - 1)];
|
auto block = blocks[insecure.randrange(blocks.size() - 1)];
|
||||||
Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, &ignored);
|
Assert(m_node.chainman)->ProcessNewBlock(block, true, &ignored);
|
||||||
}
|
}
|
||||||
|
|
||||||
// to make sure that eventually we process the full chain - do it here
|
// to make sure that eventually we process the full chain - do it here
|
||||||
for (auto block : blocks) {
|
for (auto block : blocks) {
|
||||||
if (block->vtx.size() == 1) {
|
if (block->vtx.size() == 1) {
|
||||||
bool processed = Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, &ignored);
|
bool processed = Assert(m_node.chainman)->ProcessNewBlock(block, true, &ignored);
|
||||||
assert(processed);
|
assert(processed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
|
||||||
{
|
{
|
||||||
bool ignored;
|
bool ignored;
|
||||||
auto ProcessBlock = [&](std::shared_ptr<const CBlock> block) -> bool {
|
auto ProcessBlock = [&](std::shared_ptr<const CBlock> block) -> bool {
|
||||||
return Assert(m_node.chainman)->ProcessNewBlock(Params(), block, /*force_processing=*/true, /*new_block=*/&ignored);
|
return Assert(m_node.chainman)->ProcessNewBlock(block, /*force_processing=*/true, /*new_block=*/&ignored);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process all mined blocks
|
// Process all mined blocks
|
||||||
|
|
|
@ -22,7 +22,8 @@ BOOST_FIXTURE_TEST_SUITE(validation_chainstate_tests, TestingSetup)
|
||||||
//!
|
//!
|
||||||
BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
|
BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
|
||||||
{
|
{
|
||||||
ChainstateManager manager;
|
const CChainParams& chainparams = Params();
|
||||||
|
ChainstateManager manager(chainparams);
|
||||||
WITH_LOCK(::cs_main, manager.m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(1 << 20, true));
|
WITH_LOCK(::cs_main, manager.m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(1 << 20, true));
|
||||||
CTxMemPool mempool;
|
CTxMemPool mempool;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <consensus/params.h>
|
#include <consensus/params.h>
|
||||||
#include <deploymentstatus.h>
|
|
||||||
#include <test/util/setup_common.h>
|
#include <test/util/setup_common.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
#include <versionbits.h>
|
#include <versionbits.h>
|
||||||
|
@ -257,10 +256,10 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check that ComputeBlockVersion will set the appropriate bit correctly */
|
/** Check that ComputeBlockVersion will set the appropriate bit correctly */
|
||||||
static void check_computeblockversion(const Consensus::Params& params, Consensus::DeploymentPos dep)
|
static void check_computeblockversion(VersionBitsCache& versionbitscache, const Consensus::Params& params, Consensus::DeploymentPos dep)
|
||||||
{
|
{
|
||||||
// This implicitly uses g_versionbitscache, so clear it every time
|
// Clear the cache everytime
|
||||||
g_versionbitscache.Clear();
|
versionbitscache.Clear();
|
||||||
|
|
||||||
int64_t bit = params.vDeployments[dep].bit;
|
int64_t bit = params.vDeployments[dep].bit;
|
||||||
int64_t nStartTime = params.vDeployments[dep].nStartTime;
|
int64_t nStartTime = params.vDeployments[dep].nStartTime;
|
||||||
|
@ -268,7 +267,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||||
int min_activation_height = params.vDeployments[dep].min_activation_height;
|
int min_activation_height = params.vDeployments[dep].min_activation_height;
|
||||||
|
|
||||||
// should not be any signalling for first block
|
// should not be any signalling for first block
|
||||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
|
BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
|
||||||
|
|
||||||
// always/never active deployments shouldn't need to be tested further
|
// always/never active deployments shouldn't need to be tested further
|
||||||
if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE ||
|
if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE ||
|
||||||
|
@ -288,7 +287,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||||
// Check min_activation_height is on a retarget boundary
|
// Check min_activation_height is on a retarget boundary
|
||||||
BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
|
BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
|
||||||
|
|
||||||
const uint32_t bitmask{g_versionbitscache.Mask(params, dep)};
|
const uint32_t bitmask{versionbitscache.Mask(params, dep)};
|
||||||
BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit);
|
BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit);
|
||||||
|
|
||||||
// In the first chain, test that the bit is set by CBV until it has failed.
|
// In the first chain, test that the bit is set by CBV until it has failed.
|
||||||
|
@ -307,9 +306,9 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||||
// earlier time, so will transition from DEFINED to STARTED at the
|
// earlier time, so will transition from DEFINED to STARTED at the
|
||||||
// end of the first period by mining blocks at nTime == 0
|
// end of the first period by mining blocks at nTime == 0
|
||||||
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
||||||
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||||
// then we'll keep mining at nStartTime...
|
// then we'll keep mining at nStartTime...
|
||||||
} else {
|
} else {
|
||||||
// use a time 1s earlier than start time to check we stay DEFINED
|
// use a time 1s earlier than start time to check we stay DEFINED
|
||||||
|
@ -317,28 +316,28 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||||
|
|
||||||
// Start generating blocks before nStartTime
|
// Start generating blocks before nStartTime
|
||||||
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
||||||
|
|
||||||
// Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
|
// Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
|
||||||
for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
|
for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
|
||||||
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
||||||
}
|
}
|
||||||
// Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
|
// Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
|
||||||
// CBV should still not yet set the bit.
|
// CBV should still not yet set the bit.
|
||||||
nTime = nStartTime;
|
nTime = nStartTime;
|
||||||
for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
|
for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
|
||||||
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
||||||
}
|
}
|
||||||
// Next we will advance to the next period and transition to STARTED,
|
// Next we will advance to the next period and transition to STARTED,
|
||||||
}
|
}
|
||||||
|
|
||||||
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
// so ComputeBlockVersion should now set the bit,
|
// so ComputeBlockVersion should now set the bit,
|
||||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||||
// and should also be using the VERSIONBITS_TOP_BITS.
|
// and should also be using the VERSIONBITS_TOP_BITS.
|
||||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
|
BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
|
||||||
|
|
||||||
// Check that ComputeBlockVersion will set the bit until nTimeout
|
// Check that ComputeBlockVersion will set the bit until nTimeout
|
||||||
nTime += 600;
|
nTime += 600;
|
||||||
|
@ -347,8 +346,8 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||||
// These blocks are all before nTimeout is reached.
|
// These blocks are all before nTimeout is reached.
|
||||||
while (nTime < nTimeout && blocksToMine > 0) {
|
while (nTime < nTimeout && blocksToMine > 0) {
|
||||||
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
|
BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
|
||||||
blocksToMine--;
|
blocksToMine--;
|
||||||
nTime += 600;
|
nTime += 600;
|
||||||
nHeight += 1;
|
nHeight += 1;
|
||||||
|
@ -362,7 +361,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||||
// finish the last period before we start timing out
|
// finish the last period before we start timing out
|
||||||
while (nHeight % params.nMinerConfirmationWindow != 0) {
|
while (nHeight % params.nMinerConfirmationWindow != 0) {
|
||||||
lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||||
nHeight += 1;
|
nHeight += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,12 +369,12 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||||
// the bit until the period transition.
|
// the bit until the period transition.
|
||||||
for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
|
for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
|
||||||
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||||
nHeight += 1;
|
nHeight += 1;
|
||||||
}
|
}
|
||||||
// The next block should trigger no longer setting the bit.
|
// The next block should trigger no longer setting the bit.
|
||||||
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// On a new chain:
|
// On a new chain:
|
||||||
|
@ -386,34 +385,36 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||||
// Mine one period worth of blocks, and check that the bit will be on for the
|
// Mine one period worth of blocks, and check that the bit will be on for the
|
||||||
// next period.
|
// next period.
|
||||||
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||||
|
|
||||||
// Mine another period worth of blocks, signaling the new bit.
|
// Mine another period worth of blocks, signaling the new bit.
|
||||||
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
|
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
|
||||||
// After one period of setting the bit on each block, it should have locked in.
|
// After one period of setting the bit on each block, it should have locked in.
|
||||||
// We keep setting the bit for one more period though, until activation.
|
// We keep setting the bit for one more period though, until activation.
|
||||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||||
|
|
||||||
// Now check that we keep mining the block until the end of this period, and
|
// Now check that we keep mining the block until the end of this period, and
|
||||||
// then stop at the beginning of the next period.
|
// then stop at the beginning of the next period.
|
||||||
lastBlock = secondChain.Mine((params.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = secondChain.Mine((params.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||||
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
|
|
||||||
if (lastBlock->nHeight + 1 < min_activation_height) {
|
if (lastBlock->nHeight + 1 < min_activation_height) {
|
||||||
// check signalling continues while min_activation_height is not reached
|
// check signalling continues while min_activation_height is not reached
|
||||||
lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||||
// then reach min_activation_height, which was already REQUIRE'd to start a new period
|
// then reach min_activation_height, which was already REQUIRE'd to start a new period
|
||||||
lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that we don't signal after activation
|
// Check that we don't signal after activation
|
||||||
BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||||
{
|
{
|
||||||
|
VersionBitsCache vbcache; // don't use chainman versionbitscache since we want custom chain params
|
||||||
|
|
||||||
// check that any deployment on any chain can conceivably reach both
|
// check that any deployment on any chain can conceivably reach both
|
||||||
// ACTIVE and FAILED states in roughly the way we expect
|
// ACTIVE and FAILED states in roughly the way we expect
|
||||||
for (const auto& chain_name : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET, CBaseChainParams::REGTEST}) {
|
for (const auto& chain_name : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET, CBaseChainParams::REGTEST}) {
|
||||||
|
@ -426,10 +427,10 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||||
// not take precedence over STARTED/LOCKED_IN. So all softforks on
|
// not take precedence over STARTED/LOCKED_IN. So all softforks on
|
||||||
// the same bit might overlap, even when non-overlapping start-end
|
// the same bit might overlap, even when non-overlapping start-end
|
||||||
// times are picked.
|
// times are picked.
|
||||||
const uint32_t dep_mask{g_versionbitscache.Mask(chainParams->GetConsensus(), dep)};
|
const uint32_t dep_mask{vbcache.Mask(chainParams->GetConsensus(), dep)};
|
||||||
BOOST_CHECK(!(chain_all_vbits & dep_mask));
|
BOOST_CHECK(!(chain_all_vbits & dep_mask));
|
||||||
chain_all_vbits |= dep_mask;
|
chain_all_vbits |= dep_mask;
|
||||||
check_computeblockversion(chainParams->GetConsensus(), dep);
|
check_computeblockversion(vbcache, chainParams->GetConsensus(), dep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,7 +440,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||||
ArgsManager args;
|
ArgsManager args;
|
||||||
args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008
|
args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008
|
||||||
const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
|
const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
|
||||||
check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
|
check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -449,7 +450,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||||
ArgsManager args;
|
ArgsManager args;
|
||||||
args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200
|
args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200
|
||||||
const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
|
const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
|
||||||
check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
|
check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <consensus/tx_verify.h>
|
#include <consensus/tx_verify.h>
|
||||||
#include <consensus/validation.h>
|
#include <consensus/validation.h>
|
||||||
#include <cuckoocache.h>
|
#include <cuckoocache.h>
|
||||||
#include <deploymentstatus.h>
|
|
||||||
#include <flatfile.h>
|
#include <flatfile.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
@ -262,7 +261,7 @@ bool CheckSequenceLocksAtTip(CBlockIndex* tip,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the script flags which should be checked for a given block
|
// Returns the script flags which should be checked for a given block
|
||||||
static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Consensus::Params& chainparams);
|
static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const ChainstateManager& chainman);
|
||||||
|
|
||||||
static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, size_t limit, std::chrono::seconds age)
|
static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, size_t limit, std::chrono::seconds age)
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs)
|
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs)
|
||||||
|
@ -1027,7 +1026,6 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws)
|
||||||
const CTransaction& tx = *ws.m_ptx;
|
const CTransaction& tx = *ws.m_ptx;
|
||||||
const uint256& hash = ws.m_hash;
|
const uint256& hash = ws.m_hash;
|
||||||
TxValidationState& state = ws.m_state;
|
TxValidationState& state = ws.m_state;
|
||||||
const CChainParams& chainparams = args.m_chainparams;
|
|
||||||
|
|
||||||
// Check again against the current block tip's script verification
|
// Check again against the current block tip's script verification
|
||||||
// flags to cache our script execution flags. This is, of course,
|
// flags to cache our script execution flags. This is, of course,
|
||||||
|
@ -1044,7 +1042,7 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws)
|
||||||
// There is a similar check in CreateNewBlock() to prevent creating
|
// There is a similar check in CreateNewBlock() to prevent creating
|
||||||
// invalid blocks (using TestBlockValidity), however allowing such
|
// invalid blocks (using TestBlockValidity), however allowing such
|
||||||
// transactions into the mempool can be exploited as a DoS attack.
|
// transactions into the mempool can be exploited as a DoS attack.
|
||||||
unsigned int currentBlockScriptVerifyFlags{GetBlockScriptFlags(*m_active_chainstate.m_chain.Tip(), chainparams.GetConsensus())};
|
unsigned int currentBlockScriptVerifyFlags{GetBlockScriptFlags(*m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman)};
|
||||||
if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags,
|
if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags,
|
||||||
ws.m_precomputed_txdata, m_active_chainstate.CoinsTip())) {
|
ws.m_precomputed_txdata, m_active_chainstate.CoinsTip())) {
|
||||||
LogPrintf("BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s\n", hash.ToString(), state.ToString());
|
LogPrintf("BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s\n", hash.ToString(), state.ToString());
|
||||||
|
@ -1457,7 +1455,7 @@ PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTx
|
||||||
assert(std::all_of(package.cbegin(), package.cend(), [](const auto& tx){return tx != nullptr;}));
|
assert(std::all_of(package.cbegin(), package.cend(), [](const auto& tx){return tx != nullptr;}));
|
||||||
|
|
||||||
std::vector<COutPoint> coins_to_uncache;
|
std::vector<COutPoint> coins_to_uncache;
|
||||||
const CChainParams& chainparams = Params();
|
const CChainParams& chainparams = active_chainstate.m_params;
|
||||||
const auto result = [&]() EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
|
const auto result = [&]() EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
if (test_accept) {
|
if (test_accept) {
|
||||||
|
@ -1515,7 +1513,7 @@ CChainState::CChainState(
|
||||||
std::optional<uint256> from_snapshot_blockhash)
|
std::optional<uint256> from_snapshot_blockhash)
|
||||||
: m_mempool(mempool),
|
: m_mempool(mempool),
|
||||||
m_blockman(blockman),
|
m_blockman(blockman),
|
||||||
m_params(::Params()),
|
m_params(chainman.GetParams()),
|
||||||
m_chainman(chainman),
|
m_chainman(chainman),
|
||||||
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
|
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
|
||||||
|
|
||||||
|
@ -1909,10 +1907,11 @@ void StopScriptCheckWorkerThreads()
|
||||||
class WarningBitsConditionChecker : public AbstractThresholdConditionChecker
|
class WarningBitsConditionChecker : public AbstractThresholdConditionChecker
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int bit;
|
const ChainstateManager& m_chainman;
|
||||||
|
int m_bit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WarningBitsConditionChecker(int bitIn) : bit(bitIn) {}
|
explicit WarningBitsConditionChecker(const ChainstateManager& chainman, int bit) : m_chainman{chainman}, m_bit(bit) {}
|
||||||
|
|
||||||
int64_t BeginTime(const Consensus::Params& params) const override { return 0; }
|
int64_t BeginTime(const Consensus::Params& params) const override { return 0; }
|
||||||
int64_t EndTime(const Consensus::Params& params) const override { return std::numeric_limits<int64_t>::max(); }
|
int64_t EndTime(const Consensus::Params& params) const override { return std::numeric_limits<int64_t>::max(); }
|
||||||
|
@ -1923,15 +1922,17 @@ public:
|
||||||
{
|
{
|
||||||
return pindex->nHeight >= params.MinBIP9WarningHeight &&
|
return pindex->nHeight >= params.MinBIP9WarningHeight &&
|
||||||
((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
|
((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
|
||||||
((pindex->nVersion >> bit) & 1) != 0 &&
|
((pindex->nVersion >> m_bit) & 1) != 0 &&
|
||||||
((g_versionbitscache.ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0;
|
((m_chainman.m_versionbitscache.ComputeBlockVersion(pindex->pprev, params) >> m_bit) & 1) == 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::array<ThresholdConditionCache, VERSIONBITS_NUM_BITS> warningcache GUARDED_BY(cs_main);
|
static std::array<ThresholdConditionCache, VERSIONBITS_NUM_BITS> warningcache GUARDED_BY(cs_main);
|
||||||
|
|
||||||
static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Consensus::Params& consensusparams)
|
static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const ChainstateManager& chainman)
|
||||||
{
|
{
|
||||||
|
const Consensus::Params& consensusparams = chainman.GetConsensus();
|
||||||
|
|
||||||
// BIP16 didn't become active until Apr 1 2012 (on mainnet, and
|
// BIP16 didn't become active until Apr 1 2012 (on mainnet, and
|
||||||
// retroactively applied to testnet)
|
// retroactively applied to testnet)
|
||||||
// However, only one historical block violated the P2SH rules (on both
|
// However, only one historical block violated the P2SH rules (on both
|
||||||
|
@ -1947,22 +1948,22 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Co
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce the DERSIG (BIP66) rule
|
// Enforce the DERSIG (BIP66) rule
|
||||||
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_DERSIG)) {
|
if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_DERSIG)) {
|
||||||
flags |= SCRIPT_VERIFY_DERSIG;
|
flags |= SCRIPT_VERIFY_DERSIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce CHECKLOCKTIMEVERIFY (BIP65)
|
// Enforce CHECKLOCKTIMEVERIFY (BIP65)
|
||||||
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_CLTV)) {
|
if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_CLTV)) {
|
||||||
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
|
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce CHECKSEQUENCEVERIFY (BIP112)
|
// Enforce CHECKSEQUENCEVERIFY (BIP112)
|
||||||
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_CSV)) {
|
if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_CSV)) {
|
||||||
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
|
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce BIP147 NULLDUMMY (activated simultaneously with segwit)
|
// Enforce BIP147 NULLDUMMY (activated simultaneously with segwit)
|
||||||
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_SEGWIT)) {
|
if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||||
flags |= SCRIPT_VERIFY_NULLDUMMY;
|
flags |= SCRIPT_VERIFY_NULLDUMMY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2153,12 +2154,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||||
|
|
||||||
// Enforce BIP68 (sequence locks)
|
// Enforce BIP68 (sequence locks)
|
||||||
int nLockTimeFlags = 0;
|
int nLockTimeFlags = 0;
|
||||||
if (DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_CSV)) {
|
if (DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_CSV)) {
|
||||||
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
|
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the script flags for this block
|
// Get the script flags for this block
|
||||||
unsigned int flags{GetBlockScriptFlags(*pindex, m_params.GetConsensus())};
|
unsigned int flags{GetBlockScriptFlags(*pindex, m_chainman)};
|
||||||
|
|
||||||
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
|
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
|
||||||
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
|
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
|
||||||
|
@ -2556,7 +2557,7 @@ void CChainState::UpdateTip(const CBlockIndex* pindexNew)
|
||||||
if (!this->IsInitialBlockDownload()) {
|
if (!this->IsInitialBlockDownload()) {
|
||||||
const CBlockIndex* pindex = pindexNew;
|
const CBlockIndex* pindex = pindexNew;
|
||||||
for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
|
for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
|
||||||
WarningBitsConditionChecker checker(bit);
|
WarningBitsConditionChecker checker(m_chainman, bit);
|
||||||
ThresholdState state = checker.GetStateFor(pindex, m_params.GetConsensus(), warningcache.at(bit));
|
ThresholdState state = checker.GetStateFor(pindex, m_params.GetConsensus(), warningcache.at(bit));
|
||||||
if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) {
|
if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) {
|
||||||
const bilingual_str warning = strprintf(_("Unknown new rules activated (versionbit %i)"), bit);
|
const bilingual_str warning = strprintf(_("Unknown new rules activated (versionbit %i)"), bit);
|
||||||
|
@ -3280,7 +3281,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
|
||||||
pindexNew->nDataPos = pos.nPos;
|
pindexNew->nDataPos = pos.nPos;
|
||||||
pindexNew->nUndoPos = 0;
|
pindexNew->nUndoPos = 0;
|
||||||
pindexNew->nStatus |= BLOCK_HAVE_DATA;
|
pindexNew->nStatus |= BLOCK_HAVE_DATA;
|
||||||
if (DeploymentActiveAt(*pindexNew, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
|
if (DeploymentActiveAt(*pindexNew, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||||
pindexNew->nStatus |= BLOCK_OPT_WITNESS;
|
pindexNew->nStatus |= BLOCK_OPT_WITNESS;
|
||||||
}
|
}
|
||||||
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
|
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
|
||||||
|
@ -3398,11 +3399,11 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams)
|
void ChainstateManager::UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev) const
|
||||||
{
|
{
|
||||||
int commitpos = GetWitnessCommitmentIndex(block);
|
int commitpos = GetWitnessCommitmentIndex(block);
|
||||||
static const std::vector<unsigned char> nonce(32, 0x00);
|
static const std::vector<unsigned char> nonce(32, 0x00);
|
||||||
if (commitpos != NO_WITNESS_COMMITMENT && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT) && !block.vtx[0]->HasWitness()) {
|
if (commitpos != NO_WITNESS_COMMITMENT && DeploymentActiveAfter(pindexPrev, *this, Consensus::DEPLOYMENT_SEGWIT) && !block.vtx[0]->HasWitness()) {
|
||||||
CMutableTransaction tx(*block.vtx[0]);
|
CMutableTransaction tx(*block.vtx[0]);
|
||||||
tx.vin[0].scriptWitness.stack.resize(1);
|
tx.vin[0].scriptWitness.stack.resize(1);
|
||||||
tx.vin[0].scriptWitness.stack[0] = nonce;
|
tx.vin[0].scriptWitness.stack[0] = nonce;
|
||||||
|
@ -3410,7 +3411,7 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams)
|
std::vector<unsigned char> ChainstateManager::GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev) const
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> commitment;
|
std::vector<unsigned char> commitment;
|
||||||
int commitpos = GetWitnessCommitmentIndex(block);
|
int commitpos = GetWitnessCommitmentIndex(block);
|
||||||
|
@ -3433,7 +3434,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
|
||||||
tx.vout.push_back(out);
|
tx.vout.push_back(out);
|
||||||
block.vtx[0] = MakeTransactionRef(std::move(tx));
|
block.vtx[0] = MakeTransactionRef(std::move(tx));
|
||||||
}
|
}
|
||||||
UpdateUncommittedBlockStructures(block, pindexPrev, consensusParams);
|
UpdateUncommittedBlockStructures(block, pindexPrev);
|
||||||
return commitment;
|
return commitment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3446,14 +3447,14 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
|
||||||
* in ConnectBlock().
|
* in ConnectBlock().
|
||||||
* Note that -reindex-chainstate skips the validation that happens here!
|
* Note that -reindex-chainstate skips the validation that happens here!
|
||||||
*/
|
*/
|
||||||
static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const CChainParams& params, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
|
static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const ChainstateManager& chainman, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
|
||||||
{
|
{
|
||||||
AssertLockHeld(::cs_main);
|
AssertLockHeld(::cs_main);
|
||||||
assert(pindexPrev != nullptr);
|
assert(pindexPrev != nullptr);
|
||||||
const int nHeight = pindexPrev->nHeight + 1;
|
const int nHeight = pindexPrev->nHeight + 1;
|
||||||
|
|
||||||
// Check proof of work
|
// Check proof of work
|
||||||
const Consensus::Params& consensusParams = params.GetConsensus();
|
const Consensus::Params& consensusParams = chainman.GetConsensus();
|
||||||
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
|
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");
|
||||||
|
|
||||||
|
@ -3462,7 +3463,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
||||||
// Don't accept any forks from the main chain prior to last checkpoint.
|
// Don't accept any forks from the main chain prior to last checkpoint.
|
||||||
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
|
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
|
||||||
// BlockIndex().
|
// BlockIndex().
|
||||||
const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints());
|
const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(chainman.GetParams().Checkpoints());
|
||||||
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
|
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
|
||||||
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
|
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "bad-fork-prior-to-checkpoint");
|
return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "bad-fork-prior-to-checkpoint");
|
||||||
|
@ -3478,9 +3479,9 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
|
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
|
||||||
|
|
||||||
// Reject blocks with outdated version
|
// Reject blocks with outdated version
|
||||||
if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
|
if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
|
||||||
(block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DERSIG)) ||
|
(block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_DERSIG)) ||
|
||||||
(block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CLTV))) {
|
(block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_CLTV))) {
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),
|
||||||
strprintf("rejected nVersion=0x%08x block", block.nVersion));
|
strprintf("rejected nVersion=0x%08x block", block.nVersion));
|
||||||
}
|
}
|
||||||
|
@ -3494,13 +3495,13 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
||||||
* in ConnectBlock().
|
* in ConnectBlock().
|
||||||
* Note that -reindex-chainstate skips the validation that happens here!
|
* Note that -reindex-chainstate skips the validation that happens here!
|
||||||
*/
|
*/
|
||||||
static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
|
static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& state, const ChainstateManager& chainman, const CBlockIndex* pindexPrev)
|
||||||
{
|
{
|
||||||
const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
|
const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
|
||||||
|
|
||||||
// Enforce BIP113 (Median Time Past).
|
// Enforce BIP113 (Median Time Past).
|
||||||
int nLockTimeFlags = 0;
|
int nLockTimeFlags = 0;
|
||||||
if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV)) {
|
if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_CSV)) {
|
||||||
assert(pindexPrev != nullptr);
|
assert(pindexPrev != nullptr);
|
||||||
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
|
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
|
||||||
}
|
}
|
||||||
|
@ -3517,7 +3518,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce rule that the coinbase starts with serialized block height
|
// Enforce rule that the coinbase starts with serialized block height
|
||||||
if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB))
|
if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB))
|
||||||
{
|
{
|
||||||
CScript expect = CScript() << nHeight;
|
CScript expect = CScript() << nHeight;
|
||||||
if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
|
if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
|
||||||
|
@ -3535,7 +3536,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
|
||||||
// {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness reserved value). In case there are
|
// {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness reserved value). In case there are
|
||||||
// multiple, the last one is used.
|
// multiple, the last one is used.
|
||||||
bool fHaveWitness = false;
|
bool fHaveWitness = false;
|
||||||
if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
|
if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||||
int commitpos = GetWitnessCommitmentIndex(block);
|
int commitpos = GetWitnessCommitmentIndex(block);
|
||||||
if (commitpos != NO_WITNESS_COMMITMENT) {
|
if (commitpos != NO_WITNESS_COMMITMENT) {
|
||||||
bool malleated = false;
|
bool malleated = false;
|
||||||
|
@ -3576,13 +3577,13 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex)
|
bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationState& state, CBlockIndex** ppindex)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
// Check for duplicate
|
// Check for duplicate
|
||||||
uint256 hash = block.GetHash();
|
uint256 hash = block.GetHash();
|
||||||
BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)};
|
BlockMap::iterator miSelf{m_blockman.m_block_index.find(hash)};
|
||||||
if (hash != chainparams.GetConsensus().hashGenesisBlock) {
|
if (hash != GetConsensus().hashGenesisBlock) {
|
||||||
if (miSelf != m_blockman.m_block_index.end()) {
|
if (miSelf != m_blockman.m_block_index.end()) {
|
||||||
// Block header is already known.
|
// Block header is already known.
|
||||||
CBlockIndex* pindex = &(miSelf->second);
|
CBlockIndex* pindex = &(miSelf->second);
|
||||||
|
@ -3595,7 +3596,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CheckBlockHeader(block, state, chainparams.GetConsensus())) {
|
if (!CheckBlockHeader(block, state, GetConsensus())) {
|
||||||
LogPrint(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
|
LogPrint(BCLog::VALIDATION, "%s: Consensus::CheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3612,7 +3613,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
|
||||||
LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString());
|
LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString());
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
|
||||||
}
|
}
|
||||||
if (!ContextualCheckBlockHeader(block, state, m_blockman, chainparams, pindexPrev, GetAdjustedTime())) {
|
if (!ContextualCheckBlockHeader(block, state, m_blockman, *this, pindexPrev, GetAdjustedTime())) {
|
||||||
LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
|
LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3665,14 +3666,14 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exposed wrapper for AcceptBlockHeader
|
// Exposed wrapper for AcceptBlockHeader
|
||||||
bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex)
|
bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CBlockIndex** ppindex)
|
||||||
{
|
{
|
||||||
AssertLockNotHeld(cs_main);
|
AssertLockNotHeld(cs_main);
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
for (const CBlockHeader& header : headers) {
|
for (const CBlockHeader& header : headers) {
|
||||||
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
|
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
|
||||||
bool accepted{AcceptBlockHeader(header, state, chainparams, &pindex)};
|
bool accepted{AcceptBlockHeader(header, state, &pindex)};
|
||||||
ActiveChainstate().CheckBlockIndex();
|
ActiveChainstate().CheckBlockIndex();
|
||||||
|
|
||||||
if (!accepted) {
|
if (!accepted) {
|
||||||
|
@ -3686,7 +3687,7 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
|
||||||
if (NotifyHeaderTip(ActiveChainstate())) {
|
if (NotifyHeaderTip(ActiveChainstate())) {
|
||||||
if (ActiveChainstate().IsInitialBlockDownload() && ppindex && *ppindex) {
|
if (ActiveChainstate().IsInitialBlockDownload() && ppindex && *ppindex) {
|
||||||
const CBlockIndex& last_accepted{**ppindex};
|
const CBlockIndex& last_accepted{**ppindex};
|
||||||
const int64_t blocks_left{(GetTime() - last_accepted.GetBlockTime()) / chainparams.GetConsensus().nPowTargetSpacing};
|
const int64_t blocks_left{(GetTime() - last_accepted.GetBlockTime()) / GetConsensus().nPowTargetSpacing};
|
||||||
const double progress{100.0 * last_accepted.nHeight / (last_accepted.nHeight + blocks_left)};
|
const double progress{100.0 * last_accepted.nHeight / (last_accepted.nHeight + blocks_left)};
|
||||||
LogPrintf("Synchronizing blockheaders, height: %d (~%.2f%%)\n", last_accepted.nHeight, progress);
|
LogPrintf("Synchronizing blockheaders, height: %d (~%.2f%%)\n", last_accepted.nHeight, progress);
|
||||||
}
|
}
|
||||||
|
@ -3705,7 +3706,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
|
||||||
CBlockIndex *pindexDummy = nullptr;
|
CBlockIndex *pindexDummy = nullptr;
|
||||||
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
|
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
|
||||||
|
|
||||||
bool accepted_header{m_chainman.AcceptBlockHeader(block, state, m_params, &pindex)};
|
bool accepted_header{m_chainman.AcceptBlockHeader(block, state, &pindex)};
|
||||||
CheckBlockIndex();
|
CheckBlockIndex();
|
||||||
|
|
||||||
if (!accepted_header)
|
if (!accepted_header)
|
||||||
|
@ -3745,7 +3746,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CheckBlock(block, state, m_params.GetConsensus()) ||
|
if (!CheckBlock(block, state, m_params.GetConsensus()) ||
|
||||||
!ContextualCheckBlock(block, state, m_params.GetConsensus(), pindex->pprev)) {
|
!ContextualCheckBlock(block, state, m_chainman, pindex->pprev)) {
|
||||||
if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
|
if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
|
||||||
pindex->nStatus |= BLOCK_FAILED_VALID;
|
pindex->nStatus |= BLOCK_FAILED_VALID;
|
||||||
m_blockman.m_dirty_blockindex.insert(pindex);
|
m_blockman.m_dirty_blockindex.insert(pindex);
|
||||||
|
@ -3778,7 +3779,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block)
|
bool ChainstateManager::ProcessNewBlock(const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block)
|
||||||
{
|
{
|
||||||
AssertLockNotHeld(cs_main);
|
AssertLockNotHeld(cs_main);
|
||||||
|
|
||||||
|
@ -3796,7 +3797,7 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
|
||||||
// malleability that cause CheckBlock() to fail; see e.g. CVE-2012-2459 and
|
// malleability that cause CheckBlock() to fail; see e.g. CVE-2012-2459 and
|
||||||
// https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-February/016697.html. Because CheckBlock() is
|
// https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-February/016697.html. Because CheckBlock() is
|
||||||
// not very expensive, the anti-DoS benefits of caching failure (of a definitely-invalid block) are not substantial.
|
// not very expensive, the anti-DoS benefits of caching failure (of a definitely-invalid block) are not substantial.
|
||||||
bool ret = CheckBlock(*block, state, chainparams.GetConsensus());
|
bool ret = CheckBlock(*block, state, GetConsensus());
|
||||||
if (ret) {
|
if (ret) {
|
||||||
// Store to disk
|
// Store to disk
|
||||||
ret = ActiveChainstate().AcceptBlock(block, state, &pindex, force_processing, nullptr, new_block);
|
ret = ActiveChainstate().AcceptBlock(block, state, &pindex, force_processing, nullptr, new_block);
|
||||||
|
@ -3849,11 +3850,11 @@ bool TestBlockValidity(BlockValidationState& state,
|
||||||
indexDummy.phashBlock = &block_hash;
|
indexDummy.phashBlock = &block_hash;
|
||||||
|
|
||||||
// NOTE: CheckBlockHeader is called by CheckBlock
|
// NOTE: CheckBlockHeader is called by CheckBlock
|
||||||
if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainparams, pindexPrev, GetAdjustedTime()))
|
if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainstate.m_chainman, pindexPrev, GetAdjustedTime()))
|
||||||
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
|
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
|
||||||
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
|
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
|
||||||
return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
|
return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
|
||||||
if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev))
|
if (!ContextualCheckBlock(block, state, chainstate.m_chainman, pindexPrev))
|
||||||
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, state.ToString());
|
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, state.ToString());
|
||||||
if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, true)) {
|
if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, true)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -4133,7 +4134,7 @@ bool CChainState::NeedsRedownload() const
|
||||||
// At and above m_params.SegwitHeight, segwit consensus rules must be validated
|
// At and above m_params.SegwitHeight, segwit consensus rules must be validated
|
||||||
CBlockIndex* block{m_chain.Tip()};
|
CBlockIndex* block{m_chain.Tip()};
|
||||||
|
|
||||||
while (block != nullptr && DeploymentActiveAt(*block, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
|
while (block != nullptr && DeploymentActiveAt(*block, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||||
if (!(block->nStatus & BLOCK_OPT_WITNESS)) {
|
if (!(block->nStatus & BLOCK_OPT_WITNESS)) {
|
||||||
// block is insufficiently validated for a segwit client
|
// block is insufficiently validated for a segwit client
|
||||||
return true;
|
return true;
|
||||||
|
@ -4993,7 +4994,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
|
||||||
}
|
}
|
||||||
|
|
||||||
int base_height = snapshot_start_block->nHeight;
|
int base_height = snapshot_start_block->nHeight;
|
||||||
auto maybe_au_data = ExpectedAssumeutxo(base_height, ::Params());
|
auto maybe_au_data = ExpectedAssumeutxo(base_height, GetParams());
|
||||||
|
|
||||||
if (!maybe_au_data) {
|
if (!maybe_au_data) {
|
||||||
LogPrintf("[snapshot] assumeutxo height in snapshot metadata not recognized " /* Continued */
|
LogPrintf("[snapshot] assumeutxo height in snapshot metadata not recognized " /* Continued */
|
||||||
|
@ -5147,7 +5148,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
|
||||||
|
|
||||||
// Fake BLOCK_OPT_WITNESS so that CChainState::NeedsRedownload()
|
// Fake BLOCK_OPT_WITNESS so that CChainState::NeedsRedownload()
|
||||||
// won't ask to rewind the entire assumed-valid chain on startup.
|
// won't ask to rewind the entire assumed-valid chain on startup.
|
||||||
if (DeploymentActiveAt(*index, ::Params().GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
|
if (DeploymentActiveAt(*index, *this, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||||
index->nStatus |= BLOCK_OPT_WITNESS;
|
index->nStatus |= BLOCK_OPT_WITNESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5216,9 +5217,9 @@ ChainstateManager::~ChainstateManager()
|
||||||
{
|
{
|
||||||
LOCK(::cs_main);
|
LOCK(::cs_main);
|
||||||
|
|
||||||
// TODO: The version bits cache and warning cache should probably become
|
m_versionbitscache.Clear();
|
||||||
// non-globals
|
|
||||||
g_versionbitscache.Clear();
|
// TODO: The warning cache should probably become non-global
|
||||||
for (auto& i : warningcache) {
|
for (auto& i : warningcache) {
|
||||||
i.clear();
|
i.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
#include <arith_uint256.h>
|
#include <arith_uint256.h>
|
||||||
#include <attributes.h>
|
#include <attributes.h>
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
|
#include <chainparams.h>
|
||||||
#include <consensus/amount.h>
|
#include <consensus/amount.h>
|
||||||
|
#include <deploymentstatus.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <node/blockstorage.h>
|
#include <node/blockstorage.h>
|
||||||
#include <policy/feerate.h>
|
#include <policy/feerate.h>
|
||||||
|
@ -26,6 +28,7 @@
|
||||||
#include <util/check.h>
|
#include <util/check.h>
|
||||||
#include <util/hasher.h>
|
#include <util/hasher.h>
|
||||||
#include <util/translation.h>
|
#include <util/translation.h>
|
||||||
|
#include <versionbits.h>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -40,7 +43,6 @@
|
||||||
|
|
||||||
class CChainState;
|
class CChainState;
|
||||||
class CBlockTreeDB;
|
class CBlockTreeDB;
|
||||||
class CChainParams;
|
|
||||||
class CTxMemPool;
|
class CTxMemPool;
|
||||||
class ChainstateManager;
|
class ChainstateManager;
|
||||||
struct ChainTxData;
|
struct ChainTxData;
|
||||||
|
@ -51,6 +53,9 @@ struct AssumeutxoData;
|
||||||
namespace node {
|
namespace node {
|
||||||
class SnapshotMetadata;
|
class SnapshotMetadata;
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
namespace Consensus {
|
||||||
|
struct Params;
|
||||||
|
} // namespace Consensus
|
||||||
|
|
||||||
/** Default for -minrelaytxfee, minimum relay fee for transactions */
|
/** Default for -minrelaytxfee, minimum relay fee for transactions */
|
||||||
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000;
|
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000;
|
||||||
|
@ -359,12 +364,6 @@ bool TestBlockValidity(BlockValidationState& state,
|
||||||
bool fCheckPOW = true,
|
bool fCheckPOW = true,
|
||||||
bool fCheckMerkleRoot = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
bool fCheckMerkleRoot = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
/** Update uncommitted block structures (currently: only the witness reserved value). This is safe for submitted blocks. */
|
|
||||||
void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams);
|
|
||||||
|
|
||||||
/** Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks). */
|
|
||||||
std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams);
|
|
||||||
|
|
||||||
/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
|
/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
|
||||||
class CVerifyDB {
|
class CVerifyDB {
|
||||||
public:
|
public:
|
||||||
|
@ -495,6 +494,7 @@ public:
|
||||||
node::BlockManager& m_blockman;
|
node::BlockManager& m_blockman;
|
||||||
|
|
||||||
/** Chain parameters for this chainstate */
|
/** Chain parameters for this chainstate */
|
||||||
|
/* TODO: replace with m_chainman.GetParams() */
|
||||||
const CChainParams& m_params;
|
const CChainParams& m_params;
|
||||||
|
|
||||||
//! The chainstate manager that owns this chainstate. The reference is
|
//! The chainstate manager that owns this chainstate. The reference is
|
||||||
|
@ -834,6 +834,8 @@ private:
|
||||||
|
|
||||||
CBlockIndex* m_best_invalid GUARDED_BY(::cs_main){nullptr};
|
CBlockIndex* m_best_invalid GUARDED_BY(::cs_main){nullptr};
|
||||||
|
|
||||||
|
const CChainParams& m_chainparams;
|
||||||
|
|
||||||
//! Internal helper for ActivateSnapshot().
|
//! Internal helper for ActivateSnapshot().
|
||||||
[[nodiscard]] bool PopulateAndValidateSnapshot(
|
[[nodiscard]] bool PopulateAndValidateSnapshot(
|
||||||
CChainState& snapshot_chainstate,
|
CChainState& snapshot_chainstate,
|
||||||
|
@ -847,11 +849,15 @@ private:
|
||||||
bool AcceptBlockHeader(
|
bool AcceptBlockHeader(
|
||||||
const CBlockHeader& block,
|
const CBlockHeader& block,
|
||||||
BlockValidationState& state,
|
BlockValidationState& state,
|
||||||
const CChainParams& chainparams,
|
|
||||||
CBlockIndex** ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
CBlockIndex** ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
friend CChainState;
|
friend CChainState;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
explicit ChainstateManager(const CChainParams& chainparams) : m_chainparams{chainparams} { }
|
||||||
|
|
||||||
|
const CChainParams& GetParams() const { return m_chainparams; }
|
||||||
|
const Consensus::Params& GetConsensus() const { return m_chainparams.GetConsensus(); }
|
||||||
|
|
||||||
std::thread m_load_block;
|
std::thread m_load_block;
|
||||||
//! A single BlockManager instance is shared across each constructed
|
//! A single BlockManager instance is shared across each constructed
|
||||||
//! chainstate to avoid duplicating block metadata.
|
//! chainstate to avoid duplicating block metadata.
|
||||||
|
@ -932,6 +938,11 @@ public:
|
||||||
return m_blockman.m_block_index;
|
return m_blockman.m_block_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Track versionbit status
|
||||||
|
*/
|
||||||
|
mutable VersionBitsCache m_versionbitscache;
|
||||||
|
|
||||||
//! @returns true if a snapshot-based chainstate is in use. Also implies
|
//! @returns true if a snapshot-based chainstate is in use. Also implies
|
||||||
//! that a background validation chainstate is also in use.
|
//! that a background validation chainstate is also in use.
|
||||||
bool IsSnapshotActive() const;
|
bool IsSnapshotActive() const;
|
||||||
|
@ -960,7 +971,7 @@ public:
|
||||||
* @param[out] new_block A boolean which is set to indicate if the block was first received via this call
|
* @param[out] new_block A boolean which is set to indicate if the block was first received via this call
|
||||||
* @returns If the block was processed, independently of block validity
|
* @returns If the block was processed, independently of block validity
|
||||||
*/
|
*/
|
||||||
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block) LOCKS_EXCLUDED(cs_main);
|
bool ProcessNewBlock(const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block) LOCKS_EXCLUDED(cs_main);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process incoming block headers.
|
* Process incoming block headers.
|
||||||
|
@ -970,10 +981,9 @@ public:
|
||||||
*
|
*
|
||||||
* @param[in] block The block headers themselves
|
* @param[in] block The block headers themselves
|
||||||
* @param[out] state This may be set to an Error state if any error occurred processing them
|
* @param[out] state This may be set to an Error state if any error occurred processing them
|
||||||
* @param[in] chainparams The params for the chain we want to connect to
|
|
||||||
* @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
|
* @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
|
||||||
*/
|
*/
|
||||||
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
|
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to add a transaction to the memory pool.
|
* Try to add a transaction to the memory pool.
|
||||||
|
@ -991,9 +1001,34 @@ public:
|
||||||
//! ResizeCoinsCaches() as needed.
|
//! ResizeCoinsCaches() as needed.
|
||||||
void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
|
void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
|
||||||
|
|
||||||
|
/** Update uncommitted block structures (currently: only the witness reserved value). This is safe for submitted blocks. */
|
||||||
|
void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev) const;
|
||||||
|
|
||||||
|
/** Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks). */
|
||||||
|
std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev) const;
|
||||||
|
|
||||||
~ChainstateManager();
|
~ChainstateManager();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Deployment* info via ChainstateManager */
|
||||||
|
template<typename DEP>
|
||||||
|
bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const ChainstateManager& chainman, DEP dep)
|
||||||
|
{
|
||||||
|
return DeploymentActiveAfter(pindexPrev, chainman.GetConsensus(), dep, chainman.m_versionbitscache);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DEP>
|
||||||
|
bool DeploymentActiveAt(const CBlockIndex& index, const ChainstateManager& chainman, DEP dep)
|
||||||
|
{
|
||||||
|
return DeploymentActiveAt(index, chainman.GetConsensus(), dep, chainman.m_versionbitscache);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DEP>
|
||||||
|
bool DeploymentEnabled(const ChainstateManager& chainman, DEP dep)
|
||||||
|
{
|
||||||
|
return DeploymentEnabled(chainman.GetConsensus(), dep);
|
||||||
|
}
|
||||||
|
|
||||||
using FopenFn = std::function<FILE*(const fs::path&, const char*)>;
|
using FopenFn = std::function<FILE*(const fs::path&, const char*)>;
|
||||||
|
|
||||||
/** Dump the mempool to disk. */
|
/** Dump the mempool to disk. */
|
||||||
|
|
Loading…
Add table
Reference in a new issue