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 JDC and zJDC supply at the beginning # ------------------------------------------ # zJDC supply: 2 coins for each denomination expected_zjdc_supply = { "1": 2, "5": 10, "10": 20, "50": 100, "100": 200, "500": 1000, "1000": 2000, "5000": 10000, "total": 13332, } # JDC 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_zjdc_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-txns-invalid-zjdc", self.nodes[0].sendrawtransaction, tx_B0) assert_raises_rpc_error(-26, "bad-txns-invalid-zjdc", 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 JDC and zJDC supplies were properly updated after the spends and reorgs self.log.info("Check JDC and zJDC supply...") expected_money_supply += 250.0 * (self.nodes[1].getblockcount() - 330) spent_coin_0 = mints[0]["denomination"] spent_coin_1 = mints[1]["denomination"] expected_zjdc_supply[str(spent_coin_0)] -= spent_coin_0 expected_zjdc_supply[str(spent_coin_1)] -= spent_coin_1 expected_zjdc_supply["total"] -= (spent_coin_0 + spent_coin_1) self.check_money_supply(expected_money_supply, expected_zjdc_supply) self.log.info("Supply checks out.")
def run_test(self): def get_zerocoin_data(coin): return coin["s"], coin["r"], coin["k"], coin["id"], coin["d"], coin["t"] def check_balances(denom, zpiv_bal, piv_bal): zpiv_bal -= denom assert_equal(self.nodes[2].getzerocoinbalance()['Total'], zpiv_bal) piv_bal += denom wi = self.nodes[2].getwalletinfo() assert_equal(wi['balance'] + wi['immature_balance'], piv_bal) return zpiv_bal, piv_bal def stake_4_blocks(block_time): for peer in range(2): for i in range(2): block_time = self.generate_pos(peer, block_time) sync_blocks(self.nodes) return block_time self.log_title() block_time = self.mocktime set_node_times(self.nodes, block_time) # Start with cache balances wi = self.nodes[2].getwalletinfo() balance = wi['balance'] + wi['immature_balance'] zpiv_balance = self.nodes[2].getzerocoinbalance()['Total'] assert_equal(balance, DecimalAmt(13833.92)) assert_equal(zpiv_balance, 6666) # Export zerocoin data listmints = self.nodes[2].listmintedzerocoins(True, True) serial_ids = [mint["serial hash"] for mint in listmints] exported_zerocoins = [x for x in self.nodes[2].exportzerocoins(False) if x["id"] in serial_ids] exported_zerocoins.sort(key=lambda x: x["d"], reverse=False) assert_equal(8, len(exported_zerocoins)) # 1) Try to do a v3 spend before activation self.log.info("Trying to make a public spend...") serial_0, randomness_0, privkey_0, id_0, denom_0, tx_0 = get_zerocoin_data(exported_zerocoins[0]) assert_raises_rpc_error(-4, "The transaction was rejected!", self.nodes[2].spendrawzerocoin, serial_0, randomness_0, denom_0, privkey_0, "", tx_0) self.log.info("GOOD: v3 spend is not possible yet.") # 2) stake more blocks - save a v3 spend for later (serial_1) serial_1, randomness_1, privkey_1, id_1, denom_1, tx_1 = get_zerocoin_data(exported_zerocoins[1]) self.log.info("Staking 70 blocks to get to public spend activation") for j in range(5): for peer in range(2): for i in range(7): block_time = self.generate_pos(peer, block_time) sync_blocks(self.nodes) old_spend_v3 = self.nodes[2].createrawzerocoinspend(id_1) # 3) Spend one minted coin - spend v3 (serial_2) serial_2, randomness_2, privkey_2, id_2, denom_2, tx_2 = get_zerocoin_data(exported_zerocoins[2]) self.log.info("Spending the minted coin with serial %s..." % serial_2[:16]) txid = self.nodes[2].spendzerocoinmints([id_2])['txid'] # stake 4 blocks - check it gets included on chain and check balances block_time = stake_4_blocks(block_time) self.check_tx_in_chain(0, txid) zpiv_balance, balance = check_balances(denom_2, zpiv_balance, balance) self.log.info("--> VALID PUBLIC COIN SPEND (v3) PASSED") # 4) Check double spends - spend v3 self.log.info("Trying to spend the serial twice now...") assert_raises_rpc_error(-4, "Trying to spend an already spent serial", self.nodes[2].spendrawzerocoin, serial_2, randomness_2, denom_2, privkey_2, "", tx_2) # 5) Activate v4 spends with SPORK_18 self.setV4SpendEnforcement() # 6) Spend one minted coin - spend v4 (serial_3) serial_3, randomness_3, privkey_3, id_3, denom_3, tx_3 = get_zerocoin_data(exported_zerocoins[3]) self.log.info("Spending the minted coin with serial %s..." % serial_3[:16]) txid = self.nodes[2].spendzerocoinmints([id_3])['txid'] # stake 4 blocks - check it gets included on chain and check balances block_time = stake_4_blocks(block_time) self.check_tx_in_chain(0, txid) zpiv_balance, balance = check_balances(denom_3, zpiv_balance, balance) self.log.info("--> VALID PUBLIC COIN SPEND (v4) PASSED") # 7) Check double spends - spend v4 self.log.info("Trying to spend the serial twice now...") assert_raises_rpc_error(-4, "Trying to spend an already spent serial", self.nodes[2].spendrawzerocoin, serial_3, randomness_3, denom_3, privkey_3, "", tx_3) # 8) Try to relay old v3 spend now (serial_1) self.log.info("Trying to send old v3 spend now...") assert_raises_rpc_error(-26, "bad-txns-invalid-zpiv", self.nodes[2].sendrawtransaction, old_spend_v3) self.log.info("GOOD: Old transaction not sent.") # 9) Try to double spend with v4 a mint already spent with v3 (serial_2) self.log.info("Trying to double spend v4 against v3...") assert_raises_rpc_error(-4, "Trying to spend an already spent serial", self.nodes[2].spendrawzerocoin, serial_2, randomness_2, denom_2, privkey_2, "", tx_2) self.log.info("GOOD: Double-spending transaction did not verify.") # 10) Reactivate v3 spends and try to spend the old saved one (serial_1) again self.setV4SpendEnforcement(False) self.log.info("Trying to send old v3 spend now (serial: %s...)" % serial_1[:16]) txid = self.nodes[2].sendrawtransaction(old_spend_v3) # stake 4 blocks - check it gets included on chain and check balances _ = stake_4_blocks(block_time) self.check_tx_in_chain(0, txid) # need to reset spent mints since this was a raw broadcast self.nodes[2].resetmintzerocoin() _, _ = check_balances(denom_1, zpiv_balance, balance) self.log.info("--> VALID PUBLIC COIN SPEND (v3) PASSED")
def run_test(self): self.min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee'] # This test is not meant to test fee estimation and we'd like # to be sure all txs are sent at a consistent desired feerate for node in self.nodes: node.settxfee(float(self.min_relay_tx_fee)) # if the fee's positive delta is higher than this value tests will fail, # neg. delta always fail the tests. # The size of the signature of every input may be at most 2 bytes larger # than a minimum sized signature. # = 2 bytes * minRelayTxFeePerByte self.fee_tolerance = 2 * self.min_relay_tx_fee / 1000 print("Mining blocks...") self.nodes[1].generate(1) self.sync_all() self.nodes[0].generate(121) self.sync_all() watchonly_address = self.nodes[0].getnewaddress() watchonly_pubkey = self.nodes[0].validateaddress( watchonly_address)["pubkey"] self.watchonly_amount = DecimalAmt(200.0) self.nodes[3].importpubkey(watchonly_pubkey, "", True) self.watchonly_txid = self.nodes[0].sendtoaddress( watchonly_address, float(self.watchonly_amount)) # Lock UTXO so nodes[0] doesn't accidentally spend it self.watchonly_vout = find_vout_for_address(self.nodes[0], self.watchonly_txid, watchonly_address) self.nodes[0].lockunspent(False, [{ "txid": self.watchonly_txid, "vout": self.watchonly_vout }]) self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), float(self.watchonly_amount) / 10) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0) self.sync_all() self.nodes[0].generate(1) self.sync_all() self.test_simple() self.test_simple_two_coins() self.test_simple_one_coin() self.test_simple_two_outputs() self.test_change() self.test_no_change() self.test_change_position() self.test_invalid_option() self.test_invalid_change_address() self.test_valid_change_address() self.test_coin_selection() self.test_two_vin() self.test_two_vin_two_vout() self.test_invalid_input() self.test_fee_p2pkh() self.test_fee_p2pkh_multi_out() self.test_fee_p2sh() self.test_fee_4of5() self.test_spend_2of2() self.test_locked_wallet() self.test_many_inputs_fee() self.test_many_inputs() self.test_op_return() self.test_watchonly() self.test_all_watched_funds() self.test_option_feerate()
def run_test(self): def get_zerocoin_data(coin): return coin["s"], coin["r"], coin["k"], coin["id"], coin["d"], coin["t"] def check_balances(denom, zpiv_bal, piv_bal): zpiv_bal -= denom assert_equal(self.nodes[2].getzerocoinbalance()['Total'], zpiv_bal) piv_bal += denom wi = self.nodes[2].getwalletinfo() assert_equal(wi['balance'] + wi['immature_balance'], piv_bal) return zpiv_bal, piv_bal def stake_4_blocks(block_time): for peer in range(2): for i in range(2): block_time = self.generate_pos(peer, block_time) sync_blocks(self.nodes) return block_time q = 73829871667027927151400291810255409637272593023945445234219354687881008052707 pow2 = 2**256 K_BITSIZE = 128 # bitsize of the range for random K self.log_title() block_time = self.mocktime set_node_times(self.nodes, block_time) # Start with cache balances wi = self.nodes[2].getwalletinfo() balance = wi['balance'] + wi['immature_balance'] zpiv_balance = self.nodes[2].getzerocoinbalance()['Total'] assert_equal(balance, DecimalAmt(13833.92)) assert_equal(zpiv_balance, 6666) # Export zerocoin data listmints = self.nodes[2].listmintedzerocoins(True, True) serial_ids = [mint["serial hash"] for mint in listmints] exported_zerocoins = [x for x in self.nodes[2].exportzerocoins(False) if x["id"] in serial_ids] exported_zerocoins.sort(key=lambda x: x["d"], reverse=False) assert_equal(8, len(exported_zerocoins)) # 1) Spend 1 coin and mine two more blocks serial_0, randomness_0, privkey_0, id_0, denom_0, tx_0 = get_zerocoin_data(exported_zerocoins[0]) self.log.info("Spending the minted coin with serial %s..." % serial_0[:16]) txid = self.nodes[2].spendzerocoin(denom_0, False, False, "", False)['txid'] # stake 4 blocks - check it gets included on chain and check balances block_time = stake_4_blocks(block_time) self.check_tx_in_chain(0, txid) zpiv_balance, balance = check_balances(denom_0, zpiv_balance, balance) self.log.info("Coin spent.") # 2) create 5 new coins new_coins = [] for i in range(5): K = random.getrandbits(K_BITSIZE) new_coins.append({ "s": hex(int(serial_0, 16) + K*q*pow2)[2:], "r": randomness_0, "d": denom_0, "p": privkey_0, "t": tx_0}) # 3) Spend the new zerocoins (V2) for c in new_coins: self.log.info("V2 - Spending the wrapping serial %s" % c["s"]) assert_raises_rpc_error(-4, "CoinSpend: failed check", self.nodes[2].spendrawzerocoin, c["s"], c["r"], c["d"], c["p"], "", c["t"], False) self.log.info("GOOD: It was not possible")
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 # FLS supply: block rewards expected_money_supply = 250.0 * 200 self.check_money_supply(expected_money_supply) block_time_0 = block_time_1 = 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.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) 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): 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 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 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) 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.nodes[1].generate(1) self.sync_blocks() res, utxo = findUtxoInList(stakeinput["txid"], stakeinput["vout"], self.nodes[0].listunspent()) assert (not res or not utxo["spendable"]) # Verify that FLS supply was properly updated after the reorgs self.log.info("Check FLS supply...") expected_money_supply += 250.0 * (self.nodes[1].getblockcount() - 200) self.check_money_supply(expected_money_supply) self.log.info("Supply checks out.")
def check_money_supply(self, expected_piv): # verify that nodes have the expected PIV supply piv_supply = [self.nodes[i].getsupplyinfo(True)['transparentsupply'] for i in range(self.num_nodes)] assert_equal(piv_supply, [DecimalAmt(expected_piv)] * self.num_nodes)
def test_simple_one_coin(self): self.log.info("simple test with one coin") dec_tx, fee, changepos = self.create_and_fund(2, [], {self.nodes[0].getnewaddress(): 2.6}) assert_equal(len(dec_tx['vin']) > 0, True) # test if we have enought inputs assert_greater_than(changepos, -1) # check change assert_equal(Decimal(dec_tx['vout'][changepos]['value']) + fee, DecimalAmt(2.4))