From 71768555dd7307824c94f2aa2384d2a50ee23454 Mon Sep 17 00:00:00 2001 From: Jay Graber Date: Thu, 14 Dec 2017 18:02:35 -0800 Subject: [PATCH 1/4] Add upgrades field to RPC call getblockchaininfo Closes #2785. Co-authored-by: Jack Grigg --- src/rpcblockchain.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index bbed8cba1..ebd4a733a 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -659,6 +659,37 @@ static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* return rv; } +static UniValue NetworkUpgradeDesc(const Consensus::Params& consensusParams, Consensus::UpgradeIndex idx, int height) +{ + UniValue rv(UniValue::VOBJ); + auto upgrade = NetworkUpgradeInfo[idx]; + rv.push_back(Pair("name", upgrade.strName)); + rv.push_back(Pair("activationheight", consensusParams.vUpgrades[idx].nActivationHeight)); + switch (NetworkUpgradeState(height, consensusParams, idx)) { + case UPGRADE_DISABLED: rv.push_back(Pair("status", "disabled")); break; + case UPGRADE_PENDING: rv.push_back(Pair("status", "pending")); break; + case UPGRADE_ACTIVE: rv.push_back(Pair("status", "active")); break; + } + rv.push_back(Pair("info", upgrade.strInfo)); + return rv; +} + +void NetworkUpgradeDescPushBack( + UniValue& networkUpgrades, + const Consensus::Params& consensusParams, + Consensus::UpgradeIndex idx, + int height) +{ + // Network upgrades with an activation height of NO_ACTIVATION_HEIGHT are + // hidden. This is used when network upgrade implementations are merged + // without specifying the activation height. + if (consensusParams.vUpgrades[idx].nActivationHeight != Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) { + networkUpgrades.push_back(Pair( + HexInt(NetworkUpgradeInfo[idx].nBranchId), + NetworkUpgradeDesc(consensusParams, idx, height))); + } +} + UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -687,7 +718,15 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " },\n" " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" " }, ...\n" - " ]\n" + " ],\n" + " \"upgrades\": { (object) status of network upgrades\n" + " \"xxxx\" : { (string) branch ID of the upgrade\n" + " \"name\": \"xxxx\", (string) name of upgrade\n" + " \"activationheight\": xxxxxx, (numeric) block height of activation\n" + " \"status\": \"xxxx\", (string) status of upgrade\n" + " \"info\": \"xxxx\", (string) additional information about upgrade\n" + " }, ...\n" + " }\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblockchaininfo", "") @@ -722,6 +761,12 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); obj.push_back(Pair("softforks", softforks)); + UniValue upgrades(UniValue::VOBJ); + for (int i = Consensus::UPGRADE_OVERWINTER; i < Consensus::MAX_NETWORK_UPGRADES; i++) { + NetworkUpgradeDescPushBack(upgrades, consensusParams, Consensus::UpgradeIndex(i), tip->nHeight); + } + obj.push_back(Pair("upgrades", upgrades)); + if (fPruneMode) { CBlockIndex *block = chainActive.Tip(); From ed9aa2b62a9c65d152f7560368d407794caa6d72 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 21 Feb 2018 21:02:09 +0000 Subject: [PATCH 2/4] Add branch IDs for current and next block to getblockchaininfo Closes #2974. --- qa/rpc-tests/wallet_overwintertx.py | 8 ++++++++ src/rpcblockchain.cpp | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/qa/rpc-tests/wallet_overwintertx.py b/qa/rpc-tests/wallet_overwintertx.py index 84215eb6b..91bdb7764 100755 --- a/qa/rpc-tests/wallet_overwintertx.py +++ b/qa/rpc-tests/wallet_overwintertx.py @@ -38,6 +38,9 @@ class WalletOverwinterTxTest (BitcoinTestFramework): # # Currently at block 198. The next block to be mined 199 is a Sprout block # + assert_equal(self.nodes[0].getblockchaininfo()['consensus']['chaintip'], '00000000') + assert_equal(self.nodes[0].getblockchaininfo()['consensus']['nextblock'], '00000000') + taddr0 = self.nodes[0].getnewaddress() taddr2 = self.nodes[2].getnewaddress() zaddr2 = self.nodes[2].z_getnewaddress() @@ -76,6 +79,8 @@ class WalletOverwinterTxTest (BitcoinTestFramework): # # Currently at block 199. The next block to be mined 200 is an Overwinter block # + assert_equal(self.nodes[0].getblockchaininfo()['consensus']['chaintip'], '00000000') + assert_equal(self.nodes[0].getblockchaininfo()['consensus']['nextblock'], '5ba81b19') # Send taddr to taddr tsendamount = Decimal('4.56') @@ -88,9 +93,12 @@ class WalletOverwinterTxTest (BitcoinTestFramework): myopid = self.nodes[0].z_sendmany(taddr0, recipients) txid_shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + # Mine the first Overwinter block self.sync_all() self.nodes[0].generate(1) self.sync_all() + assert_equal(self.nodes[0].getblockchaininfo()['consensus']['chaintip'], '5ba81b19') + assert_equal(self.nodes[0].getblockchaininfo()['consensus']['nextblock'], '5ba81b19') # Verify balance assert_equal(self.nodes[3].getbalance(), tsendamount) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index ebd4a733a..32f3f0fee 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -726,6 +726,10 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"status\": \"xxxx\", (string) status of upgrade\n" " \"info\": \"xxxx\", (string) additional information about upgrade\n" " }, ...\n" + " },\n" + " \"consensus\": { (object) branch IDs of the current and upcoming consensus rules\n" + " \"chaintip\": \"xxxxxxxx\", (string) branch ID used to validate the current chain tip\n" + " \"nextblock\": \"xxxxxxxx\" (string) branch ID that the next block will be validated under\n" " }\n" "}\n" "\nExamples:\n" @@ -767,6 +771,11 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) } obj.push_back(Pair("upgrades", upgrades)); + UniValue consensus(UniValue::VOBJ); + consensus.push_back(Pair("chaintip", HexInt(CurrentEpochBranchId(tip->nHeight, consensusParams)))); + consensus.push_back(Pair("nextblock", HexInt(CurrentEpochBranchId(tip->nHeight + 1, consensusParams)))); + obj.push_back(Pair("consensus", consensus)); + if (fPruneMode) { CBlockIndex *block = chainActive.Tip(); From 4c3d2b3bbe05941e27ad1bc3bb8a29d8d7283a65 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 22 Feb 2018 13:44:40 +0000 Subject: [PATCH 3/4] Check upgrade status in wallet_overwintertx RPC test --- qa/rpc-tests/wallet_overwintertx.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/qa/rpc-tests/wallet_overwintertx.py b/qa/rpc-tests/wallet_overwintertx.py index 91bdb7764..bad99a528 100755 --- a/qa/rpc-tests/wallet_overwintertx.py +++ b/qa/rpc-tests/wallet_overwintertx.py @@ -38,8 +38,10 @@ class WalletOverwinterTxTest (BitcoinTestFramework): # # Currently at block 198. The next block to be mined 199 is a Sprout block # - assert_equal(self.nodes[0].getblockchaininfo()['consensus']['chaintip'], '00000000') - assert_equal(self.nodes[0].getblockchaininfo()['consensus']['nextblock'], '00000000') + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '00000000') + assert_equal(bci['consensus']['nextblock'], '00000000') + assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending') taddr0 = self.nodes[0].getnewaddress() taddr2 = self.nodes[2].getnewaddress() @@ -79,8 +81,10 @@ class WalletOverwinterTxTest (BitcoinTestFramework): # # Currently at block 199. The next block to be mined 200 is an Overwinter block # - assert_equal(self.nodes[0].getblockchaininfo()['consensus']['chaintip'], '00000000') - assert_equal(self.nodes[0].getblockchaininfo()['consensus']['nextblock'], '5ba81b19') + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '00000000') + assert_equal(bci['consensus']['nextblock'], '5ba81b19') + assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending') # Send taddr to taddr tsendamount = Decimal('4.56') @@ -97,8 +101,10 @@ class WalletOverwinterTxTest (BitcoinTestFramework): self.sync_all() self.nodes[0].generate(1) self.sync_all() - assert_equal(self.nodes[0].getblockchaininfo()['consensus']['chaintip'], '5ba81b19') - assert_equal(self.nodes[0].getblockchaininfo()['consensus']['nextblock'], '5ba81b19') + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '5ba81b19') + assert_equal(bci['consensus']['nextblock'], '5ba81b19') + assert_equal(bci['upgrades']['5ba81b19']['status'], 'active') # Verify balance assert_equal(self.nodes[3].getbalance(), tsendamount) From 50a90615af196d89f11da6e13527d323e1c03fe1 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 22 Feb 2018 14:01:43 +0000 Subject: [PATCH 4/4] Document that consensus.chaintip != consensus.nextblock just before an upgrade --- src/rpcblockchain.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 32f3f0fee..626c4724f 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -696,6 +696,8 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) throw runtime_error( "getblockchaininfo\n" "Returns an object containing various state info regarding block chain processing.\n" + "\nNote that when the chain tip is at the last block before a network upgrade activation,\n" + "consensus.chaintip != consensus.nextblock.\n" "\nResult:\n" "{\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" @@ -721,10 +723,10 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " ],\n" " \"upgrades\": { (object) status of network upgrades\n" " \"xxxx\" : { (string) branch ID of the upgrade\n" - " \"name\": \"xxxx\", (string) name of upgrade\n" + " \"name\": \"xxxx\", (string) name of upgrade\n" " \"activationheight\": xxxxxx, (numeric) block height of activation\n" - " \"status\": \"xxxx\", (string) status of upgrade\n" - " \"info\": \"xxxx\", (string) additional information about upgrade\n" + " \"status\": \"xxxx\", (string) status of upgrade\n" + " \"info\": \"xxxx\", (string) additional information about upgrade\n" " }, ...\n" " },\n" " \"consensus\": { (object) branch IDs of the current and upcoming consensus rules\n"