Skip to content

Commit ddc6979

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#19438: Introduce deploymentstatus
e48826a tests: remove ComputeBlockVersion shortcut from versionbits tests (Anthony Towns) c5f3672 [refactor] Move ComputeBlockVersion into VersionBitsCache (Anthony Towns) 4a69b4d [move-only] Move ComputeBlockVersion from validation to versionbits (Anthony Towns) 0cfd6c6 [refactor] versionbits: make VersionBitsCache a full class (Anthony Towns) 8ee3e0b [refactor] rpc/blockchain.cpp: SoftForkPushBack (Anthony Towns) 92f48f3 deploymentinfo: Add DeploymentName() (Anthony Towns) ea68b3a [move-only] Rename versionbitsinfo to deploymentinfo (Anthony Towns) c64b2c6 scripted-diff: rename versionbitscache (Anthony Towns) de55304 [refactor] Add versionbits deployments to deploymentstatus.h (Anthony Towns) 2b0d291 [refactor] Add deploymentstatus.h (Anthony Towns) eccd736 versionbits: Use dedicated lock instead of cs_main (Anthony Towns) 36a4ba0 versionbits: correct doxygen comments (Anthony Towns) Pull request description: Introduces helper functions to make it easy to bury future deployments, along the lines of the suggestion from [11398](bitcoin/bitcoin#11398 (comment)) "I would prefer it if a buried deployment wouldn't require all code paths that check the BIP9 status to require changing". This provides three functions: `DeploymentEnabled()` which tests if a deployment can ever be active, `DeploymentActiveAt()` which checks if a deployment should be enforced in the given block, and `DeploymentActiveAfter()` which checks if a deployment should be enforced in the block following the given block, and overloads all three to work both with buried deployments and versionbits deployments. This adds a dedicated lock for the versionbits cache, which is acquired internally by the versionbits functions, rather than relying on `cs_main`. It also moves moves versionbitscache into deploymentstatus to avoid a circular dependency with validation. ACKs for top commit: jnewbery: ACK e48826a gruve-p: ACK bitcoin/bitcoin@e48826a MarcoFalke: re-ACK e48826a 🥈 Tree-SHA512: c846ba64436d36f8180046ad551d8b0d9e20509b9bc185aa2639055fc28803dd8ec2d6771ab337e80da0b40009ad959590d5772f84a0bf6199b65190d4155bed
2 parents a926d6d + e48826a commit ddc6979

20 files changed

+321
-192
lines changed

src/Makefile.am

+4-2
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ BITCOIN_CORE_H = \
145145
core_memusage.h \
146146
cuckoocache.h \
147147
dbwrapper.h \
148+
deploymentinfo.h \
149+
deploymentstatus.h \
148150
external_signer.h \
149151
flatfile.h \
150152
fs.h \
@@ -272,7 +274,6 @@ BITCOIN_CORE_H = \
272274
validation.h \
273275
validationinterface.h \
274276
versionbits.h \
275-
versionbitsinfo.h \
276277
wallet/bdb.h \
277278
wallet/coincontrol.h \
278279
wallet/coinselection.h \
@@ -328,6 +329,7 @@ libbitcoin_server_a_SOURCES = \
328329
chain.cpp \
329330
consensus/tx_verify.cpp \
330331
dbwrapper.cpp \
332+
deploymentstatus.cpp \
331333
flatfile.cpp \
332334
httprpc.cpp \
333335
httpserver.cpp \
@@ -540,6 +542,7 @@ libbitcoin_common_a_SOURCES = \
540542
compressor.cpp \
541543
core_read.cpp \
542544
core_write.cpp \
545+
deploymentinfo.cpp \
543546
external_signer.cpp \
544547
init/common.cpp \
545548
key.cpp \
@@ -561,7 +564,6 @@ libbitcoin_common_a_SOURCES = \
561564
script/sign.cpp \
562565
script/signingprovider.cpp \
563566
script/standard.cpp \
564-
versionbitsinfo.cpp \
565567
warnings.cpp \
566568
$(BITCOIN_CORE_H)
567569

src/chainparams.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
#include <chainparamsseeds.h>
99
#include <consensus/merkle.h>
10+
#include <deploymentinfo.h>
1011
#include <hash.h> // for signet block challenge hash
1112
#include <util/system.h>
12-
#include <versionbitsinfo.h>
1313

1414
#include <assert.h>
1515

src/consensus/params.h

+32-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,25 @@
1111

1212
namespace Consensus {
1313

14-
enum DeploymentPos
14+
enum BuriedDeployment : int16_t
15+
{
16+
// buried deployments get negative values to avoid overlap with DeploymentPos
17+
DEPLOYMENT_HEIGHTINCB = std::numeric_limits<int16_t>::min(),
18+
DEPLOYMENT_CLTV,
19+
DEPLOYMENT_DERSIG,
20+
DEPLOYMENT_CSV,
21+
DEPLOYMENT_SEGWIT,
22+
};
23+
constexpr bool ValidDeployment(BuriedDeployment dep) { return DEPLOYMENT_HEIGHTINCB <= dep && dep <= DEPLOYMENT_SEGWIT; }
24+
25+
enum DeploymentPos : uint16_t
1526
{
1627
DEPLOYMENT_TESTDUMMY,
1728
DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342)
18-
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
29+
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
1930
MAX_VERSION_BITS_DEPLOYMENTS
2031
};
32+
constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_TAPROOT; }
2133

