def set_test_params(self):
        self.pubkeys = [
            "025700236c2890233592fcef262f4520d22af9160e3d9705855140eb2aa06c35d3",
            "03831a69b8009833ab5b0326012eaf489bfea35a7321b1ca15b11d88131423fafc"
        ]

        privkeystr = [
            "67ae3f5bfb3464b9704d7bd3a134401cc80c3a172240ebfca9f1e40f51bb6d37",
            "dbb9d19637018267268dfc2cc7aec07e7217c1a2d6733e1184a0909273bf078b"
        ]

        self.privkeys = []
        for key in privkeystr:
            ckey = CECKey()
            ckey.set_secretbytes(bytes.fromhex(key))
            self.privkeys.append(ckey)

        self.coinbase_key = CECKey()
        self.coinbase_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))
        self.coinbase_pubkey = self.coinbase_key.get_pubkey()

        self.schnorr_key = Schnorr()
        self.schnorr_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))

        self.num_nodes = 1
        self.setup_clean_chain = True
Esempio n. 2
0
 def solve(self, signblockprivkey):
     # create signed blocks.
     sighash = self.getsighash()
     self.proof = ""
     #proof is based on Schnorr aggregate private key
     signKey = Schnorr()
     signKey.set_secretbytes(hex_str_to_bytes(signblockprivkey))
     self.proof = bytearray(signKey.sign(sighash))
     self.rehash()
    def set_test_params(self):
        self.aggpubkeys = [
            "025700236c2890233592fcef262f4520d22af9160e3d9705855140eb2aa06c35d3",
            "03831a69b8009833ab5b0326012eaf489bfea35a7321b1ca15b11d88131423fafc",
            "02bf2027c8455800c7626542219e6208b5fe787483689f1391d6d443ec85673ecf",
            "03b44f1cfcf46aba8bc98e2fd39f137cc43d98ab7792e4848b09c06198b042ca8b",
            "02b9a609d6bec0fdc9ba690986013cf7bbd13c54ffc25e6cf30916b4732c4a952a",
            "02e78cafe033b22bda5d7d1c8e82ee932930bf12e08489bc19769cbec765568be9",
            "02473757a955a23f75379820f3071abf5b3343b78eb54e52373d06259ffa6c550b"
        ]

        self.aggprivkey = [
            "67ae3f5bfb3464b9704d7bd3a134401cc80c3a172240ebfca9f1e40f51bb6d37",
            "dbb9d19637018267268dfc2cc7aec07e7217c1a2d6733e1184a0909273bf078b",
            "aa2c70c4b85a09be514292d04b27bbb0cc3f86d306d58fe87743d10a095ada07",
            "3087d8decc5f951f19a442397cf1eba1e2b064e68650c346502780b56454c6e2",
            "6125c8d4330941944cc6cc3e775e8620c479a5901ad627e6e734c6a6f7377428",
            "1c3e5453c0f9aa74a8eb0216310b2b013f017813a648fce364bf41dbc0b37647",
            "ea9fe9fd2f1761fc6f1f0f23eb4d4141d7b05f2b95a1b7a9912cd97bddd9036c"
        ]

        self.aggprivkey_wif = [
            "cR4F4fGuKjDWxiYDtGtyM77WkrVhTgokVyM2ERxoxp7R4RQP9dgE",
            "cUwpWhH9CbYwjUWzfz1UVaSjSQm9ALXWRqeFFiZKnn8cV6wqNXQA",
            "cTHVmjaAwKtU75t89fg42SLx43nRxhsri6YY1Eynvs1V1tPRCfae",
            "cPD3D5AvmXhw7NGxQeaRhTVNW2UoYeibQAMhye7jzyM4ETG9d1ez",
            "cQqYVqYhK47EWvDViNwcyhc6sLS6tkuhED7T3rvumeGRtVJcEQHh",
            "cNXbwddRQrPR4k7Us7eSrRUHFBerNBKwxrExTSs4gdH1rjHdoNuL",
            "cVSnGe9DzWfEgahMjSXs5nuVqnwvyanG9aaEQF6m7M5mSY2wfZzW"
        ]

        self.blocks = []

        self.coinbase_key = CECKey()
        self.coinbase_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))

        self.schnorr_key = Schnorr()
        self.schnorr_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))

        self.num_nodes = 1
        self.sig_scheme = 0
        self.setup_clean_chain = True
        self.genesisBlock = createTestGenesisBlock(self.aggpubkeys[0],
                                                   self.aggprivkey[0],
                                                   int(time.time() - 100))
Esempio n. 4
0
    def set_test_params(self):
        self.aggpubkeys = [
            "025700236c2890233592fcef262f4520d22af9160e3d9705855140eb2aa06c35d3",
            "03831a69b8009833ab5b0326012eaf489bfea35a7321b1ca15b11d88131423fafc",
            "02bf2027c8455800c7626542219e6208b5fe787483689f1391d6d443ec85673ecf",
            "03b44f1cfcf46aba8bc98e2fd39f137cc43d98ab7792e4848b09c06198b042ca8b",
            "02b9a609d6bec0fdc9ba690986013cf7bbd13c54ffc25e6cf30916b4732c4a952a",
            "02e78cafe033b22bda5d7d1c8e82ee932930bf12e08489bc19769cbec765568be9",
            "02473757a955a23f75379820f3071abf5b3343b78eb54e52373d06259ffa6c550b"
        ]

        self.aggprivkey = [
            "67ae3f5bfb3464b9704d7bd3a134401cc80c3a172240ebfca9f1e40f51bb6d37",
            "dbb9d19637018267268dfc2cc7aec07e7217c1a2d6733e1184a0909273bf078b",
            "aa2c70c4b85a09be514292d04b27bbb0cc3f86d306d58fe87743d10a095ada07",
            "3087d8decc5f951f19a442397cf1eba1e2b064e68650c346502780b56454c6e2",
            "6125c8d4330941944cc6cc3e775e8620c479a5901ad627e6e734c6a6f7377428",
            "1c3e5453c0f9aa74a8eb0216310b2b013f017813a648fce364bf41dbc0b37647",
            "ea9fe9fd2f1761fc6f1f0f23eb4d4141d7b05f2b95a1b7a9912cd97bddd9036c"
        ]

        self.blocks = []

        self.coinbase_key = CECKey()
        self.coinbase_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))

        self.schnorr_key = Schnorr()
        self.schnorr_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))

        self.num_nodes = 1
        self.sig_scheme = 0
        self.setup_clean_chain = True
        self.genesisBlock = createTestGenesisBlock(self.aggpubkeys[0],
                                                   self.aggprivkey[0],
                                                   int(time.time() - 100))
