Skip to content

Commit edebf42

Browse files
committed
Merge #8489: Bugfix: Use pre-BIP141 sigops until segwit activates (GBT)
239cbd2 qa/rpc-tests/segwit: Test GBT sigops before and after activation (Luke Dashjr) 160f895 Bugfix: Use pre-BIP141 sigops until segwit activates (Luke Dashjr)
2 parents 484312b + 239cbd2 commit edebf42

File tree

2 files changed

+60
-9
lines changed

2 files changed

+60
-9
lines changed

qa/rpc-tests/segwit.py

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ def getutxo(txid):
6969
utxo["txid"] = txid
7070
return utxo
7171

72+
def find_unspent(node, min_value):
73+
for utxo in node.listunspent():
74+
if utxo['amount'] >= min_value:
75+
return utxo
76+
7277
class SegWitTest(BitcoinTestFramework):
7378

7479
def setup_chain(self):
@@ -117,8 +122,21 @@ def fail_mine(self, node, txid, sign, redeem_script=""):
117122
sync_blocks(self.nodes)
118123

119124
def run_test(self):
120-
self.nodes[0].generate(160) #block 160
121-
125+
self.nodes[0].generate(161) #block 161
126+
127+
print("Verify sigops are counted in GBT with pre-BIP141 rules before the fork")
128+
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
129+
tmpl = self.nodes[0].getblocktemplate({})
130+
assert(tmpl['sigoplimit'] == 20000)
131+
assert(tmpl['transactions'][0]['hash'] == txid)
132+
assert(tmpl['transactions'][0]['sigops'] == 2)
133+
tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']})
134+
assert(tmpl['sigoplimit'] == 20000)
135+
assert(tmpl['transactions'][0]['hash'] == txid)
136+
assert(tmpl['transactions'][0]['sigops'] == 2)
137+
self.nodes[0].generate(1) #block 162
138+
139+
balance_presetup = self.nodes[0].getbalance()
122140
self.pubkey = []
123141
p2sh_ids = [] # p2sh_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE embedded in p2sh
124142
wit_ids = [] # wit_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE via bare witness
@@ -137,18 +155,18 @@ def run_test(self):
137155
for i in range(5):
138156
for n in range(3):
139157
for v in range(2):
140-
wit_ids[n][v].append(send_to_witness(v, self.nodes[0], self.nodes[0].listunspent()[0], self.pubkey[n], False, Decimal("49.999")))
141-
p2sh_ids[n][v].append(send_to_witness(v, self.nodes[0], self.nodes[0].listunspent()[0], self.pubkey[n], True, Decimal("49.999")))
158+
wit_ids[n][v].append(send_to_witness(v, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[n], False, Decimal("49.999")))
159+
p2sh_ids[n][v].append(send_to_witness(v, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[n], True, Decimal("49.999")))
142160

143-
self.nodes[0].generate(1) #block 161
161+
self.nodes[0].generate(1) #block 163
144162
sync_blocks(self.nodes)
145163

146164
# Make sure all nodes recognize the transactions as theirs
147-
assert_equal(self.nodes[0].getbalance(), 60*50 - 60*50 + 20*Decimal("49.999") + 50)
165+
assert_equal(self.nodes[0].getbalance(), balance_presetup - 60*50 + 20*Decimal("49.999") + 50)
148166
assert_equal(self.nodes[1].getbalance(), 20*Decimal("49.999"))
149167
assert_equal(self.nodes[2].getbalance(), 20*Decimal("49.999"))
150168

151-
self.nodes[0].generate(262) #block 423
169+
self.nodes[0].generate(260) #block 423
152170
sync_blocks(self.nodes)
153171

154172
print("Verify default node can't accept any witness format txs before fork")
@@ -205,5 +223,25 @@ def run_test(self):
205223
self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], True) #block 434
206224
self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], True) #block 435
207225

226+
print("Verify sigops are counted in GBT with BIP141 rules after the fork")
227+
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
228+
tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']})
229+
assert(tmpl['sigoplimit'] == 80000)
230+
assert(tmpl['transactions'][0]['txid'] == txid)
231+
assert(tmpl['transactions'][0]['sigops'] == 8)
232+
233+
print("Verify non-segwit miners get a valid GBT response after the fork")
234+
send_to_witness(1, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[0], False, Decimal("49.998"))
235+
try:
236+
tmpl = self.nodes[0].getblocktemplate({})
237+
assert(len(tmpl['transactions']) == 1) # Doesn't include witness tx
238+
assert(tmpl['sigoplimit'] == 20000)
239+
assert(tmpl['transactions'][0]['hash'] == txid)
240+
assert(tmpl['transactions'][0]['sigops'] == 2)
241+
assert(('!segwit' in tmpl['rules']) or ('segwit' not in tmpl['rules']))
242+
except JSONRPCException:
243+
# This is an acceptable outcome
244+
pass
245+
208246
if __name__ == '__main__':
209247
SegWitTest().main()

src/rpc/mining.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
546546
UpdateTime(pblock, consensusParams, pindexPrev);
547547
pblock->nNonce = 0;
548548

549+
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
550+
const bool fPreSegWit = (THRESHOLD_ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache));
551+
549552
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
550553

551554
UniValue transactions(UniValue::VARR);
@@ -574,7 +577,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
574577

575578
int index_in_template = i - 1;
576579
entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
577-
entry.push_back(Pair("sigops", pblocktemplate->vTxSigOpsCost[index_in_template]));
580+
int64_t nTxSigOps = pblocktemplate->vTxSigOpsCost[index_in_template];
581+
if (fPreSegWit) {
582+
assert(nTxSigOps % WITNESS_SCALE_FACTOR == 0);
583+
nTxSigOps /= WITNESS_SCALE_FACTOR;
584+
}
585+
entry.push_back(Pair("sigops", nTxSigOps));
578586
entry.push_back(Pair("weight", GetTransactionWeight(tx)));
579587

580588
transactions.push_back(entry);
@@ -657,7 +665,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
657665
result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
658666
result.push_back(Pair("mutable", aMutable));
659667
result.push_back(Pair("noncerange", "00000000ffffffff"));
660-
result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS_COST));
668+
int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST;
669+
if (fPreSegWit) {
670+
assert(nSigOpLimit % WITNESS_SCALE_FACTOR == 0);
671+
nSigOpLimit /= WITNESS_SCALE_FACTOR;
672+
}
673+
result.push_back(Pair("sigoplimit", nSigOpLimit));
661674
result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE));
662675
result.push_back(Pair("weightlimit", (int64_t)MAX_BLOCK_WEIGHT));
663676
result.push_back(Pair("curtime", pblock->GetBlockTime()));

0 commit comments

Comments
 (0)