示例#1
0
    def run_test(self):

        def findUtxoInList(txid, vout, utxo_list):
            for x in utxo_list:
                if x["txid"] == txid and x["vout"] == vout:
                    return True, x
            return False, None

        # Check NYEX and zNYEX supply at the beginning
        # ------------------------------------------
        # zNYEX supply: 2 coins for each denomination
        expected_znyex_supply = {
            "1": 2,
            "5": 10,
            "10": 20,
            "50": 100,
            "100": 200,
            "500": 1000,
            "1000": 2000,
            "5000": 10000,
            "total": 13332,
        }
        # NYEX supply: block rewards minus burned fees for minting
        expected_money_supply = 250.0 * 330 - 16 * 0.01
        self.check_money_supply(expected_money_supply, expected_znyex_supply)

        # Stake with node 0 and node 1 up to public spend activation (400)
        # 70 blocks: 5 blocks each (x7)
        self.log.info("Staking 70 blocks to reach public spends activation...")
        set_node_times(self.nodes, self.mocktime)
        for i in range(7):
            for peer in range(2):
                for nblock in range(5):
                    self.mocktime = self.generate_pos(peer, self.mocktime)
                sync_blocks(self.nodes)
        block_time_0 = block_time_1 = self.mocktime
        self.log.info("Blocks staked.")

        # Check balances
        self.log.info("Checking balances...")
        initial_balance = [self.get_tot_balance(i) for i in range(self.num_nodes)]
        # --nodes 0, 1: 62 pow blocks + 55 pos blocks
        assert_equal(initial_balance[0], DecimalAmt(250.0 * (62 + 55)))
        assert_equal(initial_balance[1], DecimalAmt(250.0 * (62 + 55)))
        # --node 2: 62 pow blocks + 20 pos blocks - zc minted - zcfee
        assert_equal(initial_balance[2], DecimalAmt(250.0 * (62 + 20) - 6666 - 0.08))
        assert_equal(self.nodes[2].getzerocoinbalance()['Total'], DecimalAmt(6666))
        self.log.info("Balances ok.")

        # create the raw zerocoin spend txes
        addy = self.nodes[2].getnewaddress()
        self.log.info("Creating the raw zerocoin public spends...")
        mints = self.nodes[2].listmintedzerocoins(True, True)
        tx_A0 = self.nodes[2].createrawzerocoinspend(mints[0]["serial hash"], addy)
        tx_A1 = self.nodes[2].createrawzerocoinspend(mints[1]["serial hash"], addy)
        # Spending same coins to different recipients to get different txids
        new_addy = "yAVWM5urwaTyhiuFQHP2aP47rdZsLUG5PH"
        tx_B0 = self.nodes[2].createrawzerocoinspend(mints[0]["serial hash"], new_addy)
        tx_B1 = self.nodes[2].createrawzerocoinspend(mints[1]["serial hash"], new_addy)

        # Disconnect nodes
        minted_amount = mints[0]["denomination"] + mints[1]["denomination"]
        self.disconnect_all()

        # Stake one block with node-0 and save the stake input
        self.log.info("Staking 1 block with node 0...")
        initial_unspent_0 = self.nodes[0].listunspent()
        self.nodes[0].generate(1)
        block_time_0 += 60
        set_node_times(self.nodes, block_time_0)
        last_block = self.nodes[0].getblock(self.nodes[0].getbestblockhash())
        assert(len(last_block["tx"]) > 1)                                       # a PoS block has at least two txes
        coinstake_txid = last_block["tx"][1]
        coinstake_tx = self.nodes[0].getrawtransaction(coinstake_txid, True)
        assert (coinstake_tx["vout"][0]["scriptPubKey"]["hex"] == "")  # first output of coinstake is empty
        stakeinput = coinstake_tx["vin"][0]

        # The stake input was unspent 1 block ago, now it's not
        res, utxo = findUtxoInList(stakeinput["txid"], stakeinput["vout"], initial_unspent_0)
        assert (res and utxo["spendable"])
        res, utxo = findUtxoInList(stakeinput["txid"], stakeinput["vout"], self.nodes[0].listunspent())
        assert (not res or not utxo["spendable"])
        self.log.info("Coinstake input %s...%s-%d is no longer spendable." % (
            stakeinput["txid"][:9], stakeinput["txid"][-4:], stakeinput["vout"]))

        # Relay zerocoin spends
        self.nodes[0].sendrawtransaction(tx_A0)
        self.nodes[0].sendrawtransaction(tx_A1)

        # Stake 10 more blocks with node-0 and check balances
        self.log.info("Staking 10 more blocks with node 0...")
        for i in range(10):
            block_time_0 = self.generate_pos(0, block_time_0)
        expected_balance_0 = initial_balance[0] + DecimalAmt(11 * 250.0)
        assert_equal(self.get_tot_balance(0), expected_balance_0)
        self.log.info("Balance for node 0 checks out.")

        # Connect with node 2, sync and check zerocoin balance
        self.log.info("Reconnecting node 0 and node 2")
        connect_nodes(self.nodes[0], 2)
        sync_blocks([self.nodes[i] for i in [0, 2]])
        self.log.info("Resetting zerocoin mints on node 2")
        self.nodes[2].resetmintzerocoin(True)
        assert_equal(self.get_tot_balance(2), initial_balance[2] + DecimalAmt(minted_amount))
        assert_equal(self.nodes[2].getzerocoinbalance()['Total'], DecimalAmt(6666-minted_amount))
        self.log.info("Balance for node 2 checks out.")

        # Double spending txes not possible
        assert_raises_rpc_error(-26, "bad-zc-spend-contextcheck",
                                self.nodes[0].sendrawtransaction, tx_B0)
        assert_raises_rpc_error(-26, "bad-zc-spend-contextcheck",
                                self.nodes[0].sendrawtransaction, tx_B1)

        # verify that the stakeinput can't be spent
        stakeinput_tx_json = self.nodes[0].getrawtransaction(stakeinput["txid"], True)
        stakeinput_amount = float(stakeinput_tx_json["vout"][int(stakeinput["vout"])]["value"])
        rawtx_unsigned = self.nodes[0].createrawtransaction(
            [{"txid": stakeinput["txid"], "vout": int(stakeinput["vout"])}],
            {"xxncEuJK27ygNh7imNfaX8JV6ZQUnoBqzN": (stakeinput_amount-0.01)})
        rawtx = self.nodes[0].signrawtransaction(rawtx_unsigned)
        assert(rawtx["complete"])
        try:
            self.nodes[0].sendrawtransaction(rawtx["hex"])
        except JSONRPCException as e:
            # JSONRPCException was thrown as expected. Check the code and message values are correct.
            if e.error["code"] not in [-26, -25]:
                raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"])
            if ([x for x in ["bad-txns-inputs-spent", "Missing inputs"] if x in e.error['message']] == []):
                raise e
        except Exception as e:
            raise AssertionError("Unexpected exception raised: " + type(e).__name__)
        self.log.info("GOOD: v2 spend was not possible.")

        # Spend tx_B0 and tx_B1 on the other chain
        self.nodes[1].sendrawtransaction(tx_B0)
        self.nodes[1].sendrawtransaction(tx_B1)

        # Stake 12 blocks with node-1
        set_node_times(self.nodes, block_time_1)
        self.log.info("Staking 12 blocks with node 1...")
        for i in range(12):
            block_time_1 = self.generate_pos(1, block_time_1)
        expected_balance_1 = initial_balance[1] + DecimalAmt(12 * 250.0)
        assert_equal(self.get_tot_balance(1), expected_balance_1)
        self.log.info("Balance for node 1 checks out.")

        # re-connect and sync nodes and check that node-0 and node-2 get on the other chain
        new_best_hash = self.nodes[1].getbestblockhash()
        self.log.info("Connecting and syncing nodes...")
        set_node_times(self.nodes, block_time_1)
        connect_nodes_clique(self.nodes)
        sync_blocks(self.nodes)
        for i in [0, 2]:
            assert_equal(self.nodes[i].getbestblockhash(), new_best_hash)

        # check balance of node-0
        assert_equal(self.get_tot_balance(0), initial_balance[0])
        self.log.info("Balance for node 0 checks out.")

        # check that NOW the original stakeinput is present and spendable
        res, utxo = findUtxoInList(stakeinput["txid"], stakeinput["vout"], self.nodes[0].listunspent())
        assert (res and utxo["spendable"])
        self.log.info("Coinstake input %s...%s-%d is spendable again." % (
            stakeinput["txid"][:9], stakeinput["txid"][-4:], stakeinput["vout"]))
        self.nodes[0].sendrawtransaction(rawtx["hex"])
        self.nodes[1].generate(1)
        sync_blocks(self.nodes)
        res, utxo = findUtxoInList(stakeinput["txid"], stakeinput["vout"], self.nodes[0].listunspent())
        assert (not res or not utxo["spendable"])

        # Verify that NYEX and zNYEX supplies were properly updated after the spends and reorgs
        self.log.info("Check NYEX and zNYEX supply...")
        expected_money_supply += 250.0 * (self.nodes[1].getblockcount() - 330)
        spent_coin_0 = mints[0]["denomination"]
        spent_coin_1 = mints[1]["denomination"]
        expected_znyex_supply[str(spent_coin_0)] -= spent_coin_0
        expected_znyex_supply[str(spent_coin_1)] -= spent_coin_1
        expected_znyex_supply["total"] -= (spent_coin_0 + spent_coin_1)
        self.check_money_supply(expected_money_supply, expected_znyex_supply)
        self.log.info("Supply checks out.")
