Skip to content

Commit 416809c

Browse files
committed
Merge #9955: Don't require segwit in getblocktemplate for segwit signalling or mining
c85ffe6 Test transaction selection when gbt called without segwit support (Suhas Daftuar) abe7b3d Don't require segwit in getblocktemplate for segwit signalling or mining (Suhas Daftuar) Tree-SHA512: 172496b6d7cdf1879de1266748f2b4ed9fd2ba9ff4a1fd964d74d73c674c16d74bf01a3ba42bf25f2d69f348217c0bbf3412ac64821f222efc9de25a287a5240
2 parents 2c781fb + c85ffe6 commit 416809c

File tree

6 files changed

+73
-16
lines changed

6 files changed

+73
-16
lines changed

qa/rpc-tests/p2p-segwit.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,9 +1698,11 @@ def test_getblocktemplate_before_lockin(self):
16981698
for node in [self.nodes[0], self.nodes[2]]:
16991699
gbt_results = node.getblocktemplate()
17001700
block_version = gbt_results['version']
1701-
# If we're not indicating segwit support, we should not be signalling
1702-
# for segwit activation, nor should we get a witness commitment.
1703-
assert_equal(block_version & (1 << VB_WITNESS_BIT), 0)
1701+
# If we're not indicating segwit support, we will still be
1702+
# signalling for segwit activation.
1703+
assert_equal((block_version & (1 << VB_WITNESS_BIT) != 0), node == self.nodes[0])
1704+
# If we don't specify the segwit rule, then we won't get a default
1705+
# commitment.
17041706
assert('default_witness_commitment' not in gbt_results)
17051707

17061708
# Workaround:

qa/rpc-tests/segwit.py

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
from test_framework.util import *
99
from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut, COIN
1010
from test_framework.address import script_to_p2sh, key_to_p2pkh
11-
from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG, hash160
11+
from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG, hash160, OP_TRUE
1212
from io import BytesIO
13-
from test_framework.mininode import FromHex, ToHex
13+
from test_framework.mininode import ToHex, FromHex, COIN
1414

1515
NODE_0 = 0
1616
NODE_1 = 1
@@ -250,9 +250,54 @@ def run_test(self):
250250
assert(tmpl['transactions'][0]['txid'] == txid)
251251
assert(tmpl['transactions'][0]['sigops'] == 8)
252252

253-
self.log.info("Non-segwit miners are not able to use GBT response after activation.")
254-
send_to_witness(1, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[0], False, Decimal("49.998"))
255-
assert_raises_jsonrpc(-8, "Support for 'segwit' rule requires explicit client support", self.nodes[0].getblocktemplate, {})
253+
self.nodes[0].generate(1) # Mine a block to clear the gbt cache
254+
255+
self.log.info("Non-segwit miners are able to use GBT response after activation.")
256+
# Create a 3-tx chain: tx1 (non-segwit input, paying to a segwit output) ->
257+
# tx2 (segwit input, paying to a non-segwit output) ->
258+
# tx3 (non-segwit input, paying to a non-segwit output).
259+
# tx1 is allowed to appear in the block, but no others.
260+
txid1 = send_to_witness(1, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[0], False, Decimal("49.996"))
261+
hex_tx = self.nodes[0].gettransaction(txid)['hex']
262+
tx = FromHex(CTransaction(), hex_tx)
263+
assert(tx.wit.is_null()) # This should not be a segwit input
264+
assert(txid1 in self.nodes[0].getrawmempool())
265+
266+
# Now create tx2, which will spend from txid1.
267+
tx = CTransaction()
268+
tx.vin.append(CTxIn(COutPoint(int(txid1, 16), 0), b''))
269+
tx.vout.append(CTxOut(int(49.99*COIN), CScript([OP_TRUE])))
270+
tx2_hex = self.nodes[0].signrawtransaction(ToHex(tx))['hex']
271+
txid2 = self.nodes[0].sendrawtransaction(tx2_hex)
272+
tx = FromHex(CTransaction(), tx2_hex)
273+
assert(not tx.wit.is_null())
274+
275+
# Now create tx3, which will spend from txid2
276+
tx = CTransaction()
277+
tx.vin.append(CTxIn(COutPoint(int(txid2, 16), 0), b""))
278+
tx.vout.append(CTxOut(int(49.95*COIN), CScript([OP_TRUE]))) # Huge fee
279+
tx.calc_sha256()
280+
txid3 = self.nodes[0].sendrawtransaction(ToHex(tx))
281+
assert(tx.wit.is_null())
282+
assert(txid3 in self.nodes[0].getrawmempool())
283+
284+
# Now try calling getblocktemplate() without segwit support.
285+
template = self.nodes[0].getblocktemplate()
286+
287+
# Check that tx1 is the only transaction of the 3 in the template.
288+
template_txids = [ t['txid'] for t in template['transactions'] ]
289+
assert(txid2 not in template_txids and txid3 not in template_txids)
290+
assert(txid1 in template_txids)
291+
292+
# Check that running with segwit support results in all 3 being included.
293+
template = self.nodes[0].getblocktemplate({"rules": ["segwit"]})
294+
template_txids = [ t['txid'] for t in template['transactions'] ]
295+
assert(txid1 in template_txids)
296+
assert(txid2 in template_txids)
297+
assert(txid3 in template_txids)
298+
299+
# Mine a block to clear the gbt cache again.
300+
self.nodes[0].generate(1)
256301

