From 296236412f311de7e889a4c37c3ee545b358dd12 Mon Sep 17 00:00:00 2001 From: Pedro Pinheiro Date: Mon, 22 Feb 2016 14:15:19 +0000 Subject: [PATCH 1/3] Add hard fork information to getblockchaininfo RPC endpoint --- src/main.h | 1 + src/rpcblockchain.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/main.h b/src/main.h index 93b412b08db..7ae8eec4df0 100644 --- a/src/main.h +++ b/src/main.h @@ -124,6 +124,7 @@ struct BlockHasher extern CScript COINBASE_FLAGS; extern CCriticalSection cs_main; extern CTxMemPool mempool; +extern boost::atomic sizeForkTime; typedef boost::unordered_map BlockMap; extern BlockMap mapBlockIndex; extern uint64_t nLastBlockTx; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index f5b16bc7c49..1c6d25cdf28 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -16,6 +16,8 @@ #include "streams.h" #include "sync.h" #include "txmempool.h" +#include "txdb.h" +#include "timedata.h" #include "util.h" #include "utilstrencodings.h" @@ -604,6 +606,46 @@ static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* return rv; } +static UniValue HardForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams) +{ + uint32_t forkTime = sizeForkTime.load(); + bool isHardForkActive = forkTime < std::numeric_limits::max(); + int nFound = 0; + UniValue gracePeriodEnds; + UniValue triggeredAtBlock; + CBlockIndex* pstart = pindex; + if (isHardForkActive) { + // Always report blocks found as over the threshold once the fork is active + nFound = nRequired + 1; + gracePeriodEnds = static_cast(forkTime); + triggeredAtBlock = pblocktree->ForkBitActivated(FORK_BIT_2MB).GetHex(); + } else { + for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++) + { + if (pstart->nVersion >= minVersion) + ++nFound; + pstart = pstart->pprev; + } + } + + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("triggeredatblock", triggeredAtBlock)); + rv.push_back(Pair("earliestforktime", gracePeriodEnds)); + rv.push_back(Pair("found", nFound)); + rv.push_back(Pair("required", nRequired)); + rv.push_back(Pair("window", consensusParams.nMajorityWindow)); + return rv; +} + +static UniValue HardForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +{ + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("id", name)); + rv.push_back(Pair("version", version)); + rv.push_back(Pair("status", HardForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))); + return rv; +} + UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -662,6 +704,10 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); obj.push_back(Pair("softforks", softforks)); + UniValue hardforks(UniValue::VARR); + hardforks.push_back(HardForkDesc("bip109", 0x01000000, tip, consensusParams)); + obj.push_back(Pair("hardforks", hardforks)); + if (fPruneMode) { CBlockIndex *block = chainActive.Tip(); From 839f1fa4ea2a29e983a8c93b8a0ac65fc76ba741 Mon Sep 17 00:00:00 2001 From: Pedro Pinheiro Date: Wed, 24 Feb 2016 18:36:33 +0000 Subject: [PATCH 2/3] Add assertion Enforce the invariant that the existence of an end-of-grace-period implies the existence of an activation hash. --- src/rpcblockchain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 1c6d25cdf28..aa547266f2c 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -618,7 +618,9 @@ static UniValue HardForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nR // Always report blocks found as over the threshold once the fork is active nFound = nRequired + 1; gracePeriodEnds = static_cast(forkTime); - triggeredAtBlock = pblocktree->ForkBitActivated(FORK_BIT_2MB).GetHex(); + uint256 activationHash = pblocktree->ForkBitActivated(FORK_BIT_2MB); + assert(activationHash != uint256()); + triggeredAtBlock = activationHash.GetHex(); } else { for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++) { From 51d83aa4c935ff520321b547e37ef1dd5726b492 Mon Sep 17 00:00:00 2001 From: Pedro Pinheiro Date: Wed, 24 Feb 2016 18:36:59 +0000 Subject: [PATCH 3/3] Add documentation for hardfork --- src/rpcblockchain.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index aa547266f2c..e5848794495 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -679,6 +679,20 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" " }, ...\n" " ]\n" + " \"hardforks\": [ (array) status of hardforks in progress\n" + " {\n" + " \"id\": \"xxxx\", (string) name of hardfork\n" + " \"version\": xx, (numeric) block version\n" + " \"status\": { (object) status of the hardfork\n" + " \"triggeredatblock\": \"xx\", (string) hash for the block where triggering conditions were met\n" + " \"earliestforktime\": xx, (numeric) lowest timestamp (seconds since Epoch) for which new blocks will be accepted \n" + " \"found\": xx, (numeric) number of blocks with the new version found\n" + " \"required\": xx, (numeric) number of blocks required to trigger\n" + " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n" + " },\n" + " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" + " }, ...\n" + " ]\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblockchaininfo", "")