class FederationManagementTest(BitcoinTestFramework):
    def set_test_params(self):
        self.aggpubkeys = [
            "025700236c2890233592fcef262f4520d22af9160e3d9705855140eb2aa06c35d3",
            "03831a69b8009833ab5b0326012eaf489bfea35a7321b1ca15b11d88131423fafc",
            "02bf2027c8455800c7626542219e6208b5fe787483689f1391d6d443ec85673ecf",
            "03b44f1cfcf46aba8bc98e2fd39f137cc43d98ab7792e4848b09c06198b042ca8b",
            "02b9a609d6bec0fdc9ba690986013cf7bbd13c54ffc25e6cf30916b4732c4a952a",
            "02e78cafe033b22bda5d7d1c8e82ee932930bf12e08489bc19769cbec765568be9",
            "02473757a955a23f75379820f3071abf5b3343b78eb54e52373d06259ffa6c550b"
        ]

        self.aggprivkey = [
            "67ae3f5bfb3464b9704d7bd3a134401cc80c3a172240ebfca9f1e40f51bb6d37",
            "dbb9d19637018267268dfc2cc7aec07e7217c1a2d6733e1184a0909273bf078b",
            "aa2c70c4b85a09be514292d04b27bbb0cc3f86d306d58fe87743d10a095ada07",
            "3087d8decc5f951f19a442397cf1eba1e2b064e68650c346502780b56454c6e2",
            "6125c8d4330941944cc6cc3e775e8620c479a5901ad627e6e734c6a6f7377428",
            "1c3e5453c0f9aa74a8eb0216310b2b013f017813a648fce364bf41dbc0b37647",
            "ea9fe9fd2f1761fc6f1f0f23eb4d4141d7b05f2b95a1b7a9912cd97bddd9036c"
        ]

        self.aggprivkey_wif = [
            "cR4F4fGuKjDWxiYDtGtyM77WkrVhTgokVyM2ERxoxp7R4RQP9dgE",
            "cUwpWhH9CbYwjUWzfz1UVaSjSQm9ALXWRqeFFiZKnn8cV6wqNXQA",
            "cTHVmjaAwKtU75t89fg42SLx43nRxhsri6YY1Eynvs1V1tPRCfae",
            "cPD3D5AvmXhw7NGxQeaRhTVNW2UoYeibQAMhye7jzyM4ETG9d1ez",
            "cQqYVqYhK47EWvDViNwcyhc6sLS6tkuhED7T3rvumeGRtVJcEQHh",
            "cNXbwddRQrPR4k7Us7eSrRUHFBerNBKwxrExTSs4gdH1rjHdoNuL",
            "cVSnGe9DzWfEgahMjSXs5nuVqnwvyanG9aaEQF6m7M5mSY2wfZzW"
        ]

        self.blocks = []

        self.coinbase_key = CECKey()
        self.coinbase_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))

        self.schnorr_key = Schnorr()
        self.schnorr_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))

        self.num_nodes = 1
        self.sig_scheme = 0
        self.setup_clean_chain = True
        self.genesisBlock = createTestGenesisBlock(self.aggpubkeys[0],
                                                   self.aggprivkey[0],
                                                   int(time.time() - 100))

    def run_test(self):
        node = self.nodes[0]  # convenience reference to the node
        self.address = node.getnewaddress()
        node.add_p2p_connection(P2PDataStore())
        node.p2p.wait_for_getheaders(timeout=5)

        self.log.info("Test starting...")

        #genesis block (B0)
        self.blocks = [self.genesisBlock.hash]
        block_time = self.genesisBlock.nTime

        # Create a new blocks B1 - B10
        self.blocks += node.generate(1, self.aggprivkey_wif[0])
        create_colored_transaction(2, 100, node)
        self.blocks += node.generate(9, self.aggprivkey_wif[0])
        best_block = node.getblock(node.getbestblockhash())
        self.tip = node.getbestblockhash()

        self.log.info("First federation block")
        # B11 - Create block - aggpubkey2 - sign with aggpubkey1
        block_time = best_block["time"] + 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(11),
                                block_time, self.aggpubkeys[1])
        blocknew.solve(self.aggprivkey[0])
        self.blocks += [blocknew.hash]

        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.tip = self.blocks[-1]
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B -- Create block with invalid aggpubkey2 - sign with aggpubkey1 -- failure - invalid aggpubkey
        aggpubkeyInv = self.aggpubkeys[-1][:-2]
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(12),
                                block_time, aggpubkeyInv)
        blocknew.solve(self.aggprivkey[0])
        assert_equal(node.submitblock(bytes_to_hex_str(blocknew.serialize())),
                     "invalid")
        assert_equal(self.tip, node.getbestblockhash())

        # B - Create block - sign with aggpubkey1 - failure - Proof verification failed
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(12),
                                block_time)
        blocknew.solve(self.aggprivkey[0])
        assert_equal(node.submitblock(bytes_to_hex_str(blocknew.serialize())),
                     "invalid")
        assert_equal(self.tip, node.getbestblockhash())

        # B12 - Create block - sign with aggpubkey2
        blocknew.solve(self.aggprivkey[1])
        self.blocks += [blocknew.hash]

        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.tip = self.blocks[-1]
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        # Create a new blocks B13 - B22
        self.blocks += node.generate(10, self.aggprivkey_wif[1])
        best_block = node.getblock(node.getbestblockhash())
        self.tip = node.getbestblockhash()

        #B23 -- Create block with 1 valid transaction - sign with aggpubkey2 -- success
        block_time = best_block["time"] + 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(23),
                                block_time)
        spendHash = node.getblock(self.blocks[2])['tx'][1]
        vout = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(
            spendHash, 1)["vout"]) if vout["value"] != 100)
        rawtx = node.createrawtransaction(inputs=[{
            "txid": spendHash,
            "vout": vout
        }],
                                          outputs={self.address: 1.0})
        signresult = node.signrawtransactionwithwallet(rawtx, [], "ALL",
                                                       self.options.scheme)
        assert_equal(signresult["complete"], True)
        tx = CTransaction()
        tx.deserialize(BytesIO(hex_str_to_bytes(signresult['hex'])))
        blocknew.vtx += [tx]
        blocknew.hashMerkleRoot = blocknew.calc_merkle_root()
        blocknew.hashImMerkleRoot = blocknew.calc_immutable_merkle_root()
        blocknew.solve(self.aggprivkey[1])
        self.blocks.append(blocknew.hash)
        self.tip = blocknew.hash
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #call invalidate block rpc on B23 -- success - B23 is removed from the blockchain. tip is B22
        node.invalidateblock(self.tip)
        self.tip = self.blocks[22]
        assert_equal(self.tip, node.getbestblockhash())

        #B23 -- Re Create a new block B23 -- success
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(23),
                                block_time)
        spendHash = node.getblock(self.blocks[2])['tx'][0]
        blocknew.vtx += [
            create_transaction(node, spendHash, self.address, amount=49.0)
        ]
        blocknew.hashMerkleRoot = blocknew.calc_merkle_root()
        blocknew.hashImMerkleRoot = blocknew.calc_immutable_merkle_root()
        blocknew.solve(self.aggprivkey[1])
        self.blocks[22] = blocknew.hash
        self.tip = blocknew.hash
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B -- - Create block with 1 invalid transaction - sign with aggpubkey2 -- failure
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(23),
                                block_time)
        spendHash = node.getblock(self.blocks[3])['tx'][0]
        blocknew.vtx += [
            create_transaction(node, spendHash, self.address, amount=100.0)
        ]  #invalid
        blocknew.hashMerkleRoot = blocknew.calc_merkle_root()
        blocknew.hashImMerkleRoot = blocknew.calc_immutable_merkle_root()
        blocknew.solve(self.aggprivkey[1])
        assert_equal(node.submitblock(bytes_to_hex_str(blocknew.serialize())),
                     "invalid")
        assert_equal(self.tip, node.getbestblockhash())

        #B -- - Create block with 1 invalid transaction and aggpubkey3 - sign with aggpubkey2 -- failure and aggpubkey3 is not added to the list
        blocknew = create_block(int(self.tip, 16), create_coinbase(23),
                                block_time, self.aggpubkeys[2])
        spendHash = node.getblock(self.blocks[4])['tx'][0]
        blocknew.vtx += [
            create_transaction(node, spendHash, self.address, amount=100.0)
        ]  #invalid
        blocknew.hashMerkleRoot = blocknew.calc_merkle_root()
        blocknew.hashImMerkleRoot = blocknew.calc_immutable_merkle_root()
        blocknew.solve(self.aggprivkey[1])
        assert_equal(node.submitblock(bytes_to_hex_str(blocknew.serialize())),
                     "invalid")
        assert_equal(self.tip, node.getbestblockhash())

        # verify aggpubkey3 is not added to the list : verify that block signed using aggprivkey3 is rejected
        blocknew = create_block(int(self.tip, 16), create_coinbase(24),
                                block_time, self.aggpubkeys[2])
        blocknew.solve(self.aggprivkey[2])
        assert_equal(node.submitblock(bytes_to_hex_str(blocknew.serialize())),
                     "invalid")
        assert_equal(self.tip, node.getbestblockhash())

        self.log.info("Second federation block")
        #B24 -- Create block with 1 valid transaction and aggpubkey3- sign with aggpubkey2 -- success and aggpubkey3 is added to the list
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(24),
                                block_time, self.aggpubkeys[2])
        spendHash = node.getblock(self.blocks[4])['tx'][0]
        blocknew.vtx += [
            create_transaction(node, spendHash, self.address, amount=10.0)
        ]
        blocknew.hashMerkleRoot = blocknew.calc_merkle_root()
        blocknew.hashImMerkleRoot = blocknew.calc_immutable_merkle_root()
        blocknew.solve(self.aggprivkey[1])
        self.blocks.append(blocknew.hash)
        self.tip = blocknew.hash
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B25 -- Create block with 1 valid transaction - sign with aggpubkey3 -- success
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(25),
                                block_time)
        spendHash = node.getblock(self.blocks[5])['tx'][0]
        blocknew.vtx += [
            create_transaction(node, spendHash, self.address, amount=10.0)
        ]
        blocknew.hashMerkleRoot = blocknew.calc_merkle_root()
        blocknew.hashImMerkleRoot = blocknew.calc_immutable_merkle_root()
        blocknew.solve(self.aggprivkey[2])
        self.blocks.append(blocknew.hash)
        self.tip = blocknew.hash
        b25 = blocknew.hash
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        # Create a new blocks B26 - B30
        self.blocks += node.generate(5, self.aggprivkey_wif[2])
        best_block = node.getblock(node.getbestblockhash())
        self.tip = node.getbestblockhash()

        self.log.info("Verifying getblockchaininfo")
        #getblockchaininfo
        expectedAggPubKeys = [{
            self.aggpubkeys[0]: 0
        }, {
            self.aggpubkeys[1]: 12
        }, {
            self.aggpubkeys[2]: 25
        }]
        blockchaininfo = node.getblockchaininfo()
        assert_equal(blockchaininfo["aggregatePubkeys"], expectedAggPubKeys)

        self.log.info(
            "Simulate Blockchain Reorg  - After the last federation block")
        #B27 -- Create block with previous block hash = B26 - sign with aggpubkey3 -- success - block is accepted but there is no re-org
        block_time += 1
        self.forkblocks = self.blocks
        blocknew = create_block(int(self.blocks[26], 16), create_coinbase(27),
                                block_time)
        blocknew.solve(self.aggprivkey[2])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.forkblocks[27] = blocknew.hash
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B28 -- Create block with previous block hash = B27 - sign with aggpubkey3 -- success - block is accepted but there is no re-org
        block_time += 1
        blocknew = create_block(int(self.forkblocks[27], 16),
                                create_coinbase(28), block_time)
        blocknew.solve(self.aggprivkey[2])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.forkblocks[28] = blocknew.hash
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B29 -- Create block with previous block hash = B28 - sign with aggpubkey3 -- success - block is accepted but there is no re-org
        block_time += 1
        blocknew = create_block(int(self.forkblocks[28], 16),
                                create_coinbase(29), block_time)
        blocknew.solve(self.aggprivkey[2])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.forkblocks[29] = blocknew.hash
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B30 -- Create block with previous block hash = B29 - sign with aggpubkey3 -- success - block is accepted but there is no re-org
        block_time += 1
        blocknew = create_block(int(self.forkblocks[29], 16),
                                create_coinbase(30), block_time)
        blocknew.solve(self.aggprivkey[2])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.forkblocks[30] = blocknew.hash
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B31 -- Create block with previous block hash = B30 - sign with aggpubkey3 -- success - block is accepted and re-org happens
        block_time += 1
        blocknew = create_block(int(self.forkblocks[30], 16),
                                create_coinbase(31), block_time)
        blocknew.solve(self.aggprivkey[2])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.forkblocks.append(blocknew.hash)
        self.tip = blocknew.hash
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        assert_equal(blockchaininfo["aggregatePubkeys"], expectedAggPubKeys)

        self.log.info(
            "Simulate Blockchain Reorg  - Before the last federation block")
        #B24 -- Create block with previous block hash = B23 - sign with aggpubkey2 -- failure - block is in invalid chain
        block_time += 1
        blocknew = create_block(int(self.blocks[23], 16), create_coinbase(24),
                                block_time)
        blocknew.solve(self.aggprivkey[1])
        assert_equal(node.submitblock(bytes_to_hex_str(blocknew.serialize())),
                     "invalid")
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B25 -- Create block with previous block hash = B24 - sign with aggpubkey2 -- success - block is in invalid chain
        block_time += 1
        blocknew = create_block(int(self.blocks[24], 16), create_coinbase(25),
                                block_time)
        blocknew.solve(self.aggprivkey[1])
        assert_equal(node.submitblock(bytes_to_hex_str(blocknew.serialize())),
                     "invalid")
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #there are 3 tips in the current blockchain
        chaintips = node.getchaintips()
        assert_equal(len(chaintips), 3)

        assert (node.getblock(self.blocks[12]))
        assert (node.getblock(self.blocks[25]))
        assert_raises_rpc_error(-5, "Block not found", node.getblock,
                                blocknew.hash)

        self.log.info("Third Federation Block - active chain")
        #B32 -- Create block with aggpubkey4 - sign with aggpubkey3 -- success - aggpubkey4 is added to the list
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(32),
                                block_time, self.aggpubkeys[3])
        blocknew.solve(self.aggprivkey[2])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.forkblocks.append(blocknew.hash)
        self.tip = blocknew.hash
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B -- Create block - sign with aggpubkey2 -- failure - proof verification failed
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(33),
                                block_time)
        blocknew.solve(self.aggprivkey[1])
        assert_equal(node.submitblock(bytes_to_hex_str(blocknew.serialize())),
                     "invalid")
        assert_equal(self.tip, node.getbestblockhash())

        #B -- Create block - sign with aggpubkey3 -- failure - proof verification failed
        blocknew.solve(self.aggprivkey[2])
        assert_equal(node.submitblock(bytes_to_hex_str(blocknew.serialize())),
                     "invalid")
        assert_equal(self.tip, node.getbestblockhash())

        #B33 -- Create block  - sign with aggpubkey4 -- success
        blocknew.solve(self.aggprivkey[3])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.forkblocks.append(blocknew.hash)
        self.tip = blocknew.hash
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B34 - B35 -- Generate 2 blocks - no aggpubkey -- chain becomes longer
        self.forkblocks += node.generate(2, self.aggprivkey_wif[3])
        self.tip = self.forkblocks[35]
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        self.log.info("Fourth Federation Block")
        #B36 -- Create block with aggpubkey5 - sign using aggpubkey4 -- success - aggpubkey5 is added to the list
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(36),
                                block_time, self.aggpubkeys[4])
        blocknew.solve(self.aggprivkey[3])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.tip = blocknew.hash
        self.forkblocks.append(blocknew.hash)
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #call invalidate block rpc on B36 -- failure - B36 is a federation block
        assert_raises_rpc_error(-8, "Federation block found",
                                node.invalidateblock, self.tip)
        assert_raises_rpc_error(-8, "Federation block found",
                                node.invalidateblock, self.forkblocks[33])
        assert_raises_rpc_error(-8, "Federation block found",
                                node.invalidateblock, self.blocks[29])
        assert_equal(self.tip, node.getbestblockhash())

        #B37 - Create block - sign using aggpubkey5 -- success
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(37),
                                block_time)
        blocknew.solve(self.aggprivkey[4])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.tip = blocknew.hash
        self.forkblocks.append(blocknew.hash)
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        self.log.info("Verifying getblockchaininfo")
        #getblockchaininfo
        expectedAggPubKeys = [
            {
                self.aggpubkeys[0]: 0
            },
            {
                self.aggpubkeys[1]: 12
            },
            {
                self.aggpubkeys[2]: 25
            },
            {
                self.aggpubkeys[3]: 33
            },
            {
                self.aggpubkeys[4]: 37
            },
        ]
        blockchaininfo = node.getblockchaininfo()
        assert_equal(blockchaininfo["aggregatePubkeys"], expectedAggPubKeys)

        #B38 - B40 -- Generate 2 blocks - no aggpubkey -- chain becomes longer
        self.forkblocks += node.generate(3, self.aggprivkey_wif[4])
        self.tip = node.getbestblockhash()
        best_block = node.getblock(self.tip)

        self.log.info("Test Repeated aggpubkeys in Federation Block")
        #B41 -- Create block with aggpubkey0 - sign using aggpubkey5 -- success - aggpubkey0 is added to the list
        block_time = best_block["time"] + 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(41),
                                block_time, self.aggpubkeys[0])
        blocknew.solve(self.aggprivkey[4])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.tip = blocknew.hash
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        #B42 -- Create block with aggpubkey1 - sign using aggpubkey0 -- success - aggpubkey1 is added to the list
        block_time += 1
        blocknew = create_block(int(self.tip, 16), create_coinbase(42),
                                block_time, self.aggpubkeys[1])
        blocknew.solve(self.aggprivkey[0])
        node.submitblock(bytes_to_hex_str(blocknew.serialize()))
        self.tip = blocknew.hash
        assert_equal(self.tip, node.getbestblockhash())
        assert (node.getblock(self.tip))

        self.log.info("Verifying getblockchaininfo")
        #getblockchaininfo
        expectedAggPubKeys = [
            {
                self.aggpubkeys[0]: 0
            },
            {
                self.aggpubkeys[1]: 12
            },
            {
                self.aggpubkeys[2]: 25
            },
            {
                self.aggpubkeys[3]: 33
            },
            {
                self.aggpubkeys[4]: 37
            },
            {
                self.aggpubkeys[0]: 42
            },
            {
                self.aggpubkeys[1]: 43
            },
        ]
        blockchaininfo = node.getblockchaininfo()
        assert_equal(blockchaininfo["aggregatePubkeys"], expectedAggPubKeys)
        self.stop_node(0)

        self.log.info("Restarting node with '-reindex-chainstate'")
        self.start_node(0, extra_args=["-reindex-chainstate"])
        self.sync_all()
        self.stop_node(0)

        self.log.info("Restarting node with '-loadblock'")
        shutil.copyfile(
            os.path.join(self.nodes[0].datadir, NetworkDirName(), 'blocks',
                         'blk00000.dat'),
            os.path.join(self.nodes[0].datadir, 'blk00000.dat'))
        os.remove(
            os.path.join(self.nodes[0].datadir, NetworkDirName(), 'blocks',
                         'blk00000.dat'))
        extra_args = [
            "-loadblock=%s" %
            os.path.join(self.nodes[0].datadir, 'blk00000.dat'), "-reindex"
        ]
        self.start_node(0, extra_args)