2234
/**
2335
* Struct for each individual consensus rule change using BIP9.
@@ -100,7 +112,25 @@ struct Params {
100112
*/
101113
bool signet_blocks{false};
102114
std::vector<uint8_t> signet_challenge;
115+
116+
int DeploymentHeight(BuriedDeployment dep) const
117+
{
118+
switch (dep) {
119+
case DEPLOYMENT_HEIGHTINCB:
120+
return BIP34Height;
121+
case DEPLOYMENT_CLTV:
122+
return BIP65Height;
123+
case DEPLOYMENT_DERSIG:
124+
return BIP66Height;
125+
case DEPLOYMENT_CSV:
126+
return CSVHeight;
127+
case DEPLOYMENT_SEGWIT:
128+
return SegwitHeight;
129+
} // no default case, so the compiler can warn about missing cases
130+
return std::numeric_limits<int>::max();
131+
}
103132
};
133+
104134
} // namespace Consensus
105135

106136
#endif // BITCOIN_CONSENSUS_PARAMS_H

src/deploymentinfo.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) 2016-2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <deploymentinfo.h>
6+
7+
#include <consensus/params.h>
8+
9+
const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = {
10+
{
11+
/*.name =*/ "testdummy",
12+
/*.gbt_force =*/ true,
13+
},
14+
{
15+
/*.name =*/ "taproot",
16+
/*.gbt_force =*/ true,
17+
},
18+
};
19+
20+
std::string DeploymentName(Consensus::BuriedDeployment dep)
21+
{
22+
assert(ValidDeployment(dep));
23+
switch (dep) {
24+
case Consensus::DEPLOYMENT_HEIGHTINCB:
25+
return "bip34";
26+
case Consensus::DEPLOYMENT_CLTV:
27+
return "bip65";
28+
case Consensus::DEPLOYMENT_DERSIG:
29+
return "bip66";
30+
case Consensus::DEPLOYMENT_CSV:
31+
return "csv";
32+
case Consensus::DEPLOYMENT_SEGWIT:
33+
return "segwit";
34+
} // no default case, so the compiler can warn about missing cases
35+
return "";
36+
}