257302
self.log.info("Verify behaviour of importaddress, addwitnessaddress and listunspent")
258303

src/miner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ void BlockAssembler::resetBlock()
137137
nFees = 0;
138138
}
139139

140-
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
140+
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx)
141141
{
142142
resetBlock();
143143

@@ -175,7 +175,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
175175
// -promiscuousmempoolflags is used.
176176
// TODO: replace this with a call to main to assess validity of a mempool
177177
// transaction (which in most cases can be a no-op).
178-
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
178+
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()) && fMineWitnessTx;
179179

180180
addPackageTxs();
181181

src/miner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class BlockAssembler
170170
BlockAssembler(const CChainParams& params, const Options& options);
171171

172172
/** Construct a new block template with coinbase to scriptPubKeyIn */
173-
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
173+
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx=true);
174174

175175
private:
176176
// utility functions

src/rpc/mining.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,12 +514,22 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
514514
// TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
515515
}
516516

517+
const struct BIP9DeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT];
518+
// If the caller is indicating segwit support, then allow CreateNewBlock()
519+
// to select witness transactions, after segwit activates (otherwise
520+
// don't).
521+
bool fSupportsSegwit = setClientRules.find(segwit_info.name) != setClientRules.end();
522+
517523
// Update block
518524
static CBlockIndex* pindexPrev;
519525
static int64_t nStart;
520526
static std::unique_ptr<CBlockTemplate> pblocktemplate;
527+
// Cache whether the last invocation was with segwit support, to avoid returning
528+
// a segwit-block to a non-segwit caller.
529+
static bool fLastTemplateSupportsSegwit = true;
521530
if (pindexPrev != chainActive.Tip() ||
522-
(mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
531+
(mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5) ||
532+
fLastTemplateSupportsSegwit != fSupportsSegwit)
523533
{
524534
// Clear pindexPrev so future calls make a new block, despite any failures from here on
525535
pindexPrev = nullptr;
@@ -528,10 +538,11 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
528538
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
529539
CBlockIndex* pindexPrevNew = chainActive.Tip();
530540
nStart = GetTime();
541+
fLastTemplateSupportsSegwit = fSupportsSegwit;
531542

532543
// Create new block
533544
CScript scriptDummy = CScript() << OP_TRUE;
534-
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy);
545+
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fSupportsSegwit);
535546
if (!pblocktemplate)
536547
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
537548

@@ -681,8 +692,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
681692
result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
682693
result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
683694

684-
const struct BIP9DeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT];
685-
if (!pblocktemplate->vchCoinbaseCommitment.empty() && setClientRules.find(segwit_info.name) != setClientRules.end()) {
695+
if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) {
686696
result.push_back(Pair("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end())));
687697
}
688698

src/versionbits.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION
1717
},
1818
{
1919
/*.name =*/ "segwit",
20-
/*.gbt_force =*/ false,
20+
/*.gbt_force =*/ true,
2121
}
2222
};
2323

0 commit comments

Comments
 (0)