diff --git a/doc/release-notes.md b/doc/release-notes.md
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -3,3 +3,6 @@
This release includes the following features and fixes:
+
+ - New `minerfundaddresses` subfield of `coinbasetxn` in `getblocktemplate` to
+ enable easy fetching of valid addresses for infrastructure funding.
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -5,6 +5,7 @@
#include
#include
+#include
#include
#include
#include
@@ -14,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -657,6 +659,15 @@
UniValue aux(UniValue::VOBJ);
aux.pushKV("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()));
+ UniValue coinbasetxn(UniValue::VOBJ);
+ UniValue minerFundList(UniValue::VARR);
+ for (auto fundDestination : GetMinerFundWhitelist(
+ config.GetChainParams().GetConsensus(), pindexPrev)) {
+ minerFundList.push_back(
+ EncodeCashAddr(fundDestination, config.GetChainParams()));
+ }
+ coinbasetxn.pushKV("minerfundaddresses", minerFundList);
+
arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
UniValue aMutable(UniValue::VARR);
@@ -672,6 +683,7 @@
result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex());
result.pushKV("transactions", transactions);
result.pushKV("coinbaseaux", aux);
+ result.pushKV("coinbasetxn", coinbasetxn);
result.pushKV("coinbasevalue", int64_t(coinbasevalue / SATOSHI));
result.pushKV("longpollid", ::ChainActive().Tip()->GetBlockHash().GetHex() +
i64tostr(nTransactionsUpdatedLast));
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
@@ -17,6 +17,7 @@
from decimal import Decimal
AXION_ACTIVATION_TIME = 2000000600
+MINER_FUND_ADDR = 'bchreg:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgd35g0pkl'
class AbcMiningRPCTest(BitcoinTestFramework):
@@ -31,13 +32,6 @@
node = self.nodes[0]
address = node.get_deterministic_priv_key().address
- # Move MTP forward to axion activation
- node.setmocktime(AXION_ACTIVATION_TIME)
- node.generatetoaddress(6, address)
- assert_equal(
- node.getblockchaininfo()['mediantime'],
- AXION_ACTIVATION_TIME)
-
# Assert the results of getblocktemplate have expected values. Keys not
# in 'expected' are not checked.
def assert_getblocktemplate(expected):
@@ -50,6 +44,23 @@
for key, value in expected.items():
assert_equal(blockTemplate[key], value)
+ # Move block time to just before axion activation
+ node.setmocktime(AXION_ACTIVATION_TIME)
+ node.generatetoaddress(5, address)
+
+ # Before axion activation, the miner fund list is empty
+ assert_getblocktemplate({
+ 'coinbasetxn': {
+ 'minerfundaddresses': [],
+ },
+ })
+
+ # Move MTP forward to axion activation
+ node.generatetoaddress(1, address)
+ assert_equal(
+ node.getblockchaininfo()['mediantime'],
+ AXION_ACTIVATION_TIME)
+
def get_best_coinbase():
return node.getblock(node.getbestblockhash(), 2)['tx'][0]
@@ -60,6 +71,11 @@
# We don't need to test all fields in getblocktemplate since many of
# them are covered in mining_basic.py
assert_getblocktemplate({
+ 'coinbasetxn': {
+ # We expect to start seeing the miner fund addresses since the
+ # next block will start enforcing them.
+ 'minerfundaddresses': [MINER_FUND_ADDR],
+ },
'coinbasevalue': block_reward * COIN,
'mintime': AXION_ACTIVATION_TIME + 1,
})
@@ -76,6 +92,9 @@
assert_equal(total, block_reward)
assert_getblocktemplate({
+ 'coinbasetxn': {
+ 'minerfundaddresses': [MINER_FUND_ADDR],
+ },
'coinbasevalue': block_reward * COIN,
'mintime': AXION_ACTIVATION_TIME + 1,
})
@@ -84,6 +103,9 @@
node.setmocktime(AXION_ACTIVATION_TIME + 1)
node.generatetoaddress(6, address)
assert_getblocktemplate({
+ 'coinbasetxn': {
+ 'minerfundaddresses': [MINER_FUND_ADDR],
+ },
'coinbasevalue': block_reward * COIN,
'mintime': AXION_ACTIVATION_TIME + 2,
})