src/deploymentinfo.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2016-2018 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_DEPLOYMENTINFO_H
6+
#define BITCOIN_DEPLOYMENTINFO_H
7+
8+
#include <consensus/params.h>
9+
10+
#include <string>
11+
12+
struct VBDeploymentInfo {
13+
/** Deployment name */
14+
const char *name;
15+
/** Whether GBT clients can safely ignore this rule in simplified usage */
16+
bool gbt_force;
17+
};
18+
19+
extern const VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS];
20+
21+
std::string DeploymentName(Consensus::BuriedDeployment dep);
22+
23+
inline std::string DeploymentName(Consensus::DeploymentPos pos)
24+
{
25+
assert(Consensus::ValidDeployment(pos));
26+
return VersionBitsDeploymentInfo[pos].name;
27+
}
28+
29+
#endif // BITCOIN_DEPLOYMENTINFO_H

src/deploymentstatus.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) 2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <deploymentstatus.h>
6+
7+
#include <consensus/params.h>
8+
#include <versionbits.h>
9+
10+
VersionBitsCache g_versionbitscache;
11+
12+
/* Basic sanity checking for BuriedDeployment/DeploymentPos enums and
13+
* ValidDeployment check */
14+
15+
static_assert(ValidDeployment(Consensus::DEPLOYMENT_TESTDUMMY), "sanity check of DeploymentPos failed (TESTDUMMY not valid)");
16+
static_assert(!ValidDeployment(Consensus::MAX_VERSION_BITS_DEPLOYMENTS), "sanity check of DeploymentPos failed (MAX value considered valid)");
17+
static_assert(!ValidDeployment(static_cast<Consensus::BuriedDeployment>(Consensus::DEPLOYMENT_TESTDUMMY)), "sanity check of BuriedDeployment failed (overlaps with DeploymentPos)");

src/deploymentstatus.h

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) 2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_DEPLOYMENTSTATUS_H
6+
#define BITCOIN_DEPLOYMENTSTATUS_H
7+
8+
#include <chain.h>
9+
#include <versionbits.h>
10+
11+
#include <limits>
12+
13+
/** Global cache for versionbits deployment status */
14+
extern VersionBitsCache g_versionbitscache;
15+
16+
/** Determine if a deployment is active for the next block */
17+
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep)
18+
{
19+
assert(Consensus::ValidDeployment(dep));
20+
return (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1) >= params.DeploymentHeight(dep);
21+
}
22+
23+
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep)
24+
{
25+
assert(Consensus::ValidDeployment(dep));
26+
return ThresholdState::ACTIVE == g_versionbitscache.State(pindexPrev, params, dep);
27+
}
28+
29+
/** Determine if a deployment is active for this block */
30+
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep)
31+
{
32+
assert(Consensus::ValidDeployment(dep));
33+
return index.nHeight >= params.DeploymentHeight(dep);
34+
}
35+
36+
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::DeploymentPos dep)
37+
{
38+
assert(Consensus::ValidDeployment(dep));
39+
return DeploymentActiveAfter(index.pprev, params, dep);
40+
}
41+
42+
/** Determine if a deployment is enabled (can ever be active) */
43+
inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::BuriedDeployment dep)
44+
{
45+
assert(Consensus::ValidDeployment(dep));
46+
return params.DeploymentHeight(dep) != std::numeric_limits<int>::max();
47+
}
48+
49+
inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::DeploymentPos dep)
50+
{
51+
assert(Consensus::ValidDeployment(dep));
52+
return params.vDeployments[dep].nTimeout != 0;
53+
}
54+
55+
#endif // BITCOIN_DEPLOYMENTSTATUS_H

src/init.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <chain.h>
1717
#include <chainparams.h>
1818
#include <compat/sanity.h>
19+
#include <deploymentstatus.h>
1920
#include <fs.h>
2021
#include <hash.h>
2122
#include <httprpc.h>
@@ -1587,7 +1588,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15871588
}
15881589
}
15891590

