def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature, bitno): # generate some coins for later self.coinbase_blocks = self.nodes[0].generate(2) self.height = 3 # height of the next block to build self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) self.nodeaddress = self.nodes[0].getnewaddress() self.last_block_time = int(time.time()) assert_equal(self.get_bip9_status(bipName)['status'], 'defined') tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) assert (bipName not in tmpl['vbavailable']) assert_equal(tmpl['vbrequired'], 0) assert_equal(tmpl['version'], 0x20000000) # Test 1 # Advance from DEFINED to STARTED test_blocks = self.generate_blocks(141, 4) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'started') tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) assert_equal(tmpl['vbavailable'][bipName], bitno) assert_equal(tmpl['vbrequired'], 0) assert (tmpl['version'] & activated_version) # Test 2 # Fail to achieve LOCKED_IN 100 out of 144 signal bit 1 # using a variety of bits to simulate multiple parallel softforks test_blocks = self.generate_blocks( 50, activated_version) # 0x20000001 (signalling ready) test_blocks = self.generate_blocks( 20, 4, test_blocks) # 0x00000004 (signalling not) test_blocks = self.generate_blocks( 50, activated_version, test_blocks) # 0x20000101 (signalling ready) test_blocks = self.generate_blocks( 24, 4, test_blocks) # 0x20010000 (signalling not) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'started') tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) assert_equal(tmpl['vbavailable'][bipName], bitno) assert_equal(tmpl['vbrequired'], 0) assert (tmpl['version'] & activated_version) # Test 3 # 108 out of 144 signal bit 1 to achieve LOCKED_IN # using a variety of bits to simulate multiple parallel softforks test_blocks = self.generate_blocks( 58, activated_version) # 0x20000001 (signalling ready) test_blocks = self.generate_blocks( 26, 4, test_blocks) # 0x00000004 (signalling not) test_blocks = self.generate_blocks( 50, activated_version, test_blocks) # 0x20000101 (signalling ready) test_blocks = self.generate_blocks( 10, 4, test_blocks) # 0x20010000 (signalling not) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in') tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) # Test 4 # 143 more version 536870913 blocks (waiting period-1) test_blocks = self.generate_blocks(143, 4) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in') tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) # Test 5 # Check that the new rule is enforced spendtx = self.create_transaction(self.nodes[0], self.coinbase_blocks[0], self.nodeaddress, 1.0) invalidate(spendtx) spendtx = self.sign_transaction(self.nodes[0], spendtx) spendtx.rehash() invalidatePostSignature(spendtx) spendtx.rehash() block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) block.nVersion = activated_version block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() self.last_block_time += 1 self.tip = block.sha256 self.height += 1 yield TestInstance([[block, True]]) assert_equal(self.get_bip9_status(bipName)['status'], 'active') tmpl = self.nodes[0].getblocktemplate({}) assert (bipName in tmpl['rules']) assert (bipName not in tmpl['vbavailable']) assert_equal(tmpl['vbrequired'], 0) assert (not (tmpl['version'] & (1 << bitno))) # Test 6 # Check that the new sequence lock rules are enforced spendtx = self.create_transaction(self.nodes[0], self.coinbase_blocks[1], self.nodeaddress, 1.0) invalidate(spendtx) spendtx = self.sign_transaction(self.nodes[0], spendtx) spendtx.rehash() invalidatePostSignature(spendtx) spendtx.rehash() block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) block.nVersion = 5 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() self.last_block_time += 1 yield TestInstance([[block, False]]) # Restart all self.test.block_store.close() stop_nodes(self.nodes) wait_BTSds() shutil.rmtree(self.options.tmpdir) self.setup_chain() self.setup_network() self.test.block_store = BlockStore(self.options.tmpdir) self.test.clear_all_connections() self.test.add_all_connections(self.nodes) NetworkThread().start() # Start up network handling in another thread
def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature, bitno): assert_equal(self.get_bip9_status(bipName)['status'], 'defined') assert_equal(self.get_bip9_status(bipName)['since'], 0) # generate some coins for later self.coinbase_blocks = self.nodes[0].generate(2) self.height = 3 # height of the next block to build self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) self.nodeaddress = self.nodes[0].getnewaddress() self.last_block_time = int(time.time()) assert_equal(self.get_bip9_status(bipName)['status'], 'defined') assert_equal(self.get_bip9_status(bipName)['since'], 0) tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) assert (bipName not in tmpl['vbavailable']) assert_equal(tmpl['vbrequired'], 0) assert_equal(tmpl['version'], 0x20000000) # Test 1 # Advance from DEFINED to STARTED test_blocks = self.generate_blocks(141, 4) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'started') assert_equal(self.get_bip9_status(bipName)['since'], 144) assert_equal(self.get_bip9_status(bipName)['statistics']['elapsed'], 0) assert_equal(self.get_bip9_status(bipName)['statistics']['count'], 0) tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) assert_equal(tmpl['vbavailable'][bipName], bitno) assert_equal(tmpl['vbrequired'], 0) assert (tmpl['version'] & activated_version) # Test 1-A # check stats after max number of "signalling not" blocks such that LOCKED_IN still possible this period test_blocks = self.generate_blocks( 36, 4, test_blocks) # 0x00000004 (signalling not) test_blocks = self.generate_blocks( 10, activated_version) # 0x20000001 (signalling ready) yield TestInstance(test_blocks, sync_every_block=False) assert_equal( self.get_bip9_status(bipName)['statistics']['elapsed'], 46) assert_equal(self.get_bip9_status(bipName)['statistics']['count'], 10) assert_equal( self.get_bip9_status(bipName)['statistics']['possible'], True) # Test 1-B # check stats after one additional "signalling not" block -- LOCKED_IN no longer possible this period test_blocks = self.generate_blocks( 1, 4, test_blocks) # 0x00000004 (signalling not) yield TestInstance(test_blocks, sync_every_block=False) assert_equal( self.get_bip9_status(bipName)['statistics']['elapsed'], 47) assert_equal(self.get_bip9_status(bipName)['statistics']['count'], 10) assert_equal( self.get_bip9_status(bipName)['statistics']['possible'], False) # Test 1-C # finish period with "ready" blocks, but soft fork will still fail to advance to LOCKED_IN test_blocks = self.generate_blocks( 97, activated_version) # 0x20000001 (signalling ready) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['statistics']['elapsed'], 0) assert_equal(self.get_bip9_status(bipName)['statistics']['count'], 0) assert_equal( self.get_bip9_status(bipName)['statistics']['possible'], True) assert_equal(self.get_bip9_status(bipName)['status'], 'started') # Test 2 # Fail to achieve LOCKED_IN 100 out of 144 signal bit 1 # using a variety of bits to simulate multiple parallel softforks test_blocks = self.generate_blocks( 50, activated_version) # 0x20000001 (signalling ready) test_blocks = self.generate_blocks( 20, 4, test_blocks) # 0x00000004 (signalling not) test_blocks = self.generate_blocks( 50, activated_version, test_blocks) # 0x20000101 (signalling ready) test_blocks = self.generate_blocks( 24, 4, test_blocks) # 0x20010000 (signalling not) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'started') assert_equal(self.get_bip9_status(bipName)['since'], 144) assert_equal(self.get_bip9_status(bipName)['statistics']['elapsed'], 0) assert_equal(self.get_bip9_status(bipName)['statistics']['count'], 0) tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) assert_equal(tmpl['vbavailable'][bipName], bitno) assert_equal(tmpl['vbrequired'], 0) assert (tmpl['version'] & activated_version) # Test 3 # 108 out of 144 signal bit 1 to achieve LOCKED_IN # using a variety of bits to simulate multiple parallel softforks test_blocks = self.generate_blocks( 57, activated_version) # 0x20000001 (signalling ready) test_blocks = self.generate_blocks( 26, 4, test_blocks) # 0x00000004 (signalling not) test_blocks = self.generate_blocks( 50, activated_version, test_blocks) # 0x20000101 (signalling ready) test_blocks = self.generate_blocks( 10, 4, test_blocks) # 0x20010000 (signalling not) yield TestInstance(test_blocks, sync_every_block=False) # check counting stats and "possible" flag before last block of this period achieves LOCKED_IN... assert_equal( self.get_bip9_status(bipName)['statistics']['elapsed'], 143) assert_equal(self.get_bip9_status(bipName)['statistics']['count'], 107) assert_equal( self.get_bip9_status(bipName)['statistics']['possible'], True) assert_equal(self.get_bip9_status(bipName)['status'], 'started') # ...continue with Test 3 test_blocks = self.generate_blocks( 1, activated_version) # 0x20000001 (signalling ready) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in') assert_equal(self.get_bip9_status(bipName)['since'], 576) tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) # Test 4 # 143 more version 536870913 blocks (waiting period-1) test_blocks = self.generate_blocks(143, 4) yield TestInstance(test_blocks, sync_every_block=False) assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in') assert_equal(self.get_bip9_status(bipName)['since'], 576) tmpl = self.nodes[0].getblocktemplate({}) assert (bipName not in tmpl['rules']) # Test 5 # Check that the new rule is enforced spendtx = self.create_transaction(self.nodes[0], self.coinbase_blocks[0], self.nodeaddress, 1.0) invalidate(spendtx) spendtx = self.sign_transaction(self.nodes[0], spendtx) spendtx.rehash() invalidatePostSignature(spendtx) spendtx.rehash() block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) block.nVersion = activated_version block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() self.last_block_time += 1 self.tip = block.sha256 self.height += 1 yield TestInstance([[block, True]]) assert_equal(self.get_bip9_status(bipName)['status'], 'active') assert_equal(self.get_bip9_status(bipName)['since'], 720) tmpl = self.nodes[0].getblocktemplate({}) assert (bipName in tmpl['rules']) assert (bipName not in tmpl['vbavailable']) assert_equal(tmpl['vbrequired'], 0) assert (not (tmpl['version'] & (1 << bitno))) # Test 6 # Check that the new sequence lock rules are enforced spendtx = self.create_transaction(self.nodes[0], self.coinbase_blocks[1], self.nodeaddress, 1.0) invalidate(spendtx) spendtx = self.sign_transaction(self.nodes[0], spendtx) spendtx.rehash() invalidatePostSignature(spendtx) spendtx.rehash() block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) block.nVersion = 5 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() self.last_block_time += 1 yield TestInstance([[block, False]]) # Restart all self.test.block_store.close() stop_nodes(self.nodes) shutil.rmtree(self.options.tmpdir) self.setup_chain() self.setup_network() self.test.block_store = BlockStore(self.options.tmpdir) self.test.clear_all_connections() self.test.add_all_connections(self.nodes) NetworkThread().start() # Start up network handling in another thread