deploymentstatus.h raw
1 // Copyright (c) 2020-2022 The Limenka 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 LIMENKA_DEPLOYMENTSTATUS_H
6 #define LIMENKA_DEPLOYMENTSTATUS_H
7
8 #include <chain.h>
9 #include <versionbits.h>
10
11 #include <limits>
12
13 /** Determine if a deployment is active for the next block */
14 inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache& versionbitscache)
15 {
16 assert(Consensus::ValidDeployment(dep));
17 return (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1) >= params.DeploymentHeight(dep);
18 }
19
20 inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep, VersionBitsCache& versionbitscache)
21 {
22 assert(Consensus::ValidDeployment(dep));
23 if (ThresholdState::ACTIVE != versionbitscache.State(pindexPrev, params, dep)) return false;
24
25 const auto& deployment = params.vDeployments[dep];
26 // Permanent deployment (never expires)
27 if (deployment.active_duration == std::numeric_limits<int>::max()) return true;
28
29 const int activation_height = versionbitscache.StateSinceHeight(pindexPrev, params, dep);
30 const int height = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
31 return height < activation_height + deployment.active_duration;
32 }
33
34 /** Determine if a deployment is active for this block */
35 inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache& versionbitscache)
36 {
37 assert(Consensus::ValidDeployment(dep));
38 return index.nHeight >= params.DeploymentHeight(dep);
39 }
40
41 inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::DeploymentPos dep, VersionBitsCache& versionbitscache)
42 {
43 assert(Consensus::ValidDeployment(dep));
44 return DeploymentActiveAfter(index.pprev, params, dep, versionbitscache);
45 }
46
47 /** Determine if a deployment is enabled (can ever be active) */
48 inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::BuriedDeployment dep)
49 {
50 assert(Consensus::ValidDeployment(dep));
51 return params.DeploymentHeight(dep) != std::numeric_limits<int>::max();
52 }
53
54 inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::DeploymentPos dep)
55 {
56 assert(Consensus::ValidDeployment(dep));
57 return params.vDeployments[dep].nStartTime != Consensus::BIP9Deployment::NEVER_ACTIVE;
58 }
59
60 /** Determine if mandatory signaling is required for a deployment at the next block */
61 inline bool DeploymentMustSignalAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep, ThresholdState state)
62 {
63 assert(Consensus::ValidDeployment(dep));
64 const auto& deployment = params.vDeployments[dep];
65 if (deployment.max_activation_height >= std::numeric_limits<int>::max()) return false;
66 if (state != ThresholdState::STARTED) return false; // If must_signal height is reached before start time, abstain from enforcement
67 const int nPeriod = params.nMinerConfirmationWindow;
68 const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
69 return nHeight >= deployment.max_activation_height - (2 * nPeriod)
70 && nHeight < deployment.max_activation_height - nPeriod;
71 }
72
73 #endif // LIMENKA_DEPLOYMENTSTATUS_H
74