1590-
if (chainparams.GetConsensus().SegwitHeight != std::numeric_limits<int>::max()) {
1591+
if (DeploymentEnabled(chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
15911592
// Advertise witness capabilities.
15921593
// The option to not set NODE_WITNESS is only used in the tests and should be removed.
15931594
nLocalServices = ServiceFlags(nLocalServices | NODE_WITNESS);

src/miner.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <consensus/merkle.h>
1414
#include <consensus/tx_verify.h>
1515
#include <consensus/validation.h>
16+
#include <deploymentstatus.h>
1617
#include <policy/feerate.h>
1718
#include <policy/policy.h>
1819
#include <pow.h>
@@ -120,7 +121,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
120121
assert(pindexPrev != nullptr);
121122
nHeight = pindexPrev->nHeight + 1;
122123

123-
pblock->nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
124+
pblock->nVersion = g_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
124125
// -regtest only: allow overriding block.nVersion with
125126
// -blockversion=N to test forking scenarios
126127
if (chainparams.MineBlocksOnDemand())
@@ -137,12 +138,12 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
137138
// This is only needed in case the witness softfork activation is reverted
138139
// (which would require a very deep reorganization).
139140
// Note that the mempool would accept transactions with witness data before
140-
// IsWitnessEnabled, but we would only ever mine blocks after IsWitnessEnabled
141+
// the deployment is active, but we would only ever mine blocks after activation
141142
// unless there is a massive block reorganization with the witness softfork
142143
// not activated.
143144
// TODO: replace this with a call to main to assess validity of a mempool
144145
// transaction (which in most cases can be a no-op).
145-
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
146+
fIncludeWitness = DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT);
146147

147148
int nPackagesSelected = 0;
148149
int nDescendantsUpdated = 0;

src/net_processing.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <blockfilter.h>
1212
#include <chainparams.h>
1313
#include <consensus/validation.h>
14+
#include <deploymentstatus.h>
1415
#include <hash.h>
1516
#include <index/blockfilterindex.h>
1617
#include <merkleblock.h>
@@ -997,7 +998,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
997998
// We consider the chain that this peer is on invalid.
998999
return;
9991000
}
1000-
if (!State(nodeid)->fHaveWitness && IsWitnessEnabled(pindex->pprev, consensusParams)) {
1001+
if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
10011002
// We wouldn't download this block or its descendants from this peer.
10021003
return;
10031004
}
@@ -1467,7 +1468,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
14671468
return;
14681469
nHighestFastAnnounce = pindex->nHeight;
14691470

1470-
bool fWitnessEnabled = IsWitnessEnabled(pindex->pprev, m_chainparams.GetConsensus());
1471+
bool fWitnessEnabled = DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT);
14711472
uint256 hashBlock(pblock->GetHash());
14721473

14731474
{
@@ -2082,7 +2083,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
20822083
while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
20832084
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
20842085
!IsBlockRequested(pindexWalk->GetBlockHash()) &&
2085-
(!IsWitnessEnabled(pindexWalk->pprev, m_chainparams.GetConsensus()) || State(pfrom.GetId())->fHaveWitness)) {
2086+
(!DeploymentActiveAt(*pindexWalk, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
20862087
// We don't have this block, and it's not yet in flight.
20872088
vToFetch.push_back(pindexWalk);
20882089
}
@@ -3397,7 +3398,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
33973398
return;
33983399
}
33993400

3400-
if (IsWitnessEnabled(pindex->pprev, m_chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) {
3401+
if (DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) && !nodestate->fSupportsDesiredCmpctVersion) {
34013402
// Don't bother trying to process compact blocks from v1 peers
34023403
// after segwit activates.
34033404
return;

src/node/interfaces.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <banman.h>
77
#include <chain.h>
88
#include <chainparams.h>
9+
#include <deploymentstatus.h>
910
#include <external_signer.h>
1011
#include <init.h>
1112
#include <interfaces/chain.h>
@@ -692,7 +693,7 @@ class ChainImpl : public Chain
692693
{
693694
LOCK(::cs_main);
694695
const CBlockIndex* tip = Assert(m_node.chainman)->ActiveChain().Tip();
695-
return VersionBitsState(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_TAPROOT, versionbitscache) == ThresholdState::ACTIVE;
696+
return DeploymentActiveAfter(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_TAPROOT);
696697
}
697698
NodeContext& m_node;
698699
};

0 commit comments

Comments
 (0)