示例#2
0
 def reconnect_remotes(self):
     connect_nodes_clique(self.nodes)
     self.sync_all()
示例#3
0
 def setup_network(self):
     # connect all nodes between each other
     self.setup_nodes()
     connect_nodes_clique(self.nodes)
     self.sync_all()
示例#4
0
    def run_test(self):

        def findUtxoInList(txid, vout, utxo_list):
            for x in utxo_list:
                if x["txid"] == txid and x["vout"] == vout:
                    return True, x
            return False, None

        # PIV supply: block rewards
        expected_money_supply = 250.0 * 200
        self.check_money_supply(expected_money_supply)
        initial_time = self.mocktime

        # Check balances
        self.log.info("Checking balances...")
        initial_balance = [self.get_tot_balance(i) for i in range(self.num_nodes)]
        # -- 50 pow blocks each
        assert_equal(initial_balance, [DecimalAmt(250.0 * 50)] * self.num_nodes)
        self.log.info("Balances ok.")

        # Disconnect nodes
        self.disconnect_all()

        # Stake one block with node-0 and save the stake input
        self.log.info("Staking 1 block with node 0...")
        initial_unspent_0 = self.nodes[0].listunspent()
        self.mocktime = self.generate_pos(0, self.mocktime)
        last_block = self.nodes[0].getblock(self.nodes[0].getbestblockhash())
        assert(len(last_block["tx"]) > 1)   # a PoS block has at least two txes
        coinstake_txid = last_block["tx"][1]
        coinstake_tx = self.nodes[0].getrawtransaction(coinstake_txid, True)
        assert (coinstake_tx["vout"][0]["scriptPubKey"]["hex"] == "")  # first output of coinstake is empty
        stakeinput = coinstake_tx["vin"][0]

        # The stake input was unspent 1 block ago, now it's not
        res, utxo = findUtxoInList(stakeinput["txid"], stakeinput["vout"], initial_unspent_0)
        assert (res)
        res, utxo = findUtxoInList(stakeinput["txid"], stakeinput["vout"], self.nodes[0].listunspent())
        assert (not res)
        self.log.info("Coinstake input %s...%s-%d is no longer spendable." % (
            stakeinput["txid"][:9], stakeinput["txid"][-4:], stakeinput["vout"]))

        # Stake 10 more blocks with node-0 and check balances
        self.log.info("Staking 10 more blocks with node 0...")
        for i in range(10):
            self.mocktime = self.generate_pos(0, self.mocktime)
        expected_balance_0 = initial_balance[0] + DecimalAmt(11 * 250.0)
        assert_equal(self.get_tot_balance(0), expected_balance_0)
        self.log.info("Balance for node 0 checks out.")

        # Connect with node 2 and sync
        self.log.info("Reconnecting node 0 and node 2")
        connect_nodes(self.nodes[0], 2)
        self.sync_blocks([self.nodes[i] for i in [0, 2]])

        # verify that the stakeinput can't be spent
        stakeinput_tx_json = self.nodes[0].getrawtransaction(stakeinput["txid"], True)
        stakeinput_amount = float(stakeinput_tx_json["vout"][int(stakeinput["vout"])]["value"])
        rawtx_unsigned = self.nodes[0].createrawtransaction(
            [{"txid": stakeinput["txid"], "vout": int(stakeinput["vout"])}],
            {"xxncEuJK27ygNh7imNfaX8JV6ZQUnoBqzN": (stakeinput_amount-0.01)})
        rawtx = self.nodes[0].signrawtransaction(rawtx_unsigned)
        assert(rawtx["complete"])
        assert_raises_rpc_error(-25, "Missing inputs", self.nodes[0].sendrawtransaction, rawtx["hex"])
        txid = self.nodes[0].decoderawtransaction(rawtx["hex"])["txid"]
        assert_raises_rpc_error(-5, "No such mempool or blockchain transaction",
                                self.nodes[0].getrawtransaction, txid)
        self.log.info("GOOD: spending the stake input was not possible.")

        # Stake 12 blocks with node-1
        self.mocktime = initial_time
        set_node_times(self.nodes, self.mocktime)
        self.log.info("Staking 12 blocks with node 1...")
        for i in range(12):
            self.mocktime = self.generate_pos(1, self.mocktime)
        expected_balance_1 = initial_balance[1] + DecimalAmt(12 * 250.0)
        assert_equal(self.get_tot_balance(1), expected_balance_1)
        self.log.info("Balance for node 1 checks out.")

        # re-connect and sync nodes and check that node-0 and node-2 get on the other chain
        new_best_hash = self.nodes[1].getbestblockhash()
        self.log.info("Connecting and syncing nodes...")
        set_node_times(self.nodes, self.mocktime)
        connect_nodes_clique(self.nodes)
        self.sync_blocks()
        for i in [0, 2]:
            assert_equal(self.nodes[i].getbestblockhash(), new_best_hash)

        # check balance of node-0
        assert_equal(self.get_tot_balance(0), initial_balance[0])
        self.log.info("Balance for node 0 checks out.")

        # check that NOW the original stakeinput is present and spendable
        res, utxo = findUtxoInList(stakeinput["txid"], stakeinput["vout"], self.nodes[0].listunspent())
        assert res and utxo["spendable"]
        self.log.info("Coinstake input %s...%s-%d is spendable again." % (
            stakeinput["txid"][:9], stakeinput["txid"][-4:], stakeinput["vout"]))
        self.nodes[0].sendrawtransaction(rawtx["hex"])
        self.sync_mempools()
        self.mocktime = self.generate_pos(1, self.mocktime)
        self.sync_blocks()
        res, utxo = findUtxoInList(stakeinput["txid"], stakeinput["vout"], self.nodes[0].listunspent())
        assert not res

        # Verify that PIV supply was properly updated after the reorgs (including burned fee)
        self.log.info("Check PIV supply...")
        expected_money_supply += 250.0 * (self.nodes[1].getblockcount() - 200) - 0.01
        self.check_money_supply(expected_money_supply)
        self.log.info("Supply checks out.")