Page MenuHomePhabricator

D17658.id.diff
No OneTemporary

D17658.id.diff

diff --git a/doc/release-notes.md b/doc/release-notes.md
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -4,4 +4,9 @@
<https://download.bitcoinabc.org/0.30.11/>
-This is a maintenance release with no user-visible change.
+This release includes the following features and fixes:
+ - A new init option `simplegbt` can be enabled to change the output of the
+ `getblocktemplate` call to return the miner fund and staking reward data in a
+ simplified output format. Please refer to the `getblocktemplate` documentation
+ for more details. This option is disabled by default so there is no change in
+ behavior unless it's explicitly opted in.
diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1255,6 +1255,9 @@
"be included in block creation. (default: %s)",
ticker, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE_PER_KB)),
ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
+ argsman.AddArg("-simplegbt",
+ "Use a simplified getblocktemplate output (default: 0)",
+ ArgsManager::ALLOW_BOOL, OptionsCategory::BLOCK_CREATION);
argsman.AddArg("-blockversion=<n>",
"Override block version to test forking scenarios",
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -34,6 +34,7 @@
#include <rpc/util.h>
#include <script/descriptor.h>
#include <script/script.h>
+#include <script/standard.h>
#include <shutdown.h>
#include <timedata.h>
#include <txmempool.h>
@@ -747,7 +748,8 @@
{
{RPCResult::Type::OBJ,
"minerfund",
- "information related to the coinbase miner fund",
+ "information related to the coinbase miner fund."
+ "This will NOT be set if -simplegbt is enabled",
{
{RPCResult::Type::ARR,
@@ -766,10 +768,10 @@
{RPCResult::Type::OBJ,
"stakingrewards",
"information related to the coinbase staking reward "
- "output, only set after the Nov. 15, 2023 upgrade "
- "activated and the -avalanchestakingrewards option "
- "is "
- "enabled",
+ "output, only set if the -avalanchestakingrewards "
+ "option is enabled and if the node is able to "
+ "determine a winner. This will NOT be set if "
+ "-simplegbt is enabled",
{
{RPCResult::Type::OBJ,
"payoutscript",
@@ -847,6 +849,34 @@
{RPCResult::Type::STR_HEX, "nexttarget",
"The real-time target in compact format"},
}},
+ {RPCResult::Type::OBJ,
+ "minerfund",
+ "information related to the coinbase miner fund."
+ "This will ONLY be set if -simplegbt is enabled",
+ {
+ {RPCResult::Type::STR_HEX, "script",
+ "The scriptpubkey for the miner fund output in "
+ "hex format"},
+ {RPCResult::Type::STR_AMOUNT, "amount",
+ "The minimum value the miner fund output must "
+ "pay in satoshis"},
+
+ }},
+ {RPCResult::Type::OBJ,
+ "stakingrewards",
+ "information related to the coinbase staking reward "
+ "output, only set if the -avalanchestakingrewards "
+ "option is enabled and if the node is able to "
+ "determine a winner. This will ONLY be set if "
+ "-simplegbt is enabled",
+ {
+ {RPCResult::Type::STR_HEX, "script",
+ "The scriptpubkey for the staking reward "
+ "output in hex format"},
+ {RPCResult::Type::STR_AMOUNT, "amount",
+ "The minimum value the staking reward output must "
+ "pay in satoshis"},
+ }},
}},
},
RPCExamples{HelpExampleCli("getblocktemplate", "") +
@@ -855,6 +885,7 @@
const JSONRPCRequest &request) -> UniValue {
NodeContext &node = EnsureAnyNodeContext(request.context);
ChainstateManager &chainman = EnsureChainman(node);
+ ArgsManager &argsman = EnsureArgsman(node);
LOCK(cs_main);
const CChainParams &chainparams = config.GetChainParams();
@@ -1090,15 +1121,15 @@
index_in_template++;
}
- UniValue aux(UniValue::VOBJ);
+ const bool simplifyGbt = argsman.GetBoolArg("-simplegbt", false);
- UniValue minerFundList(UniValue::VARR);
- for (const auto &fundDestination :
- GetMinerFundWhitelist(consensusParams)) {
- minerFundList.push_back(
- EncodeDestination(fundDestination, config));
- }
+ UniValue result(UniValue::VOBJ);
+ UniValue aux(UniValue::VOBJ);
+ UniValue coinbasetxn(UniValue::VOBJ);
+ // Compute the miner fund parameters
+ const auto minerFundWhitelist =
+ GetMinerFundWhitelist(consensusParams);
int64_t minerFundMinValue = 0;
if (IsAxionEnabled(consensusParams, pindexPrev)) {
minerFundMinValue =
@@ -1107,30 +1138,61 @@
SATOSHI);
}
- UniValue minerFund(UniValue::VOBJ);
- minerFund.pushKV("addresses", minerFundList);
- minerFund.pushKV("minimumvalue", minerFundMinValue);
-
- UniValue coinbasetxn(UniValue::VOBJ);
- coinbasetxn.pushKV("minerfund", minerFund);
-
+ // Compute the staking reward parameters
std::vector<CScript> stakingRewardsPayoutScripts;
+ int64_t stakingRewardsAmount =
+ GetStakingRewardsAmount(coinbasevalue) / SATOSHI;
if (node.avalanche &&
- IsStakingRewardsActivated(consensusParams, pindexPrev) &&
- node.avalanche->getStakingRewardWinners(
- pindexPrev->GetBlockHash(), stakingRewardsPayoutScripts)) {
- UniValue stakingRewards(UniValue::VOBJ);
- UniValue stakingRewardsPayoutScriptObj(UniValue::VOBJ);
- ScriptPubKeyToUniv(stakingRewardsPayoutScripts[0],
- stakingRewardsPayoutScriptObj,
- /*fIncludeHex=*/true);
- stakingRewards.pushKV("payoutscript",
- stakingRewardsPayoutScriptObj);
- stakingRewards.pushKV(
- "minimumvalue",
- int64_t(GetStakingRewardsAmount(coinbasevalue) / SATOSHI));
-
- coinbasetxn.pushKV("stakingrewards", stakingRewards);
+ IsStakingRewardsActivated(consensusParams, pindexPrev)) {
+ if (!node.avalanche->getStakingRewardWinners(
+ pindexPrev->GetBlockHash(),
+ stakingRewardsPayoutScripts)) {
+ stakingRewardsPayoutScripts.clear();
+ }
+ }
+
+ if (simplifyGbt) {
+ UniValue minerFund(UniValue::VOBJ);
+ if (!minerFundWhitelist.empty()) {
+ minerFund.pushKV("script",
+ HexStr(GetScriptForDestination(
+ *minerFundWhitelist.begin())));
+ minerFund.pushKV("amount", minerFundMinValue);
+ }
+ result.pushKV("minerfund", minerFund);
+
+ if (!stakingRewardsPayoutScripts.empty()) {
+ UniValue stakingRewards(UniValue::VOBJ);
+ stakingRewards.pushKV(
+ "script", HexStr(stakingRewardsPayoutScripts[0]));
+ stakingRewards.pushKV("amount", stakingRewardsAmount);
+ result.pushKV("stakingrewards", stakingRewards);
+ }
+ } else {
+ UniValue minerFund(UniValue::VOBJ);
+ UniValue minerFundList(UniValue::VARR);
+ for (const auto &fundDestination : minerFundWhitelist) {
+ minerFundList.push_back(
+ EncodeDestination(fundDestination, config));
+ }
+
+ minerFund.pushKV("addresses", minerFundList);
+ minerFund.pushKV("minimumvalue", minerFundMinValue);
+
+ coinbasetxn.pushKV("minerfund", minerFund);
+
+ if (!stakingRewardsPayoutScripts.empty()) {
+ UniValue stakingRewards(UniValue::VOBJ);
+ UniValue stakingRewardsPayoutScriptObj(UniValue::VOBJ);
+ ScriptPubKeyToUniv(stakingRewardsPayoutScripts[0],
+ stakingRewardsPayoutScriptObj,
+ /*fIncludeHex=*/true);
+ stakingRewards.pushKV("payoutscript",
+ stakingRewardsPayoutScriptObj);
+ stakingRewards.pushKV("minimumvalue", stakingRewardsAmount);
+
+ coinbasetxn.pushKV("stakingrewards", stakingRewards);
+ }
}
arith_uint256 hashTarget =
@@ -1141,7 +1203,6 @@
aMutable.push_back("transactions");
aMutable.push_back("prevblock");
- UniValue result(UniValue::VOBJ);
result.pushKV("capabilities", aCaps);
result.pushKV("version", pblock->nVersion);
diff --git a/test/functional/abc_mining_basic.py b/test/functional/abc_mining_basic.py
--- a/test/functional/abc_mining_basic.py
+++ b/test/functional/abc_mining_basic.py
@@ -5,6 +5,7 @@
Tests for Bitcoin ABC mining RPCs
"""
+from test_framework.address import SCRIPT_UNSPENDABLE_HEX
from test_framework.cdefs import (
BLOCK_MAXBYTES_MAXSIGCHECKS_RATIO,
DEFAULT_MAX_BLOCK_SIZE,
@@ -18,6 +19,7 @@
MINER_FUND_LEGACY_ADDR = "2NCXTUCFd1Q3EteVpVVDTrBBoKqvMPAoeEn"
MINER_FUND_RATIO = 32
+STAKING_REWARD_RATIO = 10
class AbcMiningRPCTest(BitcoinTestFramework):
@@ -84,6 +86,55 @@
}
)
+ def test_simplified_gbt(self):
+ self.restart_node(
+ 0, extra_args=["-enableminerfund", "-avalanchestakingrewards"]
+ )
+
+ node = self.nodes[0]
+ node.add_p2p_connection(P2PInterface())
+
+ # Force a staking reward winner so we have an block template output
+ node.setstakingreward(node.getbestblockhash(), SCRIPT_UNSPENDABLE_HEX)
+
+ gbt = node.getblocktemplate()
+ assert "minerfund" not in gbt
+ assert "stakingrewards" not in gbt
+ assert "minerfund" in gbt["coinbasetxn"]
+ assert "stakingrewards" in gbt["coinbasetxn"]
+
+ self.restart_node(
+ 0,
+ extra_args=["-enableminerfund", "-avalanchestakingrewards", "-simplegbt"],
+ )
+
+ node.add_p2p_connection(P2PInterface())
+
+ node.setstakingreward(node.getbestblockhash(), SCRIPT_UNSPENDABLE_HEX)
+
+ gbt = node.getblocktemplate()
+ assert "minerfund" in gbt
+ assert "stakingrewards" in gbt
+ assert "minerfund" not in gbt["coinbasetxn"]
+ assert "stakingrewards" not in gbt["coinbasetxn"]
+
+ coinbase = node.getblock(node.getbestblockhash(), 2)["tx"][0]
+ block_reward = sum([vout["value"] for vout in coinbase["vout"]])
+
+ assert_equal(
+ gbt["minerfund"]["script"],
+ node.validateaddress(MINER_FUND_ADDR)["scriptPubKey"],
+ )
+ assert_equal(
+ gbt["minerfund"]["amount"], block_reward * MINER_FUND_RATIO // 100 * XEC
+ )
+
+ assert_equal(gbt["stakingrewards"]["script"], SCRIPT_UNSPENDABLE_HEX)
+ assert_equal(
+ gbt["stakingrewards"]["amount"],
+ block_reward * STAKING_REWARD_RATIO // 100 * XEC,
+ )
+
def run_test(self):
self.run_for_node(
self.nodes[0],
@@ -93,6 +144,7 @@
self.nodes[1],
MINER_FUND_LEGACY_ADDR,
)
+ self.test_simplified_gbt()
if __name__ == "__main__":
diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py
--- a/test/functional/test_framework/address.py
+++ b/test/functional/test_framework/address.py
@@ -14,9 +14,8 @@
ADDRESS_ECREG_UNSPENDABLE_DESCRIPTOR = (
"addr(ecregtest:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqcrl5mqkt)#u6xx93xc"
)
-SCRIPT_UNSPENDABLE = CScript.fromhex(
- "76a914000000000000000000000000000000000000000088ac"
-)
+SCRIPT_UNSPENDABLE_HEX = "76a914000000000000000000000000000000000000000088ac"
+SCRIPT_UNSPENDABLE = CScript.fromhex(SCRIPT_UNSPENDABLE_HEX)
# Coins sent to this address can be spent with a scriptSig of just OP_TRUE
ADDRESS_ECREG_P2SH_OP_TRUE = "ecregtest:prdpw30fk4ym6zl6rftfjuw806arpn26fvkgfu97xt"

File Metadata

Mime Type
text/plain
Expires
Tue, May 20, 19:04 (3 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5864846
Default Alt Text
D17658.id.diff (13 KB)

Event Timeline