def run_test(self):
    self.nodes[0].add_p2p_connection(P2PInterface())
    network_thread_start()
    self.nodes[0].p2p.wait_for_verack()
    self.log.info('Mining {} blocks'.format((CLTV_HEIGHT - 2)))
    self.coinbase_blocks = self.nodes[0].generate((CLTV_HEIGHT - 2))
    self.nodeaddress = self.nodes[0].getnewaddress()
    self.log.info('Test that an invalid-according-to-CLTV transaction can still appear in a block')
    fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[0], self.nodeaddress, 49.99)
    (fundtx, spendtx) = cltv_lock_to_height(self.nodes[0], fundtx, self.nodeaddress, 49.98)
    tip = self.nodes[0].getbestblockhash()
    block_time = (self.nodes[0].getblockheader(tip)['mediantime'] + 1)
    block = create_block(int(tip, 16), create_coinbase((CLTV_HEIGHT - 1)), block_time)
    block.nVersion = 3
    block.vtx.append(fundtx)
    block.vtx.append(spendtx)
    make_conform_to_ctor(block)
    block.hashMerkleRoot = block.calc_merkle_root()
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(self.nodes[0].getbestblockhash(), block.hash)
    self.log.info('Test that blocks must now be at least version 4')
    tip = block.sha256
    block_time += 1
    block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time)
    block.nVersion = 3
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
    wait_until((lambda : ('reject' in self.nodes[0].p2p.last_message.keys())), lock=mininode_lock)
    with mininode_lock:
        assert_equal(self.nodes[0].p2p.last_message['reject'].code, REJECT_OBSOLETE)
        assert_equal(self.nodes[0].p2p.last_message['reject'].reason, b'bad-version(0x00000003)')
        assert_equal(self.nodes[0].p2p.last_message['reject'].data, block.sha256)
        del self.nodes[0].p2p.last_message['reject']
    self.log.info('Test that invalid-according-to-cltv transactions cannot appear in a block')
    block.nVersion = 4
    fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[1], self.nodeaddress, 49.99)
    (fundtx, spendtx) = cltv_lock_to_height(self.nodes[0], fundtx, self.nodeaddress, 49.98)
    self.nodes[0].p2p.send_and_ping(msg_tx(fundtx))
    assert (fundtx.hash in self.nodes[0].getrawmempool())
    block.vtx.append(fundtx)
    block.hashMerkleRoot = block.calc_merkle_root()
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(self.nodes[0].getbestblockhash(), block.hash)
    assert_equal([{'txid': spendtx.hash, 'allowed': False, 'reject-reason': '64: non-mandatory-script-verify-flag (Negative locktime)'}], self.nodes[0].testmempoolaccept(rawtxs=[spendtx.serialize().hex()], allowhighfees=True))
    rejectedtx_signed = self.nodes[0].signrawtransactionwithwallet(ToHex(spendtx))
    assert (rejectedtx_signed['errors'][0]['error'] == 'Negative locktime')
    tip = block.hash
    block_time += 1
    block = create_block(block.sha256, create_coinbase((CLTV_HEIGHT + 1)), block_time)
    block.nVersion = 4
    block.vtx.append(spendtx)
    block.hashMerkleRoot = block.calc_merkle_root()
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(self.nodes[0].getbestblockhash(), tip)
    wait_until((lambda : ('reject' in self.nodes[0].p2p.last_message.keys())), lock=mininode_lock)
    with mininode_lock:
        assert (self.nodes[0].p2p.last_message['reject'].code in [REJECT_INVALID, REJECT_NONSTANDARD])
        assert_equal(self.nodes[0].p2p.last_message['reject'].data, block.sha256)
        if (self.nodes[0].p2p.last_message['reject'].code == REJECT_INVALID):
            assert_equal(self.nodes[0].p2p.last_message['reject'].reason, b'blk-bad-inputs')
        else:
            assert (b'Negative locktime' in self.nodes[0].p2p.last_message['reject'].reason)
    self.log.info('Test that a version 4 block with a valid-according-to-CLTV transaction is accepted')
    fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[2], self.nodeaddress, 49.99)
    (fundtx, spendtx) = cltv_lock_to_height(self.nodes[0], fundtx, self.nodeaddress, 49.98, CLTV_HEIGHT)
    spendtx.vin[0].nSequence = 4294967294
    spendtx.nLockTime = CLTV_HEIGHT
    self.nodes[0].sendrawtransaction(ToHex(fundtx))
    self.nodes[0].sendrawtransaction(ToHex(spendtx))
    block.vtx.pop(1)
    block.vtx.append(fundtx)
    block.vtx.append(spendtx)
    make_conform_to_ctor(block)
    block.hashMerkleRoot = block.calc_merkle_root()
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(self.nodes[0].getbestblockhash(), block.hash)
def run_test(self):
    self.nodes[0].add_p2p_connection(P2PInterface())
    network_thread_start()
    self.nodes[0].p2p.wait_for_verack()
    self.log.info('Mining {} blocks'.format((CLTV_HEIGHT - 2)))
    self.coinbase_blocks = self.nodes[0].generate((CLTV_HEIGHT - 2))
    self.nodeaddress = self.nodes[0].getnewaddress()
    self.log.info('Test that an invalid-according-to-CLTV transaction can still appear in a block')
    fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[0], self.nodeaddress, 49.99)
    (fundtx, spendtx) = cltv_lock_to_height(self.nodes[0], fundtx, self.nodeaddress, 49.98)
    tip = self.nodes[0].getbestblockhash()
    block_time = (self.nodes[0].getblockheader(tip)['mediantime'] + 1)
    block = create_block(int(tip, 16), create_coinbase((CLTV_HEIGHT - 1)), block_time)
    block.nVersion = 3
    block.vtx.append(fundtx)
    block.vtx.append(spendtx)
    make_conform_to_ctor(block)
    block.hashMerkleRoot = block.calc_merkle_root()
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(self.nodes[0].getbestblockhash(), block.hash)
    self.log.info('Test that blocks must now be at least version 4')
    tip = block.sha256
    block_time += 1
    block = create_block(tip, create_coinbase(CLTV_HEIGHT), block_time)
    block.nVersion = 3
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
    wait_until((lambda : ('reject' in self.nodes[0].p2p.last_message.keys())), lock=mininode_lock)
    with mininode_lock:
        assert_equal(self.nodes[0].p2p.last_message['reject'].code, REJECT_OBSOLETE)
        assert_equal(self.nodes[0].p2p.last_message['reject'].reason, b'bad-version(0x00000003)')
        assert_equal(self.nodes[0].p2p.last_message['reject'].data, block.sha256)
        del self.nodes[0].p2p.last_message['reject']
    self.log.info('Test that invalid-according-to-cltv transactions cannot appear in a block')
    block.nVersion = 4
    fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[1], self.nodeaddress, 49.99)
    (fundtx, spendtx) = cltv_lock_to_height(self.nodes[0], fundtx, self.nodeaddress, 49.98)
    self.nodes[0].p2p.send_and_ping(msg_tx(fundtx))
    assert (fundtx.hash in self.nodes[0].getrawmempool())
    block.vtx.append(fundtx)
    block.hashMerkleRoot = block.calc_merkle_root()
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(self.nodes[0].getbestblockhash(), block.hash)
    assert_equal([{'txid': spendtx.hash, 'allowed': False, 'reject-reason': '64: non-mandatory-script-verify-flag (Negative locktime)'}], self.nodes[0].testmempoolaccept(rawtxs=[spendtx.serialize().hex()], allowhighfees=True))
    rejectedtx_signed = self.nodes[0].signrawtransactionwithwallet(ToHex(spendtx))
    assert (rejectedtx_signed['errors'][0]['error'] == 'Negative locktime')
    tip = block.hash
    block_time += 1
    block = create_block(block.sha256, create_coinbase((CLTV_HEIGHT + 1)), block_time)
    block.nVersion = 4
    block.vtx.append(spendtx)
    block.hashMerkleRoot = block.calc_merkle_root()
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(self.nodes[0].getbestblockhash(), tip)
    wait_until((lambda : ('reject' in self.nodes[0].p2p.last_message.keys())), lock=mininode_lock)
    with mininode_lock:
        assert (self.nodes[0].p2p.last_message['reject'].code in [REJECT_INVALID, REJECT_NONSTANDARD])
        assert_equal(self.nodes[0].p2p.last_message['reject'].data, block.sha256)
        if (self.nodes[0].p2p.last_message['reject'].code == REJECT_INVALID):
            assert_equal(self.nodes[0].p2p.last_message['reject'].reason, b'blk-bad-inputs')
        else:
            assert (b'Negative locktime' in self.nodes[0].p2p.last_message['reject'].reason)
    self.log.info('Test that a version 4 block with a valid-according-to-CLTV transaction is accepted')
    fundtx = spend_from_coinbase(self.nodes[0], self.coinbase_blocks[2], self.nodeaddress, 49.99)
    (fundtx, spendtx) = cltv_lock_to_height(self.nodes[0], fundtx, self.nodeaddress, 49.98, CLTV_HEIGHT)
    spendtx.vin[0].nSequence = 4294967294
    spendtx.nLockTime = CLTV_HEIGHT
    self.nodes[0].sendrawtransaction(ToHex(fundtx))
    self.nodes[0].sendrawtransaction(ToHex(spendtx))
    block.vtx.pop(1)
    block.vtx.append(fundtx)
    block.vtx.append(spendtx)
    make_conform_to_ctor(block)
    block.hashMerkleRoot = block.calc_merkle_root()
    block.solve()
    self.nodes[0].p2p.send_and_ping(msg_block(block))
    assert_equal(self.nodes[0].getbestblockhash(), block.hash)