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-magnetic-anomaly-mining.py b/test/functional/abc-magnetic-anomaly-mining.py
--- a/test/functional/abc-magnetic-anomaly-mining.py
+++ b/test/functional/abc-magnetic-anomaly-mining.py
@@ -98,7 +98,6 @@
tmpl = mining_node.getblocktemplate()
assert 'proposal' in tmpl['capabilities']
- assert 'coinbasetxn' not in tmpl
# Check the template transaction metadata and ordering
last_txid = 0
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
@@ -22,6 +22,7 @@
from decimal import Decimal
AXION_ACTIVATION_TIME = 2000000600
+MINER_FUND_ADDR = 'bchreg:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgd35g0pkl'
class AbcMiningRPCTest(BitcoinTestFramework):
@@ -36,13 +37,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):
@@ -55,6 +49,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]
@@ -66,6 +77,11 @@
# them are covered in mining_basic.py
assert_equal(node.getmempoolinfo()['size'], 0)
assert_getblocktemplate({
+ 'coinbasetxn': {
+ # We expect to start seeing the miner fund addresses since the
+ # next block will start enforcing them.
+ 'minerfundaddresses': [MINER_FUND_ADDR],
+ },
# Although the coinbase value need not necessarily be the same as
# the last block due to halvings and fees, we know this to be true
# since we are not crossing a halving boundary and there are no
@@ -86,6 +102,9 @@
assert_equal(total, block_reward)
assert_getblocktemplate({
+ 'coinbasetxn': {
+ 'minerfundaddresses': [MINER_FUND_ADDR],
+ },
# Again, we assume the coinbase value is the same as prior blocks.
'coinbasevalue': block_reward * COIN,
'mintime': AXION_ACTIVATION_TIME + 1,
@@ -95,6 +114,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,
})
diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py
--- a/test/functional/mining_basic.py
+++ b/test/functional/mining_basic.py
@@ -90,7 +90,6 @@
tmpl = node.getblocktemplate()
self.log.info("getblocktemplate: Test capability advertised")
assert 'proposal' in tmpl['capabilities']
- assert 'coinbasetxn' not in tmpl
next_height = int(tmpl["height"])
coinbase_tx = create_coinbase(height=next_height)