Skip to content

Commit a916677

Browse files
committed
Merge #8815: Backports for 0.13.1
9dfa0c8 Implement NULLDUMMY softfork (Johnson Lau) cef633c Fix broken sendcmpct test in p2p-compactblocks.py (Suhas Daftuar) fb8706e Add p2p test for BIP 152 (compact blocks) (Suhas Daftuar) f6be478 Add support for compactblocks to mininode (Suhas Daftuar) 4295a7a Tests: refactor compact size serialization in mininode (Suhas Daftuar) ff893aa Implement SipHash in Python (Pieter Wuille) 198494c Allow changing BIP9 parameters on regtest (Suhas Daftuar) 23feab1 Remove maxuploadtargets recommended minimum (Jonas Schnelli) a5ec248 Remove createwitnessaddress (Johnson Lau) b394a96 Add basic test for IsStandard witness transaction blinding (instagibbs) 1672225 Do not store witness txn in rejection cache (Pieter Wuille)
2 parents 254e990 + 9dfa0c8 commit a916677

File tree

14 files changed

+1222
-129
lines changed

14 files changed

+1222
-129
lines changed

doc/reduce-traffic.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ This is *not* a hard limit; only a threshold to minimize the outbound
1919
traffic. When the limit is about to be reached, the uploaded data is cut by no
2020
longer serving historic blocks (blocks older than one week).
2121
Keep in mind that new nodes require other nodes that are willing to serve
22-
historic blocks. **The recommended minimum is 144 blocks per day (max. 144MB
23-
per day)**
22+
historic blocks.
2423

2524
Whitelisted peers will never be disconnected, although their traffic counts for
2625
calculating the target.

qa/pull-tester/rpc-tests.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@
142142
'segwit.py',
143143
'importprunedfunds.py',
144144
'signmessages.py',
145+
'p2p-compactblocks.py',
146+
'nulldummy.py',
145147
]
146148
if ENABLE_ZMQ:
147149
testScripts.append('zmq_test.py')