Esempio n. 6
0
 def set_test_params(self):
     self.setup_clean_chain = True
     self.num_nodes = 1
     self.extra_args = [["-whitelist=127.0.0.1"]]
     self.signKey = Schnorr()
     self.signKey.set_secretbytes(hex_str_to_bytes(self.signblockprivkey))
Esempio n. 7
0
class BlockHeaderXFieldTest(BitcoinTestFramework):
    def set_test_params(self):
        self.setup_clean_chain = True
        self.num_nodes = 1
        self.extra_args = [["-whitelist=127.0.0.1"]]
        self.signKey = Schnorr()
        self.signKey.set_secretbytes(hex_str_to_bytes(self.signblockprivkey))

    def createblockproof(self, block, signblockprivkey):
        # create block proof with xField for all xfieldTypes
        r = b""
        r += struct.pack("<i", block.nVersion)
        r += ser_uint256(block.hashPrevBlock)
        r += ser_uint256(block.hashMerkleRoot)
        r += ser_uint256(block.hashImMerkleRoot)
        r += struct.pack("<I", block.nTime)
        r += struct.pack("B", block.xfieldType)
        r += ser_string(block.xfield)
        sighash = hash256(r)
        block.proof = bytearray(self.signKey.sign(sighash))
        block.rehash()

    def serializeblock_err(self, block):
        r = b""
        r += struct.pack("<i", block.nVersion)
        r += ser_uint256(block.hashPrevBlock)
        r += ser_uint256(block.hashMerkleRoot)
        r += ser_uint256(block.hashImMerkleRoot)
        r += struct.pack("<I", block.nTime)
        r += struct.pack("B", block.xfieldType)
        r += block.xfield
        r += ser_string(block.proof)
        r += ser_vector(block.vtx)
        return r

    def reconnect_p2p(self):
        """Tear down and bootstrap the P2P connection to the node.

        The node gets disconnected several times in this test. This helper
        method reconnects the p2p and restarts the network thread."""
        self.nodes[0].disconnect_p2ps()
        self.nodes[0].add_p2p_connection(P2PDataStore())
        self.nodes[0].p2p.wait_for_getheaders(timeout=5)

    def run_test(self):
        node = self.nodes[0]
        node.add_p2p_connection(P2PDataStore())
        node.p2p.wait_for_getheaders(timeout=5)

        self.tip = node.getbestblockhash()
        best_block = node.getblock(self.tip)
        block_time = best_block["time"] + 1

        self.log.info("Incorrect xfield with xfieldType = 0")
        block = create_block(int(self.tip, 16), create_coinbase(1), block_time)
        block.xfieldType = 0
        block.xfield = b'1'
        self.createblockproof(block, self.signblockprivkey)

        node.p2p.send_blocks_and_test([block],
                                      node,
                                      success=False,
                                      request_block=False)

        self.log.info("Incorrect xfield with xfieldType = 1")
        block = create_block(int(self.tip, 16), create_coinbase(1), block_time)
        block.xfieldType = 1
        block.xfield = b'1'
        self.createblockproof(block, self.signblockprivkey)

        node.p2p.send_blocks_and_test([block],
                                      node,
                                      success=False,
                                      request_block=False,
                                      reject_code=16,
                                      reject_reason="bad-xfieldType-xfield")

        blockchaininfo = node.getblockchaininfo()
        assert_equal(
            blockchaininfo['warnings'],
            "This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"
        )

        self.log.info("Incorrect xfield with xfieldType = 2")
        block = create_block(int(self.tip, 16), create_coinbase(1), block_time)
        block.xfieldType = 2
        block.xfield = b'1'
        self.createblockproof(block, self.signblockprivkey)

        assert_raises_rpc_error(
            -22, "", node.submitblock,
            bytes_to_hex_str(self.serializeblock_err(block)))

        blockchaininfo = node.getblockchaininfo()
        assert_equal(
            blockchaininfo['warnings'],
            "This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"
        )

        self.log.info("Valid xfield with xfieldType = 2")
        node.p2p.send_blocks_and_test([block], node, True, True)
        assert_equal(block.hash, node.getbestblockhash())

        blockchaininfo = node.getblockchaininfo()
        assert_equal(
            blockchaininfo['warnings'],
            "Warning: Unknown xfieldType [%2x] was accepted in block [%s]" %
            (block.xfieldType, block.hash))

        self.log.info("Valid xfield with xfieldType = 0xFF")
        self.tip = node.getbestblockhash()
        block_time += 1
        block = create_block(int(self.tip, 16), create_coinbase(2), block_time)
        block.xfieldType = 0xFF
        block.xfield = b'1'
        self.createblockproof(block, self.signblockprivkey)

        node.p2p.send_blocks_and_test([block], node, True, True)
        assert_equal(block.hash, node.getbestblockhash())

        self.log.info(
            "xfieldType = 3 in invalid block - insufficient tx input")
        self.tip = node.getbestblockhash()
        block_time += 1
        block = create_block(int(self.tip, 16), create_coinbase(3), block_time)
        block.xfieldType = 3
        block.xfield = b''
        spendHash = node.getblock(self.tip)['tx'][0]
        block.vtx += [
            create_transaction(node,
                               spendHash,
                               node.getnewaddress(),
                               amount=100.0)
        ]
        block.hashMerkleRoot = block.calc_merkle_root()
        block.hashImMerkleRoot = block.calc_immutable_merkle_root()
        self.createblockproof(block, self.signblockprivkey)
        oldblockhash = block.hash

        node.p2p.send_blocks_and_test([block],
                                      node,
                                      success=False,
                                      request_block=True,
                                      reject_code=16,
                                      reject_reason="bad-txns-in-belowout")
        assert_equal(self.tip, node.getbestblockhash())

        blockchaininfo = node.getblockchaininfo()
        assert_equal(
            blockchaininfo['warnings'],
            "Warning: Unknown xfieldType [%2x] was accepted in block [%s]" %
            (block.xfieldType, block.hash))

        self.log.info("xfieldType = 4 in invalid block - height in coinbase")
        block_time += 1
        block = create_block(int(self.tip, 16), create_coinbase(1), block_time)
        block.xfieldType = 4
        block.xfield = b''
        self.createblockproof(block, self.signblockprivkey)

        node.p2p.send_blocks_and_test([block],
                                      node,
                                      success=False,
                                      request_block=True,
                                      reject_code=16,
                                      reject_reason="bad-cb-invalid")
        assert_equal(self.tip, node.getbestblockhash())

        blockchaininfo = node.getblockchaininfo()
        assert_equal(
            blockchaininfo['warnings'],
            "Warning: Unknown xfieldType [%2x] was accepted in block [%s]" %
            (3, oldblockhash))

        self.log.info("xfieldType = 5 in invalid block - no coinbase")
        block_time += 1
        block = create_block(int(self.tip, 16), create_coinbase(4), block_time)
        block.xfieldType = 5
        block.xfield = b''
        block.vtx = []
        self.createblockproof(block, self.signblockprivkey)

        node.p2p.send_blocks_and_test([block],
                                      node,
                                      success=False,
                                      request_block=True,
                                      reject_code=16,
                                      reject_reason="bad-cb-missing")
        assert_equal(self.tip, node.getbestblockhash())

        blockchaininfo = node.getblockchaininfo()
        assert_equal(
            blockchaininfo['warnings'],
            "Warning: Unknown xfieldType [%2x] was accepted in block [%s]" %
            (3, oldblockhash))