qa/rpc-tests/nulldummy.py

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2016 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
from test_framework.test_framework import ComparisonTestFramework
7+
from test_framework.util import *
8+
from test_framework.mininode import CTransaction, NetworkThread
9+
from test_framework.blocktools import create_coinbase, create_block, add_witness_commitment
10+
from test_framework.comptool import TestManager
11+
from test_framework.script import CScript
12+
from io import BytesIO
13+
import time
14+
15+
NULLDUMMY_ERROR = "64: non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)"
16+
17+
def trueDummy(tx):
18+
scriptSig = CScript(tx.vin[0].scriptSig)
19+
newscript = []
20+
for i in scriptSig:
21+
if (len(newscript) == 0):
22+
assert(len(i) == 0)
23+
newscript.append(b'\x51')
24+
else:
25+
newscript.append(i)
26+
tx.vin[0].scriptSig = CScript(newscript)
27+
tx.rehash()
28+
29+
'''
30+
This test is meant to exercise NULLDUMMY softfork.
31+
Connect to a single node.
32+
Generate 2 blocks (save the coinbases for later).
33+
Generate 427 more blocks.
34+
[Policy/Consensus] Check that NULLDUMMY compliant transactions are accepted in the 430th block.
35+
[Policy] Check that non-NULLDUMMY transactions are rejected before activation.
36+
[Consensus] Check that the new NULLDUMMY rules are not enforced on the 431st block.
37+
[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block.
38+
'''
39+
40+
class NULLDUMMYTest(ComparisonTestFramework):
41+
42+
def __init__(self):
43+
super().__init__()
44+
self.num_nodes = 1
45+
46+
def setup_network(self):
47+
# Must set the blockversion for this test
48+
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
49+
extra_args=[['-debug', '-whitelist=127.0.0.1', '-walletprematurewitness']])
50+
51+
def run_test(self):
52+
self.address = self.nodes[0].getnewaddress()
53+
self.ms_address = self.nodes[0].addmultisigaddress(1,[self.address])
54+
self.wit_address = self.nodes[0].addwitnessaddress(self.address)
55+
self.wit_ms_address = self.nodes[0].addwitnessaddress(self.ms_address)
56+
57+
test = TestManager(self, self.options.tmpdir)
58+
test.add_all_connections(self.nodes)
59+
NetworkThread().start() # Start up network handling in another thread
60+
self.coinbase_blocks = self.nodes[0].generate(2) # Block 2
61+
coinbase_txid = []
62+
for i in self.coinbase_blocks:
63+
coinbase_txid.append(self.nodes[0].getblock(i)['tx'][0])
64+
self.nodes[0].generate(427) # Block 429
65+
self.lastblockhash = self.nodes[0].getbestblockhash()
66+
self.tip = int("0x" + self.lastblockhash, 0)
67+
self.lastblockheight = 429
68+
self.lastblocktime = int(time.time()) + 429
69+
70+
print ("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]")
71+
test1txs = [self.create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)]
72+
txid1 = self.tx_submit(self.nodes[0], test1txs[0])
73+
test1txs.append(self.create_transaction(self.nodes[0], txid1, self.ms_address, 48))
74+
txid2 = self.tx_submit(self.nodes[0], test1txs[1])
75+
test1txs.append(self.create_transaction(self.nodes[0], coinbase_txid[1], self.wit_ms_address, 49))
76+
txid3 = self.tx_submit(self.nodes[0], test1txs[2])
77+
self.block_submit(self.nodes[0], test1txs, False, True)
78+
79+
print ("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation")
80+
test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 48)
81+
trueDummy(test2tx)
82+
txid4 = self.tx_submit(self.nodes[0], test2tx, NULLDUMMY_ERROR)
83+
84+
print ("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]")
85+
self.block_submit(self.nodes[0], [test2tx], False, True)
86+
87+
print ("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation")
88+
test4tx = self.create_transaction(self.nodes[0], txid4, self.address, 47)
89+
test6txs=[CTransaction(test4tx)]
90+
trueDummy(test4tx)
91+
self.tx_submit(self.nodes[0], test4tx, NULLDUMMY_ERROR)
92+
self.block_submit(self.nodes[0], [test4tx])
93+
94+
print ("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation")
95+
test5tx = self.create_transaction(self.nodes[0], txid3, self.wit_address, 48)
96+
test6txs.append(CTransaction(test5tx))
97+
test5tx.wit.vtxinwit[0].scriptWitness.stack[0] = b'\x01'
98+
self.tx_submit(self.nodes[0], test5tx, NULLDUMMY_ERROR)
99+
self.block_submit(self.nodes[0], [test5tx], True)
100+
101+
print ("Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [432]")
102+
for i in test6txs:
103+
self.tx_submit(self.nodes[0], i)
104+
self.block_submit(self.nodes[0], test6txs, True, True)
105+
106+
107+
def create_transaction(self, node, txid, to_address, amount):
108+
inputs = [{ "txid" : txid, "vout" : 0}]
109+
outputs = { to_address : amount }
110+
rawtx = node.createrawtransaction(inputs, outputs)
111+
signresult = node.signrawtransaction(rawtx)
112+
tx = CTransaction()
113+
f = BytesIO(hex_str_to_bytes(signresult['hex']))
114+
tx.deserialize(f)
115+
return tx
116+
117+
118+
def tx_submit(self, node, tx, msg = ""):
119+
tx.rehash()
120+
try:
121+
node.sendrawtransaction(bytes_to_hex_str(tx.serialize_with_witness()), True)
122+
except JSONRPCException as exp:
123+
assert_equal(exp.error["message"], msg)
124+
return tx.hash
125+
126+
127+
def block_submit(self, node, txs, witness = False, accept = False):
128+
block = create_block(self.tip, create_coinbase(self.lastblockheight + 1), self.lastblocktime + 1)
129+
block.nVersion = 4
130+
for tx in txs:
131+
tx.rehash()
132+
block.vtx.append(tx)
133+
block.hashMerkleRoot = block.calc_merkle_root()
134+
witness and add_witness_commitment(block)
135+
block.rehash()
136+
block.solve()
137+
node.submitblock(bytes_to_hex_str(block.serialize(True)))
138+
if (accept):
139+
assert_equal(node.getbestblockhash(), block.hash)
140+
self.tip = block.sha256
141+
self.lastblockhash = block.hash
142+
self.lastblocktime += 1
143+
self.lastblockheight += 1
144+
else:
145+
assert_equal(node.getbestblockhash(), self.lastblockhash)
146+
147+
if __name__ == '__main__':
148+
NULLDUMMYTest().main()

0 commit comments

Comments
 (0)