class ColoredCoinTest(BitcoinTestFramework):
    def set_test_params(self):
        self.pubkeys = [
            "025700236c2890233592fcef262f4520d22af9160e3d9705855140eb2aa06c35d3",
            "03831a69b8009833ab5b0326012eaf489bfea35a7321b1ca15b11d88131423fafc"
        ]

        privkeystr = [
            "67ae3f5bfb3464b9704d7bd3a134401cc80c3a172240ebfca9f1e40f51bb6d37",
            "dbb9d19637018267268dfc2cc7aec07e7217c1a2d6733e1184a0909273bf078b"
        ]

        self.privkeys = []
        for key in privkeystr:
            ckey = CECKey()
            ckey.set_secretbytes(bytes.fromhex(key))
            self.privkeys.append(ckey)

        self.coinbase_key = CECKey()
        self.coinbase_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))
        self.coinbase_pubkey = self.coinbase_key.get_pubkey()

        self.schnorr_key = Schnorr()
        self.schnorr_key.set_secretbytes(
            bytes.fromhex(
                "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"
            ))

        self.num_nodes = 1
        self.setup_clean_chain = True

    def run_test(self):
        node = self.nodes[0]  # convenience reference to the node
        self.address = node.getnewaddress()
        node.add_p2p_connection(P2PDataStore())
        node.p2p.wait_for_getheaders(timeout=5)
        self.address = self.nodes[0].getnewaddress()

        self.log.info("Test starting...")

        #generate 10 blocks for coinbase outputs
        coinbase_txs = []
        for i in range(1, 10):
            height = node.getblockcount() + 1
            coinbase_tx = create_coinbase(height, self.coinbase_pubkey)
            coinbase_txs.append(coinbase_tx)
            tip = node.getbestblockhash()
            block_time = node.getblockheader(tip)["mediantime"] + 1
            block = create_block(int(tip, 16), coinbase_tx, block_time)
            block.solve(self.signblockprivkey)
            tip = block.hash

            node.p2p.send_and_ping(msg_block(block))
            assert_equal(node.getbestblockhash(), tip)

        change_script = CScript([self.coinbase_pubkey, OP_CHECKSIG])
        burn_script = CScript([hex_str_to_bytes(self.pubkeys[1]), OP_CHECKSIG])

        #TxSuccess1 - coinbaseTx1 - issue 100 REISSUABLE  + 30     (UTXO-1,2)
        colorId_reissuable = colorIdReissuable(
            coinbase_txs[0].vout[0].scriptPubKey)
        script_reissuable = CP2PHK_script(colorId=colorId_reissuable,
                                          pubkey=self.pubkeys[0])
        script_transfer_reissuable = CP2PHK_script(colorId=colorId_reissuable,
                                                   pubkey=self.pubkeys[1])

        txSuccess1 = CTransaction()
        txSuccess1.vin.append(
            CTxIn(COutPoint(coinbase_txs[0].malfixsha256, 0), b""))
        txSuccess1.vout.append(CTxOut(100, script_reissuable))
        txSuccess1.vout.append(
            CTxOut(30 * COIN, CScript([self.coinbase_pubkey, OP_CHECKSIG])))
        sig_hash, err = SignatureHash(coinbase_txs[0].vout[0].scriptPubKey,
                                      txSuccess1, 0, SIGHASH_ALL)
        signature = self.coinbase_key.sign(
            sig_hash) + b'\x01'  # 0x1 is SIGHASH_ALL
        txSuccess1.vin[0].scriptSig = CScript([signature])
        txSuccess1.rehash()

        test_transaction_acceptance(node, txSuccess1, accepted=True)

        #TxSuccess2 - (UTXO-2)    - issue 100 NON-REISSUABLE       (UTXO-3)
        colorId_nonreissuable = colorIdNonReissuable(
            COutPoint(txSuccess1.malfixsha256, 1).serialize())
        script_nonreissuable = CP2PHK_script(colorId=colorId_nonreissuable,
                                             pubkey=self.pubkeys[0])
        script_transfer_nonreissuable = CP2PHK_script(
            colorId=colorId_nonreissuable, pubkey=self.pubkeys[1])

        txSuccess2 = CTransaction()
        txSuccess2.vin.append(CTxIn(COutPoint(txSuccess1.malfixsha256, 1),
                                    b""))
        txSuccess2.vout.append(CTxOut(100, script_nonreissuable))
        sig_hash, err = SignatureHash(txSuccess1.vout[1].scriptPubKey,
                                      txSuccess2, 0, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        txSuccess2.vin[0].scriptSig = CScript([signature])
        txSuccess2.rehash()

        test_transaction_acceptance(node, txSuccess2, accepted=True)

        #TxSuccess3 - coinbaseTx2 - issue 1 NFT                    (UTXO-4)
        colorId_nft = colorIdNFT(
            COutPoint(coinbase_txs[1].malfixsha256, 0).serialize())
        script_nft = CP2PHK_script(colorId=colorId_nft, pubkey=self.pubkeys[0])
        script_transfer_nft = CP2PHK_script(colorId=colorId_nft,
                                            pubkey=self.pubkeys[0])

        txSuccess3 = CTransaction()
        txSuccess3.vin.append(
            CTxIn(COutPoint(coinbase_txs[1].malfixsha256, 0), b""))
        txSuccess3.vout.append(CTxOut(1, script_nft))
        sig_hash, err = SignatureHash(coinbase_txs[1].vout[0].scriptPubKey,
                                      txSuccess3, 0, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        txSuccess3.vin[0].scriptSig = CScript([signature])
        txSuccess3.rehash()

        test_transaction_acceptance(node, txSuccess3, accepted=True)

        #TxFailure4 - (UTXO-1)    - split REISSUABLE - 25 + 75     (UTXO-5,6)
        #           - (UTXO-3)    - split NON-REISSUABLE - 40 + 60 (UTXO-7,8)
        #           - coinbaseTx3 - issue 100 REISSUABLE           (UTXO-9)
        TxFailure4 = CTransaction()
        TxFailure4.vin.append(CTxIn(COutPoint(txSuccess1.malfixsha256, 0),
                                    b""))
        TxFailure4.vin.append(CTxIn(COutPoint(txSuccess2.malfixsha256, 0),
                                    b""))
        TxFailure4.vin.append(
            CTxIn(COutPoint(coinbase_txs[2].malfixsha256, 0), b""))
        TxFailure4.vout.append(CTxOut(25, script_reissuable))
        TxFailure4.vout.append(CTxOut(75, script_reissuable))
        TxFailure4.vout.append(CTxOut(40, script_nonreissuable))
        TxFailure4.vout.append(CTxOut(60, script_nonreissuable))
        TxFailure4.vout.append(CTxOut(100, script_reissuable))
        sig_hash, err = SignatureHash(txSuccess1.vout[0].scriptPubKey,
                                      TxFailure4, 0, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure4.vin[0].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess2.vout[0].scriptPubKey,
                                      TxFailure4, 1, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure4.vin[1].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(coinbase_txs[2].vout[0].scriptPubKey,
                                      TxFailure4, 2, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        TxFailure4.vin[2].scriptSig = CScript([signature])
        TxFailure4.rehash()

        test_transaction_acceptance(node,
                                    TxFailure4,
                                    accepted=False,
                                    reason=b"bad-txns-token-balance")

        #TxSuccess4 - (UTXO-1)    - split REISSUABLE - 25 + 75     (UTXO-5,6)
        #           - (UTXO-3)    - split NON-REISSUABLE - 40 + 60 (UTXO-7,8)
        txSuccess4 = CTransaction()
        txSuccess4.vin.append(CTxIn(COutPoint(txSuccess1.malfixsha256, 0),
                                    b""))
        txSuccess4.vin.append(CTxIn(COutPoint(txSuccess2.malfixsha256, 0),
                                    b""))
        txSuccess4.vin.append(
            CTxIn(COutPoint(coinbase_txs[2].malfixsha256, 0), b""))
        txSuccess4.vout.append(CTxOut(25, script_reissuable))
        txSuccess4.vout.append(CTxOut(75, script_reissuable))
        txSuccess4.vout.append(CTxOut(40, script_nonreissuable))
        txSuccess4.vout.append(CTxOut(60, script_nonreissuable))
        sig_hash, err = SignatureHash(txSuccess1.vout[0].scriptPubKey,
                                      txSuccess4, 0, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess4.vin[0].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess2.vout[0].scriptPubKey,
                                      txSuccess4, 1, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess4.vin[1].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(coinbase_txs[2].vout[0].scriptPubKey,
                                      txSuccess4, 2, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        txSuccess4.vin[2].scriptSig = CScript([signature])
        txSuccess4.rehash()

        test_transaction_acceptance(node, txSuccess4, accepted=True)

        #TxFailure5 - (UTXO-6)    - split REISSUABLE(75)           (UTXO-10,11)
        #           - (UTXO-7)    - split NON-REISSUABLE(40)       (UTXO-12)
        #           - (UTXO-4)    - split NFT                      (UTXO-13)
        #           - coinbaseTx4
        TxFailure5 = CTransaction()
        TxFailure5.vin.append(CTxIn(COutPoint(txSuccess4.malfixsha256, 1),
                                    b""))
        TxFailure5.vin.append(CTxIn(COutPoint(txSuccess4.malfixsha256, 2),
                                    b""))
        TxFailure5.vin.append(CTxIn(COutPoint(txSuccess3.malfixsha256, 0),
                                    b""))
        TxFailure5.vin.append(
            CTxIn(COutPoint(coinbase_txs[3].malfixsha256, 0), b""))
        TxFailure5.vout.append(CTxOut(35, script_reissuable))
        TxFailure5.vout.append(CTxOut(40, script_reissuable))
        TxFailure5.vout.append(CTxOut(20, script_nonreissuable))
        TxFailure5.vout.append(CTxOut(20, script_nonreissuable))
        TxFailure5.vout.append(CTxOut(1, script_nft))
        TxFailure5.vout.append(CTxOut(1, script_nft))
        sig_hash, err = SignatureHash(txSuccess4.vout[1].scriptPubKey,
                                      TxFailure5, 0, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure5.vin[0].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess4.vout[2].scriptPubKey,
                                      TxFailure5, 1, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure5.vin[1].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess3.vout[0].scriptPubKey,
                                      TxFailure5, 2, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure5.vin[2].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(coinbase_txs[3].vout[0].scriptPubKey,
                                      TxFailure5, 3, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        TxFailure5.vin[3].scriptSig = CScript([signature])
        TxFailure5.rehash()

        test_transaction_acceptance(node,
                                    TxFailure5,
                                    accepted=False,
                                    reason=b"bad-txns-token-balance")

        #txSuccess5 - (UTXO-6)    - split REISSUABLE(75)           (UTXO-10,11)
        #           - (UTXO-7)    - split NON-REISSUABLE(40)       (UTXO-12)
        #           - (UTXO-4)    - transfer NFT                      (UTXO-13)
        #           - coinbaseTx4
        txSuccess5 = CTransaction()
        txSuccess5.vin.append(CTxIn(COutPoint(txSuccess4.malfixsha256, 1),
                                    b""))
        txSuccess5.vin.append(CTxIn(COutPoint(txSuccess4.malfixsha256, 2),
                                    b""))
        txSuccess5.vin.append(CTxIn(COutPoint(txSuccess3.malfixsha256, 0),
                                    b""))
        txSuccess5.vin.append(
            CTxIn(COutPoint(coinbase_txs[3].malfixsha256, 0), b""))
        txSuccess5.vout.append(CTxOut(35, script_reissuable))
        txSuccess5.vout.append(CTxOut(40, script_reissuable))
        txSuccess5.vout.append(CTxOut(20, script_nonreissuable))
        txSuccess5.vout.append(CTxOut(20, script_nonreissuable))
        txSuccess5.vout.append(CTxOut(1, script_nft))
        sig_hash, err = SignatureHash(txSuccess4.vout[1].scriptPubKey,
                                      txSuccess5, 0, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess5.vin[0].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess4.vout[2].scriptPubKey,
                                      txSuccess5, 1, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess5.vin[1].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess3.vout[0].scriptPubKey,
                                      txSuccess5, 2, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess5.vin[2].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(coinbase_txs[3].vout[0].scriptPubKey,
                                      txSuccess5, 3, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        txSuccess5.vin[3].scriptSig = CScript([signature])
        txSuccess5.rehash()

        test_transaction_acceptance(node, txSuccess5, accepted=True)

        #TxFailure6 - (UTXO-11)   - transfer REISSUABLE(40)        (UTXO-14)
        #           - (UTXO-8)    - burn NON-REISSUABLE(60)        (UTXO-15)*
        #           - (UTXO-13)   - transfer NFT                   (UTXO-16)
        #           - coinbaseTx5 - issue 1000 REISSUABLE1, change (UTXO-17)
        colorId_reissuable1 = colorIdReissuable(
            coinbase_txs[6].vout[0].scriptPubKey)
        script_reissuable1 = CP2PHK_script(colorId=colorId_reissuable,
                                           pubkey=self.pubkeys[0])

        TxFailure6 = CTransaction()
        TxFailure6.vin.append(CTxIn(COutPoint(txSuccess5.malfixsha256, 1),
                                    b""))
        TxFailure6.vin.append(CTxIn(COutPoint(txSuccess4.malfixsha256, 3),
                                    b""))
        TxFailure6.vin.append(CTxIn(COutPoint(txSuccess5.malfixsha256, 4),
                                    b""))
        TxFailure6.vin.append(
            CTxIn(COutPoint(coinbase_txs[4].malfixsha256, 0), b""))
        TxFailure6.vout.append(CTxOut(40, script_transfer_reissuable))
        TxFailure6.vout.append(CTxOut(30, script_transfer_nonreissuable))
        TxFailure6.vout.append(CTxOut(1, script_transfer_nft))
        TxFailure6.vout.append(CTxOut(1000, script_reissuable1))
        TxFailure6.vout.append(CTxOut(1 * COIN, change_script))
        sig_hash, err = SignatureHash(txSuccess5.vout[1].scriptPubKey,
                                      TxFailure6, 0, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure6.vin[0].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess4.vout[3].scriptPubKey,
                                      TxFailure6, 1, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure6.vin[1].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess5.vout[4].scriptPubKey,
                                      TxFailure6, 2, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure6.vin[2].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(coinbase_txs[4].vout[0].scriptPubKey,
                                      TxFailure6, 3, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        TxFailure6.vin[3].scriptSig = CScript([signature])
        TxFailure6.rehash()

        test_transaction_acceptance(node,
                                    TxFailure6,
                                    accepted=False,
                                    reason=b"bad-txns-token-balance")

        #TxSuccess6 - (UTXO-11)   - transfer REISSUABLE(40)        (UTXO-14)
        #           - (UTXO-8)    - burn NON-REISSUABLE(60)        (UTXO-15)*
        #           - (UTXO-13)   - transfer NFT                   (UTXO-16)
        #           - coinbaseTx5 - change
        txSuccess6 = CTransaction()
        txSuccess6.vin.append(CTxIn(COutPoint(txSuccess5.malfixsha256, 1),
                                    b""))
        txSuccess6.vin.append(CTxIn(COutPoint(txSuccess4.malfixsha256, 3),
                                    b""))
        txSuccess6.vin.append(CTxIn(COutPoint(txSuccess5.malfixsha256, 4),
                                    b""))
        txSuccess6.vin.append(
            CTxIn(COutPoint(coinbase_txs[4].malfixsha256, 0), b""))
        txSuccess6.vout.append(CTxOut(40, script_transfer_reissuable))
        txSuccess6.vout.append(CTxOut(30, script_transfer_nonreissuable))
        txSuccess6.vout.append(CTxOut(1, script_transfer_nft))
        txSuccess6.vout.append(CTxOut(1 * COIN, change_script))
        sig_hash, err = SignatureHash(txSuccess5.vout[1].scriptPubKey,
                                      txSuccess6, 0, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess6.vin[0].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess4.vout[3].scriptPubKey,
                                      txSuccess6, 1, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess6.vin[1].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess5.vout[4].scriptPubKey,
                                      txSuccess6, 2, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess6.vin[2].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(coinbase_txs[4].vout[0].scriptPubKey,
                                      txSuccess6, 3, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        txSuccess6.vin[3].scriptSig = CScript([signature])
        txSuccess6.rehash()

        test_transaction_acceptance(node, txSuccess6, accepted=True)

        #TxSuccess7 - coinbaseTx5 - issue 1000 REISSUABLE1, change (UTXO-17)
        txSuccess7 = CTransaction()
        txSuccess7.vin.append(
            CTxIn(COutPoint(coinbase_txs[5].malfixsha256, 0), b""))
        txSuccess7.vout.append(CTxOut(1000, script_reissuable1))
        sig_hash, err = SignatureHash(coinbase_txs[5].vout[0].scriptPubKey,
                                      txSuccess7, 0, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        txSuccess7.vin[0].scriptSig = CScript([signature])
        txSuccess7.rehash()

        test_transaction_acceptance(node, txSuccess7, accepted=True)

        #TxFailure7 - (UTXO-9,14) - aggregate REISSUABLE(25 + 40) x
        #           - (UTXO-12)   - burn NON-REISSUABLE(20)        *
        TxFailure7 = CTransaction()
        TxFailure7.vin.append(CTxIn(COutPoint(txSuccess4.malfixsha256, 0),
                                    b""))
        TxFailure7.vin.append(CTxIn(COutPoint(txSuccess6.malfixsha256, 0),
                                    b""))
        TxFailure7.vin.append(CTxIn(COutPoint(txSuccess5.malfixsha256, 2),
                                    b""))
        TxFailure7.vout.append(CTxOut(65, script_transfer_reissuable))
        sig_hash, err = SignatureHash(txSuccess4.vout[0].scriptPubKey,
                                      TxFailure7, 0, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure7.vin[0].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess6.vout[0].scriptPubKey,
                                      TxFailure7, 1, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure7.vin[1].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess5.vout[2].scriptPubKey,
                                      TxFailure7, 2, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        TxFailure7.vin[2].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        TxFailure7.rehash()

        test_transaction_acceptance(node,
                                    TxFailure7,
                                    accepted=False,
                                    reason=b'min relay fee not met')

        #txSuccess8 - (UTXO-9,14) - aggregate REISSUABLE(25 + 40) x
        #           - (UTXO-12)   - burn NON-REISSUABLE(20)        *
        #           - coinbase[6]
        txSuccess8 = CTransaction()
        txSuccess8.vin.append(CTxIn(COutPoint(txSuccess4.malfixsha256, 0),
                                    b""))
        txSuccess8.vin.append(CTxIn(COutPoint(txSuccess6.malfixsha256, 0),
                                    b""))
        txSuccess8.vin.append(CTxIn(COutPoint(txSuccess5.malfixsha256, 2),
                                    b""))
        txSuccess8.vin.append(
            CTxIn(COutPoint(coinbase_txs[6].malfixsha256, 0), b""))
        txSuccess8.vout.append(CTxOut(65, script_transfer_reissuable))
        sig_hash, err = SignatureHash(txSuccess4.vout[0].scriptPubKey,
                                      txSuccess8, 0, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess8.vin[0].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(txSuccess6.vout[0].scriptPubKey,
                                      txSuccess8, 1, SIGHASH_ALL)
        signature = self.privkeys[1].sign(sig_hash) + b'\x01'
        txSuccess8.vin[1].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[1])])
        sig_hash, err = SignatureHash(txSuccess5.vout[2].scriptPubKey,
                                      txSuccess8, 2, SIGHASH_ALL)
        signature = self.privkeys[0].sign(sig_hash) + b'\x01'
        txSuccess8.vin[2].scriptSig = CScript(
            [signature, hex_str_to_bytes(self.pubkeys[0])])
        sig_hash, err = SignatureHash(coinbase_txs[6].vout[0].scriptPubKey,
                                      txSuccess8, 3, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        txSuccess8.vin[3].scriptSig = CScript([signature])
        txSuccess8.rehash()

        test_transaction_acceptance(node, txSuccess8, accepted=True)

        #TxFailure8 - (UTXO-17)   - convert REISSUABLE to NON-REISSUABLE
        TxFailure8 = CTransaction()
        TxFailure8.vin.append(CTxIn(COutPoint(txSuccess7.malfixsha256, 0),
                                    b""))
        TxFailure8.vout.append(CTxOut(60, script_transfer_nonreissuable))
        sig_hash, err = SignatureHash(txSuccess7.vout[0].scriptPubKey,
                                      TxFailure8, 0, SIGHASH_ALL)
        signature = self.coinbase_key.sign(sig_hash) + b'\x01'
        TxFailure8.vin[0].scriptSig = CScript([signature])
        TxFailure8.rehash()

        test_transaction_acceptance(node,
                                    TxFailure8,
                                    accepted=False,
                                    reason=b'invalid-colorid')