def run_test(self): block_number = 10 for i in range(1, block_number): chosen_peer = random.randint(0, self.num_nodes - 1) block_hash = self.nodes[chosen_peer].generate_empty_blocks(1) self.log.info("generate block %s", block_hash) wait_for_block_count(self.nodes[0], block_number, timeout=30) sync_blocks(self.nodes, timeout=30) self.log.info("generated blocks received by all") self.stop_node(0, kill=True) self.log.info("node 0 stopped") block_hash = self.nodes[-1].generate_empty_blocks(1) self.log.info("generate block %s", block_hash) wait_for_block_count(self.nodes[1], block_number + 1) sync_blocks(self.nodes[1:], timeout=30) self.log.info("blocks sync success among running nodes") self.start_node(0) sync_blocks(self.nodes, timeout=30) self.log.info("Pass 1") for i in range(1, self.num_nodes): self.stop_node(i) self.nodes[0].add_p2p_connection(P2PInterface()) network_thread_start() self.nodes[0].p2p.wait_for_status() client = RpcClient(self.nodes[0]) gas_price = 1 value = 1 receiver_sk, _ = ec_random_keys() sender_key = default_config["GENESIS_PRI_KEY"] tx = create_transaction(pri_key=sender_key, receiver=priv_to_addr(receiver_sk), value=value, nonce=0, gas_price=gas_price) self.nodes[0].p2p.send_protocol_msg(Transactions(transactions=[tx])) self.log.debug("New tx %s: %s send value %d to %s", encode_hex(tx.hash), eth_utils.encode_hex(priv_to_addr(sender_key))[-4:], value, eth_utils.encode_hex(priv_to_addr(receiver_sk))[-4:]) def check_packed(): client.generate_block(1) return checktx(self.nodes[0], tx.hash_hex()) wait_until(lambda: check_packed()) sender_addr = eth_utils.encode_hex(priv_to_addr(sender_key)) receiver_addr = eth_utils.encode_hex(priv_to_addr(receiver_sk)) sender_balance = default_config["TOTAL_COIN"] - value - gas_price * 21000 # Generate 2 * CACHE_INDEX_STRIDE to start evicting anticone cache self.nodes[0].generate_empty_blocks(2000) assert_equal(client.get_balance(sender_addr), sender_balance) assert_equal(client.get_balance(receiver_addr), value) time.sleep(1) self.stop_node(0) self.start_node(0) self.log.info("Wait for node 0 to recover from crash") wait_until(lambda: client.get_balance(sender_addr) == sender_balance) wait_until(lambda: client.get_balance(receiver_addr) == value) self.log.info("Pass 2")
def test(self, num_senders, num_receivers, num_txs): self.log.debug("Initializing {} senders".format(num_senders)) senders = self.init_senders(num_senders) self.log.debug("Initializing {} receivers".format(num_receivers)) receivers = self.init_receivers(num_receivers) self.log.info( "begin to send {} txs to nodes and generate blocks ...".format( num_txs)) txs = self.send_txs_async(senders, receivers, num_txs) # generate blocks to pack txs self.log.info( "continue to generate blocks to pack all transactions ...") client = RpcClient(self.nodes[0]) retry = num_txs for sender in senders: while True: receipt = client.get_receipt(sender.last_tx_hash) if receipt is not None: break assert retry > 0, "some tx not stated yet even after {} retries".format( num_txs) retry -= 1 self.generate_block(num_txs) time.sleep(0.5) self.log.info("sync up blocks among nodes ...") sync_blocks(self.nodes) # check DAG self.log.info("begin to validate DAG for all nodes ...") self.check_with_rpc(client.epoch_number) self.check_with_rpc(client.best_block_hash) self.check_with_rpc(client.gas_price) self.check_with_rpc(client.chain, True) # check receipt self.log.info("begin to validate transaction receipts ...") for idx in range(self.num_nodes): node_client = RpcClient(self.nodes[idx]) for tx_hash in [sent_tx.hash_hex() for sent_tx in txs]: receipt = node_client.get_receipt(tx_hash) assert_equal(receipt is None, False) # check balance and nonce for all accounts self.log.info("begin to validate balance and nonce ...") all_accounts = list(senders) all_accounts.extend(receivers) for account in all_accounts: for idx in range(self.num_nodes): node_client = RpcClient(self.nodes[idx]) assert_equal(node_client.get_balance(account.address), account.balance) assert_equal(node_client.get_nonce(account.address), account.nonce)
def run_test(self): num_blocks = 200 checkpoint_epoch = 100 # Generate checkpoint on node[0] client = RpcClient(self.nodes[0]) genesis_nonce = client.get_nonce(client.GENESIS_ADDR) for _ in range(num_blocks): tx = client.new_tx(nonce=genesis_nonce) tx_hash = client.send_tx(tx) assert tx_hash == tx.hash_hex() genesis_nonce += 1 client.generate_block(100) # Start node[1] as full node to sync checkpoint # Change phase from CatchUpSyncBlockHeader to CatchUpCheckpoint # only when there is at least one connected peer. self.start_node(1, ["--full"], phase_to_wait=None) connect_nodes(self.nodes, 1, 0) # FIXME full node issue that hang at phase CatchUpRecoverBlockFromDbPhase self.nodes[1].wait_for_phase(["CatchUpRecoverBlockFromDbPhase", "NormalSyncPhase"]) sync_blocks(self.nodes) client = RpcClient(self.nodes[1]) # FIXME conflux panics # At epoch 1, block header exists while body not synchronized # print(client.block_by_epoch(client.EPOCH_NUM(1))) # There is no state from epoch 1 to checkpoint_epoch # Note, state of genesis epoch always exists assert client.epoch_number() >= checkpoint_epoch for i in range(1, checkpoint_epoch): try: client.get_balance(client.GENESIS_ADDR, client.EPOCH_NUM(i)) raise AssertionError("should be not state for epoch {}".format(i)) except ReceivedErrorResponseError as e: assert "State for epoch" in e.response.message assert "does not exist" in e.response.message # State should exist at checkpoint client.get_balance(client.GENESIS_ADDR, client.EPOCH_NUM(checkpoint_epoch))
def run_test(self): file_dir = os.path.dirname(os.path.realpath(__file__)) storage_contract = get_contract_instance( abi_file=os.path.join(file_dir, "contracts/simple_storage.abi"), bytecode_file=os.path.join(file_dir, "contracts/simple_storage.dat"), ) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_addr = self.genesis_addr self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr))) block_gen_thread = BlockGenThread(self.nodes, self.log, interval_fixed=1) block_gen_thread.start() client = RpcClient(self.nodes[0]) tx = client.new_tx(value=int(0.625 * CFX) + GDrip, receiver=self.eth_hex_addr, nonce=self.get_nonce(genesis_addr)) client.send_tx(tx, True) assert_equal(client.get_balance(self.eth_hex_addr), int(0.625 * CFX) + GDrip) # deploy contract self.log.info("Deploying contract") tx = self.call_contract_function( contract=storage_contract, name="constructor", args=[], sender_key=self.eth_priv_key, eth_tx=True, ) wait_until(lambda: self.nodes[1].tx_inspect(tx.hash_hex())['exist'], timeout=10) block_gen_thread.stop() client.generate_blocks(40) block_hash = client.generate_custom_block(client.best_block_hash(), [], [tx]) wait_until(lambda: client.best_block_hash() == block_hash, timeout=10) client.generate_blocks(40) BlockGenThread(self.nodes, self.log, interval_fixed=1).start() receipt = self.wait_for_tx([tx])[0] assert_greater_than_or_equal(int(receipt['epochNumber'], 0), 80) self.log.info("All test done")
def run_test(self): client = RpcClient(self.nodes[0]) genesis_address = "0x" + encode_hex( priv_to_addr(default_config['GENESIS_PRI_KEY'])) genesis_balance = default_config["TOTAL_COIN"] client.generate_empty_blocks(ERA_EPOCH_COUNT * 10) print(client.epoch_number("latest_checkpoint")) assert client.epoch_number("latest_checkpoint") > 0 # Just assert we can still get the balance assert_equal(client.get_balance(genesis_address, client.EPOCH_NUM(1)), genesis_balance)
def run_test(self): num_blocks = 200 checkpoint_epoch = 100 # Generate checkpoint on node[0] client = RpcClient(self.nodes[0]) self.genesis_nonce = client.get_nonce(client.GENESIS_ADDR) for _ in range(num_blocks): txs = self._generate_txs(0, random.randint(5, 10)) client.generate_block_with_fake_txs(txs) # Start node[1] as full node to sync checkpoint # Change phase from CatchUpSyncBlockHeader to CatchUpCheckpoint # only when there is at least one connected peer. self.start_node(1, ["--full"], phase_to_wait=None) connect_nodes(self.nodes, 1, 0) # FIXME full node issue that hang at phase CatchUpRecoverBlockFromDbPhase self.nodes[1].wait_for_phase(["NormalSyncPhase"], wait_time=30) sync_blocks(self.nodes, sync_count=False) client = RpcClient(self.nodes[1]) # At epoch 1, block header exists while body not synchronized try: print(client.block_by_epoch(client.EPOCH_NUM(1))) except ReceivedErrorResponseError as e: assert 'Internal error' == e.response.message # There is no state from epoch 1 to checkpoint_epoch # Note, state of genesis epoch always exists assert client.epoch_number() >= checkpoint_epoch # FIXME: we minus REWARD_EPOCH_COUNT here as a workaround. # FIXME: after the state boundary is implemented in consensus, # FIXME: this workaround should be removed. for i in range(1, checkpoint_epoch - 11): try: client.get_balance(client.GENESIS_ADDR, client.EPOCH_NUM(i)) raise AssertionError( "should not have state for epoch {}".format(i)) except ReceivedErrorResponseError as e: assert "State for epoch" in e.response.message assert "does not exist" in e.response.message # State should exist at checkpoint client.get_balance(client.GENESIS_ADDR, client.EPOCH_NUM(checkpoint_epoch)) # There should be states after checkpoint for i in range(checkpoint_epoch, client.epoch_number() - 3): client.get_balance(client.GENESIS_ADDR, client.EPOCH_NUM(i))
def check_account(self, k, balance_map): addr = eth_utils.encode_hex(priv_to_addr(k)) client = RpcClient(self.nodes[0]) try: balance = client.get_balance(addr) staking_balance = client.get_staking_balance(addr) collateral_for_storage = client.get_collateral_for_storage(addr) except Exception as e: self.log.info("Fail to get balance, error=%s", str(e)) return False if balance + staking_balance + collateral_for_storage == balance_map[ k]: return True else: self.log.info("Remote balance:%d, local balance:%d", balance + staking_balance + collateral_for_storage, balance_map[k]) time.sleep(1) return False
def run_test(self): sponsor_whitelist_contract_addr = Web3.toChecksumAddress( "0888000000000000000000000000000000000001") bytes_per_key = 64 collateral_per_byte = 10**18 // 1024 collateral_per_storage_key = 10**18 // 16 # block gas limit (GENESIS_GAS_LIMIT); -1 because below gas is set to upper_bound + 1 upper_bound = default_config["GENESIS_GAS_LIMIT"] - 1 file_dir = os.path.dirname(os.path.realpath(__file__)) control_contract_file_path = os.path.dirname( os.path.realpath(__file__)).split("/") control_contract_file_path.pop(-1) control_contract_file_path.extend( ["internal_contract", "metadata", "SponsorWhitelistControl.json"]) control_contract_file_path = "/".join(control_contract_file_path) control_contract_dict = json.loads( open(os.path.join(control_contract_file_path), "r").read()) control_contract = get_contract_instance( contract_dict=control_contract_dict) test_contract = get_contract_instance( abi_file=os.path.join( file_dir, "contracts/commission_privilege_test_abi.json"), bytecode_file=os.path.join( file_dir, "contracts/commission_privilege_test_bytecode.dat"), ) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_key = self.genesis_priv_key genesis_addr = encode_hex(self.genesis_addr) self.log.info("genesis_addr={}".format(genesis_addr)) nonce = 0 gas_price = 1 gas = CONTRACT_DEFAULT_GAS block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() self.tx_conf = { "from": Web3.toChecksumAddress(genesis_addr), "nonce": int_to_hex(nonce), "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } # Setup balance for node 0 node = self.nodes[0] client = RpcClient(node) (addr1, priv_key1) = client.rand_account() (addr2, priv_key2) = client.rand_account() (addr3, priv_key3) = client.rand_account() (addr4, priv_key4) = client.rand_account() tx = client.new_tx(sender=genesis_addr, priv_key=genesis_key, value=10**18, nonce=self.get_nonce(self.genesis_addr), receiver=addr1) client.send_tx(tx, True) assert_equal(client.get_balance(addr1), 10**18) tx = client.new_tx(sender=genesis_addr, priv_key=genesis_key, value=10**18, nonce=self.get_nonce(self.genesis_addr), receiver=addr2) client.send_tx(tx, True) assert_equal(client.get_balance(addr2), 10**18) tx = client.new_tx(sender=genesis_addr, priv_key=genesis_key, value=3 * 10**18, nonce=self.get_nonce(self.genesis_addr), receiver=addr3) client.send_tx(tx, True) assert_equal(client.get_balance(addr3), 3 * 10**18) # setup contract transaction = self.call_contract_function( contract=test_contract, name="constructor", args=[], sender_key=self.genesis_priv_key, storage_limit=2723) contract_addr = self.wait_for_tx([transaction], True)[0]['contractCreated'] self.log.info("contract_addr={}".format(contract_addr)) assert_equal(client.get_balance(contract_addr), 0) assert_equal(client.get_collateral_for_storage(genesis_addr), 2723 * collateral_per_byte) # sponsor the contract failed due to sponsor_balance < 1000 * upper_bound b0 = client.get_balance(genesis_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound], value=upper_bound * 1000 - 1, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 0) assert_equal(client.get_sponsor_for_gas(contract_addr), "0x0000000000000000000000000000000000000000") assert_equal(client.get_sponsor_gas_bound(contract_addr), 0) assert_equal(client.get_balance(genesis_addr), b0 - gas) # sponsor the contract succeed b0 = client.get_balance(genesis_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound], value=10**18, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18) assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr) assert_equal(client.get_sponsor_gas_bound(contract_addr), upper_bound) assert_equal(client.get_balance(genesis_addr), b0 - 10**18 - charged_of_huge_gas(gas)) check_info = client.check_balance_against_transaction(addr1, contract_addr, gas, gas_price, storage_limit=0) assert_equal(check_info['willPayTxFee'], True) assert_equal(check_info['willPayCollateral'], True) assert_equal(check_info['isBalanceEnough'], True) check_info = client.check_balance_against_transaction(addr4, contract_addr, gas, gas_price, storage_limit=0) assert_equal(check_info['willPayTxFee'], True) assert_equal(check_info['willPayCollateral'], True) assert_equal(check_info['isBalanceEnough'], False) # set privilege for addr4 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="add", args=[Web3.toChecksumAddress(addr4)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True, storage_limit=64) assert_equal( client.get_balance(genesis_addr), b0 - charged_of_huge_gas(gas) - collateral_per_storage_key) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + collateral_per_storage_key) check_info = client.check_balance_against_transaction(addr4, contract_addr, gas, gas_price, storage_limit=0) assert_equal(check_info['willPayTxFee'], False) assert_equal(check_info['willPayCollateral'], True) assert_equal(check_info['isBalanceEnough'], True) # remove privilege for addr4 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="remove", args=[Web3.toChecksumAddress(addr4)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 - collateral_per_storage_key) assert_equal( client.get_balance(genesis_addr), b0 - charged_of_huge_gas(gas) + collateral_per_storage_key) # set privilege for addr1 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="add", args=[Web3.toChecksumAddress(addr1)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True, storage_limit=64) assert_equal( client.get_balance(genesis_addr), b0 - charged_of_huge_gas(gas) - collateral_per_storage_key) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + collateral_per_storage_key) # addr1 call contract with privilege sb = client.get_sponsor_balance_for_gas(contract_addr) b1 = client.get_balance(addr1) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_balance(addr1), b1) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb - charged_of_huge_gas(gas)) # addr1 call contract with privilege and large tx fee b1 = client.get_balance(addr1) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, wait=True, check_status=True, gas=upper_bound + 1) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_balance(addr1), b1 - charged_of_huge_gas(upper_bound + 1)) # addr2 call contract without privilege b2 = client.get_balance(addr2) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key2, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_balance(addr2), b2 - charged_of_huge_gas(gas)) # set privilege for addr2 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="add", args=[Web3.toChecksumAddress(addr2)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True, storage_limit=64) assert_equal( client.get_balance(genesis_addr), b0 - charged_of_huge_gas(gas) - collateral_per_storage_key) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + collateral_per_storage_key) # now, addr2 call contract with privilege sb = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key2, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb - charged_of_huge_gas(gas)) assert_equal(client.get_balance(addr2), b2) # remove privilege for addr1 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="remove", args=[Web3.toChecksumAddress(addr1)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 - collateral_per_storage_key) assert_equal( client.get_balance(genesis_addr), b0 - charged_of_huge_gas(gas) + collateral_per_storage_key) # addr1 call contract without privilege sb = client.get_sponsor_balance_for_gas(contract_addr) b1 = client.get_balance(addr1) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_balance(addr1), b1 - charged_of_huge_gas(gas)) # new sponsor failed due to small sponsor_balance b3 = client.get_balance(addr3) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound + 1], value=5 * 10**17, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr) assert_equal(client.get_balance(addr3), b3 - gas) # new sponsor failed due to small upper bound b3 = client.get_balance(addr3) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound], value=10**18, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr) assert_equal(client.get_balance(addr3), b3 - gas) # new sponsor succeed b0 = client.get_balance(genesis_addr) b3 = client.get_balance(addr3) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound + 1], value=10**18, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18) assert_equal(client.get_sponsor_gas_bound(contract_addr), upper_bound + 1) assert_equal(client.get_sponsor_for_gas(contract_addr), addr3) assert_equal(client.get_balance(addr3), b3 - 10**18 - charged_of_huge_gas(gas)) assert_equal(client.get_balance(genesis_addr), b0 + sb) # sponsor the contract for collateral failed due to zero sponsor balance b3 = client.get_balance(addr3) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=0, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), 0) assert_equal(client.get_sponsor_for_collateral(contract_addr), "0x0000000000000000000000000000000000000000") assert_equal(client.get_balance(addr3), b3 - gas) # sponsor the contract for collateral succeed b3 = client.get_balance(addr3) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=10**18 - 1, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), 10**18 - 1) assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3) assert_equal(client.get_balance(addr3), b3 - charged_of_huge_gas(gas) - 10**18 + 1) check_info = client.check_balance_against_transaction(addr1, contract_addr, gas, gas_price, storage_limit=0) assert_equal(check_info['willPayTxFee'], True) assert_equal(check_info['willPayCollateral'], True) assert_equal(check_info['isBalanceEnough'], True) # addr1 create 2 keys without privilege, and storage limit is 1, should failed b1 = client.get_balance(addr1) assert_equal(client.get_collateral_for_storage(contract_addr), 0) assert_equal(client.get_collateral_for_storage(addr1), 0) self.call_contract_function(contract=test_contract, name="par_add", args=[0, 2], sender_key=priv_key1, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key) assert_equal(client.get_collateral_for_storage(contract_addr), 0) assert_equal(client.get_collateral_for_storage(addr1), 0) assert_equal(client.get_balance(addr1), b1 - gas) # addr1 create 2 keys without privilege, and storage limit is 2, should succeed b1 = client.get_balance(addr1) self.call_contract_function(contract=test_contract, name="par_add", args=[0, 2], sender_key=priv_key1, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 2) assert_equal(client.get_collateral_for_storage(contract_addr), 0) assert_equal(client.get_collateral_for_storage(addr1), collateral_per_storage_key * 2) assert_equal( client.get_balance(addr1), b1 - charged_of_huge_gas(gas) - collateral_per_storage_key * 2) # remove 1 key create by addr1 b1 = client.get_balance(addr1) self.call_contract_function(contract=test_contract, name="par_del", args=[0, 1], sender_key=priv_key1, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 2) assert_equal(client.get_collateral_for_storage(contract_addr), 0) assert_equal(client.get_collateral_for_storage(addr1), collateral_per_storage_key) assert_equal( client.get_balance(addr1), b1 - charged_of_huge_gas(gas) + collateral_per_storage_key) check_info = client.check_balance_against_transaction( addr2, contract_addr, gas, gas_price, storage_limit=bytes_per_key) assert_equal(check_info['willPayTxFee'], False) assert_equal(check_info['willPayCollateral'], False) assert_equal(check_info['isBalanceEnough'], True) check_info = client.check_balance_against_transaction( addr2, contract_addr, gas, gas_price, storage_limit=10**18) assert_equal(check_info['willPayTxFee'], False) assert_equal(check_info['willPayCollateral'], True) assert_equal(check_info['isBalanceEnough'], True) # addr2 create 2 keys with privilege, and storage limit is 1, should succeed sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_add", args=[2, 4], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 2) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc - collateral_per_storage_key * 2) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - charged_of_huge_gas(gas)) assert_equal(client.get_collateral_for_storage(addr2), 0) assert_equal(client.get_balance(addr2), b2) # addr2 create 13 keys with privilege, and storage limit is 0, should succeed sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_add", args=[4, 17], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=0) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 15) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc - collateral_per_storage_key * 13) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - charged_of_huge_gas(gas)) assert_equal(client.get_collateral_for_storage(addr2), 0) assert_equal(client.get_balance(addr2), b2) # now sponsor_balance is unable to pay collateral for storage # the balance of addr2 is able to pay 15 collateral for storage, but not 16 assert_greater_than( collateral_per_storage_key, client.get_sponsor_balance_for_collateral(contract_addr)) assert_greater_than(collateral_per_storage_key * 16, client.get_balance(addr2)) assert_greater_than(client.get_balance(addr2), collateral_per_storage_key * 15) # addr2 create 1 keys with privilege, and storage limit is 0, should failed sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_add", args=[17, 18], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=0) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 15) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - gas) assert_equal(client.get_collateral_for_storage(addr2), 0) assert_equal(client.get_balance(addr2), b2) # addr2 create 1 keys with privilege, and storage limit is 2, should succeed sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_add", args=[17, 18], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 2) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 15) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - charged_of_huge_gas(gas)) assert_equal(client.get_collateral_for_storage(addr2), collateral_per_storage_key) assert_equal(client.get_balance(addr2), b2 - collateral_per_storage_key) # addr2 del 10 keys with privilege sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_del", args=[2, 12], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 5) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc + collateral_per_storage_key * 10) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - charged_of_huge_gas(gas)) assert_equal(client.get_collateral_for_storage(addr2), collateral_per_storage_key) assert_equal(client.get_balance(addr2), b2) # addr3 sponsor more, treat as transfer b3 = client.get_balance(addr3) sb = client.get_sponsor_balance_for_collateral(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=sb, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sb * 2) assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3) assert_equal(client.get_balance(addr3), b3 - charged_of_huge_gas(gas) - sb) # genesis sponsor with sponsor balance, should failed b0 = client.get_balance(genesis_addr) sb = client.get_sponsor_balance_for_collateral(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=sb + 1, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sb) assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3) assert_equal(client.get_balance(genesis_addr), b0 - gas) # genesis sponsor with sponsor balance and collateral_for_storage, should succeed b0 = client.get_balance(genesis_addr) b3 = client.get_balance(addr3) cfs = client.get_collateral_for_storage(contract_addr) sb = client.get_sponsor_balance_for_collateral(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=sb + cfs + 1, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_collateral_for_storage(contract_addr), cfs) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sb + 1) assert_equal(client.get_sponsor_for_collateral(contract_addr), genesis_addr) assert_equal(client.get_balance(genesis_addr), b0 - charged_of_huge_gas(gas) - sb - cfs - 1) assert_equal(client.get_balance(addr3), b3 + sb + cfs) # storage change test c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="par", args=[10, 20, 30, 41], sender_key=self.genesis_priv_key, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 30) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + 11 * collateral_per_storage_key) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="par_add_del", args=[110, 120, 110, 120], sender_key=self.genesis_priv_key, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 30) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + 10 * collateral_per_storage_key) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="par_add_del", args=[210, 220, 215, 220], sender_key=self.genesis_priv_key, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 30) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + 5 * collateral_per_storage_key) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="par_add_del", args=[310, 320, 320, 330], sender_key=self.genesis_priv_key, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 30) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + 10 * collateral_per_storage_key) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="par_add_del", args=[410, 420, 409, 430], sender_key=self.genesis_priv_key, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 300) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + 21 * collateral_per_storage_key) # test recurrence c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="rec", args=[510, 520, 3], sender_key=self.genesis_priv_key, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 30) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + 4 * collateral_per_storage_key) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="par_del", args=[510, 520], sender_key=self.genesis_priv_key, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 30) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 - 4 * collateral_per_storage_key) self.log.info("Pass")
def run_test(self): file_dir = os.path.dirname(os.path.realpath(__file__)) test_contract = get_contract_instance( abi_file =os.path.join(file_dir, "contracts/issue988_abi.json"), bytecode_file=os.path.join(file_dir, "contracts/issue988_bytecode.dat"), ) start_p2p_connection(self.nodes) genesis_key = self.genesis_priv_key genesis_addr = self.genesis_addr self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr))) nonce = 0 gas_price = 1 gas = CONTRACT_DEFAULT_GAS block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() self.tx_conf = {"from":Web3.toChecksumAddress(encode_hex_0x(genesis_addr)), "nonce":int_to_hex(nonce), "gas":int_to_hex(gas), "gasPrice":int_to_hex(gas_price), "chainId":0} # setup balance for node 0 node = self.nodes[0] client = RpcClient(node) (addr, priv_key) = client.rand_account() self.log.info("addr=%s priv_key=%s", addr, priv_key) tx = client.new_tx(value=20 * 10 ** 18, receiver=addr, nonce=self.get_nonce(genesis_addr)) client.send_tx(tx, True) assert_equal(client.get_balance(addr), 20000000000000000000) # deploy test contract c0 = client.get_collateral_for_storage(addr) # code collateral + key value storage_limit = 512 * 11 + 64 tx = self.call_contract_function( contract=test_contract, name="constructor", args=[], sender_key=priv_key, storage_limit=storage_limit) contract_addr = self.wait_for_tx([tx], True)[0]['contractCreated'] c1 = client.get_collateral_for_storage(addr) assert_equal(c1 - c0, storage_limit * COLLATERAL_UNIT_IN_DRIP) self.log.info("contract_addr={}".format(contract_addr)) assert_equal(client.get_balance(contract_addr), 0) raw_result = self.call_contract_function_rpc( contract=test_contract, name="ktrriiwhlx", args=[], contract_addr=contract_addr) result = signed_bytes_to_int256(decode_hex(raw_result)) assert_equal(result, -12076) raw_result = self.call_contract_function_rpc( contract=test_contract, name="qiwmzrxuhd", args=[], contract_addr=contract_addr) result = signed_bytes_to_int256(decode_hex(raw_result)) assert_equal(result, -2) raw_result = self.call_contract_function_rpc( contract=test_contract, name="wxqpwecckl", args=[], contract_addr=contract_addr) result = signed_bytes_to_int256(decode_hex(raw_result)) assert_equal(result, -1) self.log.info("Pass")
def run_test(self): sponsor_whitelist_contract_addr = Web3.toChecksumAddress( "8ad036480160591706c831f0da19d1a424e39469") bytes_per_key = 64 collateral_per_storage_key = 10**18 // 16 upper_bound = 5 * 10**7 file_dir = os.path.dirname(os.path.realpath(__file__)) control_contract_file_path = os.path.dirname( os.path.realpath(__file__)).split("/") control_contract_file_path.pop(-1) control_contract_file_path.extend( ["internal_contract", "metadata", "SponsorWhitelistControl.json"]) control_contract_file_path = "/".join(control_contract_file_path) control_contract_dict = json.loads( open(os.path.join(control_contract_file_path), "r").read()) control_contract = get_contract_instance( contract_dict=control_contract_dict) test_contract = get_contract_instance( abi_file=os.path.join( file_dir, "contracts/commission_privilege_test_abi.json"), bytecode_file=os.path.join( file_dir, "contracts/commission_privilege_test_bytecode.dat"), ) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_key = self.genesis_priv_key genesis_addr = encode_hex(self.genesis_addr) self.log.info("genesis_addr={}".format(genesis_addr)) nonce = 0 gas_price = 1 gas = 50000000 block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() self.tx_conf = { "from": Web3.toChecksumAddress(genesis_addr), "nonce": int_to_hex(nonce), "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } # Setup balance for node 0 node = self.nodes[0] client = RpcClient(node) (addr1, priv_key1) = client.rand_account() (addr2, priv_key2) = client.rand_account() (addr3, priv_key3) = client.rand_account() tx = client.new_tx(sender=genesis_addr, priv_key=genesis_key, value=10**18, nonce=self.get_nonce(self.genesis_addr), receiver=addr1) client.send_tx(tx, True) assert_equal(client.get_balance(addr1), 10**18) tx = client.new_tx(sender=genesis_addr, priv_key=genesis_key, value=10**18, nonce=self.get_nonce(self.genesis_addr), receiver=addr2) client.send_tx(tx, True) assert_equal(client.get_balance(addr2), 10**18) tx = client.new_tx(sender=genesis_addr, priv_key=genesis_key, value=3 * 10**18, nonce=self.get_nonce(self.genesis_addr), receiver=addr3) client.send_tx(tx, True) assert_equal(client.get_balance(addr3), 3 * 10**18) # setup contract transaction = self.call_contract_function( contract=test_contract, name="constructor", args=[], sender_key=self.genesis_priv_key) contract_addr = self.wait_for_tx([transaction], True)[0]['contractCreated'] self.log.info("contract_addr={}".format(contract_addr)) assert_equal(client.get_balance(contract_addr), 0) # sponsor the contract failed due to sponsor_balance < 1000 * upper_bound b0 = client.get_balance(genesis_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound], value=upper_bound * 1000 - 1, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 0) assert_equal(client.get_sponsor_for_gas(contract_addr), "0x0000000000000000000000000000000000000000") assert_equal(client.get_sponsor_gas_bound(contract_addr), 0) assert_equal(client.get_balance(genesis_addr), b0 - gas) # sponsor the contract succeed b0 = client.get_balance(genesis_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound], value=10**18, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18) assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr) assert_equal(client.get_sponsor_gas_bound(contract_addr), upper_bound) assert_equal(client.get_balance(genesis_addr), b0 - 10**18 - gas + 12500000) # set privilege for addr1 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="add", args=[Web3.toChecksumAddress(addr1)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_balance(genesis_addr), b0 - gas + 12500000 - collateral_per_storage_key) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + collateral_per_storage_key) # addr1 call contract with privilege sb = client.get_sponsor_balance_for_gas(contract_addr) b1 = client.get_balance(addr1) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_balance(addr1), b1) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb - gas + 12500000) # addr1 call contract with privilege and large tx fee b1 = client.get_balance(addr1) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, wait=True, check_status=True, gas=upper_bound + 1) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_balance(addr1), b1 - upper_bound + upper_bound // 4 - 1) # addr2 call contract without privilege b2 = client.get_balance(addr2) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key2, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_balance(addr2), b2 - gas + 12500000) # set privilege for addr2 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="add", args=[Web3.toChecksumAddress(addr2)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_balance(genesis_addr), b0 - gas + 12500000 - collateral_per_storage_key) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + collateral_per_storage_key) # now, addr2 call contract with privilege sb = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key2, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb - gas + 12500000) assert_equal(client.get_balance(addr2), b2) # remove privilege for addr1 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="remove", args=[Web3.toChecksumAddress(addr1)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 - collateral_per_storage_key) assert_equal(client.get_balance(genesis_addr), b0 - gas + 12500000 + collateral_per_storage_key) # addr1 call contract without privilege sb = client.get_sponsor_balance_for_gas(contract_addr) b1 = client.get_balance(addr1) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_balance(addr1), b1 - gas + 12500000) # new sponsor failed due to small sponsor_balance b3 = client.get_balance(addr3) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound + 1], value=5 * 10**17, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr) assert_equal(client.get_balance(addr3), b3 - gas) # new sponsor failed due to small upper bound b3 = client.get_balance(addr3) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound], value=10**18, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb) assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr) assert_equal(client.get_balance(addr3), b3 - gas) # new sponsor succeed b0 = client.get_balance(genesis_addr) b3 = client.get_balance(addr3) sb = client.get_sponsor_balance_for_gas(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound + 1], value=10**18, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18) assert_equal(client.get_sponsor_gas_bound(contract_addr), upper_bound + 1) assert_equal(client.get_sponsor_for_gas(contract_addr), addr3) assert_equal(client.get_balance(addr3), b3 - 10**18 - gas + 12500000) assert_equal(client.get_balance(genesis_addr), b0 + sb) # sponsor the contract for collateral failed due to zero sponsor balance b3 = client.get_balance(addr3) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=0, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), 0) assert_equal(client.get_sponsor_for_collateral(contract_addr), "0x0000000000000000000000000000000000000000") assert_equal(client.get_balance(addr3), b3 - gas) # sponsor the contract for collateral succeed b3 = client.get_balance(addr3) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=10**18 - 1, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), 10**18 - 1) assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3) assert_equal(client.get_balance(addr3), b3 - gas + 12500000 - 10**18 + 1) # addr1 create 2 keys without privilege, and storage limit is 1, should failed b1 = client.get_balance(addr1) assert_equal(client.get_collateral_for_storage(contract_addr), 0) assert_equal(client.get_collateral_for_storage(addr1), 0) self.call_contract_function(contract=test_contract, name="par_add", args=[0, 2], sender_key=priv_key1, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key) assert_equal(client.get_collateral_for_storage(contract_addr), 0) assert_equal(client.get_collateral_for_storage(addr1), 0) assert_equal(client.get_balance(addr1), b1 - gas) # addr1 create 2 keys without privilege, and storage limit is 2, should succeed b1 = client.get_balance(addr1) self.call_contract_function(contract=test_contract, name="par_add", args=[0, 2], sender_key=priv_key1, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 2) assert_equal(client.get_collateral_for_storage(contract_addr), 0) assert_equal(client.get_collateral_for_storage(addr1), collateral_per_storage_key * 2) assert_equal(client.get_balance(addr1), b1 - gas + 12500000 - collateral_per_storage_key * 2) # remove 1 key create by addr1 b1 = client.get_balance(addr1) self.call_contract_function(contract=test_contract, name="par_del", args=[0, 1], sender_key=priv_key1, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 2) assert_equal(client.get_collateral_for_storage(contract_addr), 0) assert_equal(client.get_collateral_for_storage(addr1), collateral_per_storage_key) assert_equal(client.get_balance(addr1), b1 - gas + 12500000 + collateral_per_storage_key) # addr2 create 2 keys with privilege, and storage limit is 1, should succeed sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_add", args=[2, 4], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 2) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc - collateral_per_storage_key * 2) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - gas + 12500000) assert_equal(client.get_collateral_for_storage(addr2), 0) assert_equal(client.get_balance(addr2), b2) # addr2 create 13 keys with privilege, and storage limit is 0, should succeed sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_add", args=[4, 17], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=0) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 15) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc - collateral_per_storage_key * 13) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - gas + 12500000) assert_equal(client.get_collateral_for_storage(addr2), 0) assert_equal(client.get_balance(addr2), b2) # now sponsor_balance is unable to pay collateral for storage # the balance of addr2 is able to pay 15 collateral for storage, but not 16 assert_greater_than( collateral_per_storage_key, client.get_sponsor_balance_for_collateral(contract_addr)) assert_greater_than(collateral_per_storage_key * 16, client.get_balance(addr2)) assert_greater_than(client.get_balance(addr2), collateral_per_storage_key * 15) # addr2 create 1 keys with privilege, and storage limit is 0, should failed sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_add", args=[17, 18], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=0) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 15) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - gas) assert_equal(client.get_collateral_for_storage(addr2), 0) assert_equal(client.get_balance(addr2), b2) # addr2 create 1 keys with privilege, and storage limit is 2, should succeed sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_add", args=[17, 18], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key * 2) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 15) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - gas + 12500000) assert_equal(client.get_collateral_for_storage(addr2), collateral_per_storage_key) assert_equal(client.get_balance(addr2), b2 - collateral_per_storage_key) # addr2 del 10 keys with privilege sbc = client.get_sponsor_balance_for_collateral(contract_addr) sbg = client.get_sponsor_balance_for_gas(contract_addr) b2 = client.get_balance(addr2) self.call_contract_function(contract=test_contract, name="par_del", args=[2, 12], sender_key=priv_key2, contract_addr=contract_addr, wait=True, storage_limit=bytes_per_key) assert_equal(client.get_collateral_for_storage(contract_addr), collateral_per_storage_key * 5) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sbc + collateral_per_storage_key * 10) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sbg - gas + 12500000) assert_equal(client.get_collateral_for_storage(addr2), collateral_per_storage_key) assert_equal(client.get_balance(addr2), b2) # addr3 sponsor more, treat as transfer b3 = client.get_balance(addr3) sb = client.get_sponsor_balance_for_collateral(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=sb, sender_key=priv_key3, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sb * 2) assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3) assert_equal(client.get_balance(addr3), b3 - gas + 12500000 - sb) # genesis sponsor with sponsor balance, should failed b0 = client.get_balance(genesis_addr) sb = client.get_sponsor_balance_for_collateral(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=sb + 1, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sb) assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3) assert_equal(client.get_balance(genesis_addr), b0 - gas) # genesis sponsor with sponsor balance and collateral_for_storage, should succeed b0 = client.get_balance(genesis_addr) b3 = client.get_balance(addr3) cfs = client.get_collateral_for_storage(contract_addr) sb = client.get_sponsor_balance_for_collateral(contract_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_collateral", args=[Web3.toChecksumAddress(contract_addr)], value=sb + cfs + 1, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_collateral_for_storage(contract_addr), cfs) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), sb + cfs + 1) assert_equal(client.get_sponsor_for_collateral(contract_addr), genesis_addr) assert_equal(client.get_balance(genesis_addr), b0 - gas + 12500000 - sb - cfs - 1) assert_equal(client.get_balance(addr3), b3 + sb + cfs) self.log.info("Pass")
def run_test(self): sponsor_whitelist_contract_addr = Web3.toChecksumAddress( "0888000000000000000000000000000000000001") collateral_per_storage_key = COLLATERAL_UNIT_IN_DRIP * 64 upper_bound = 5 * 10**7 file_dir = os.path.dirname(os.path.realpath(__file__)) control_contract_file_path = os.path.join( file_dir, "..", "internal_contract", "metadata", "SponsorWhitelistControl.json") control_contract_dict = json.loads( open(control_contract_file_path, "r").read()) control_contract = get_contract_instance( contract_dict=control_contract_dict) test_contract = get_contract_instance( abi_file=os.path.join( file_dir, "contracts/commission_privilege_test_abi.json"), bytecode_file=os.path.join( file_dir, "contracts/commission_privilege_test_bytecode.dat"), ) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_key = self.genesis_priv_key genesis_addr = encode_hex_0x(self.genesis_addr) self.log.info("genesis_addr={}".format(genesis_addr)) nonce = 0 gas_price = 1 gas = CONTRACT_DEFAULT_GAS block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() self.tx_conf = { "from": Web3.toChecksumAddress(genesis_addr), "nonce": int_to_hex(nonce), "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } # Setup balance for node 0 node = self.nodes[0] client = RpcClient(node) (addr1, priv_key1) = client.rand_account() self.log.info("addr1={}".format(addr1)) tx = client.new_tx(sender=genesis_addr, priv_key=genesis_key, value=10**6, nonce=self.get_nonce(self.genesis_addr), receiver=addr1) client.send_tx(tx, True) assert_equal(client.get_balance(addr1), 10**6) # setup contract transaction = self.call_contract_function( contract=test_contract, name="constructor", args=[], sender_key=self.genesis_priv_key, storage_limit=20000) contract_addr = self.wait_for_tx([transaction], True)[0]['contractCreated'] self.log.info("contract_addr={}".format(contract_addr)) assert_equal(client.get_balance(contract_addr), 0) # sponsor the contract succeed b0 = client.get_balance(genesis_addr) self.call_contract_function( contract=control_contract, name="setSponsorForGas", args=[Web3.toChecksumAddress(contract_addr), upper_bound], value=10**18, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18) assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr) assert_equal(client.get_sponsor_gas_bound(contract_addr), upper_bound) assert_equal(client.get_balance(genesis_addr), b0 - 10**18 - charged_of_huge_gas(gas)) # set privilege for addr1 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) transaction = self.call_contract_function( contract=test_contract, name="add", args=[Web3.toChecksumAddress(addr1)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True, storage_limit=64) assert_equal( client.get_balance(genesis_addr), b0 - charged_of_huge_gas(gas) - collateral_per_storage_key) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + collateral_per_storage_key) assert_equal( self.wait_for_tx([transaction], True)[0]['gasCoveredBySponsor'], False) # addr1 call contract with privilege without enough cfx for gas fee sb = client.get_sponsor_balance_for_gas(contract_addr) b1 = client.get_balance(addr1) transaction = self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_balance(addr1), b1) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb - charged_of_huge_gas(gas)) assert_equal( self.wait_for_tx([transaction], True)[0]['gasCoveredBySponsor'], True) # sponsor collateral for the contract succeed b0 = client.get_balance(genesis_addr) self.call_contract_function( contract=control_contract, name="setSponsorForCollateral", args=[Web3.toChecksumAddress(contract_addr)], value=10**18, # 1 CFX = 1KB sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_collateral(contract_addr), 10**18) assert_equal(client.get_sponsor_for_collateral(contract_addr), genesis_addr) assert_equal(client.get_balance(genesis_addr), b0 - 10**18 - charged_of_huge_gas(gas)) # addr1 call contract with privilege without enough cfx for storage sb = client.get_sponsor_balance_for_gas(contract_addr) b1 = client.get_balance(addr1) transaction = self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, wait=True, check_status=True, storage_limit=1024) assert_equal(client.get_balance(addr1), b1) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb - charged_of_huge_gas(gas)) assert_equal( self.wait_for_tx([transaction], True)[0]['storageCoveredBySponsor'], True) # addr1 call with larger storage limit, should not packed transaction = self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, storage_limit=1025) for _ in range(10): client.generate_block() tx_info = self.nodes[0].txpool_txWithPoolInfo(transaction.hash_hex()) assert_equal(int(tx_info['local_nonce'], 16), 2) assert_equal(tx_info['local_balance_enough'], False) assert_equal(tx_info['packed'], False) # send 1025 * 10 ** 18 // 1024 CFX to addr1 tx = client.new_tx(sender=genesis_addr, priv_key=genesis_key, value=1025 * 10**18 // 1024, nonce=self.get_nonce(self.genesis_addr), receiver=addr1) client.send_tx(tx, True) assert_equal(client.get_balance(addr1), 10**6 + 1025 * 10**18 // 1024) for _ in range(10): client.generate_block() tx_info = self.nodes[0].txpool_txWithPoolInfo(transaction.hash_hex()) # Now addr1 pays for storage collateral by itself. assert_equal( self.wait_for_tx([transaction], True)[0]['storageCoveredBySponsor'], False) assert_equal(int(tx_info['local_nonce'], 16), 3) assert_equal(tx_info['packed'], True) self.log.info("Pass")
def run_test(self): file_dir = os.path.dirname(os.path.realpath(__file__)) pay_contract = get_contract_instance( abi_file=os.path.join(file_dir, "contracts/pay_abi.json"), bytecode_file=os.path.join(file_dir, "contracts/pay_bytecode.dat"), ) admin_control_contract = get_contract_instance( abi_file=os.path.join(file_dir, "contracts/admin_control_abi.json"), bytecode_file=os.path.join(file_dir, "contracts/admin_control_bytecode.dat"), ) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_key = self.genesis_priv_key genesis_addr = self.genesis_addr self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr))) nonce = 0 gas_price = 1 gas = 50000000 block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() self.tx_conf = {"from":Web3.toChecksumAddress(encode_hex_0x(genesis_addr)), "nonce":int_to_hex(nonce), "gas":int_to_hex(gas), "gasPrice":int_to_hex(gas_price), "chainId":0} # Setup balance for node 0 node = self.nodes[0] client = RpcClient(node) (addr, priv_key) = client.rand_account() self.log.info("addr=%s priv_key=%s", addr, priv_key) tx = client.new_tx(value=5 * 10 ** 18, receiver=addr, nonce=self.get_nonce(genesis_addr)) client.send_tx(tx, True) assert_equal(client.get_balance(addr), 5000000000000000000) (addr2, priv_key2) = client.rand_account() self.log.info("addr2=%s priv_key2=%s", addr2, priv_key2) tx = client.new_tx(value=5 * 10 ** 18, receiver=addr2, nonce=self.get_nonce(genesis_addr)) client.send_tx(tx, True) assert_equal(client.get_balance(addr2), 5000000000000000000) # deploy pay contract tx = self.call_contract_function( contract=pay_contract, name="constructor", args=[], sender_key=priv_key) contract_addr = self.wait_for_tx([tx], True)[0]['contractCreated'] self.log.info("contract_addr={}".format(contract_addr)) assert_equal(client.get_balance(contract_addr), 0) # deposit 10**18 b0 = int(node.cfx_getBalance(addr), 16) tx = self.call_contract_function( contract=pay_contract, name="recharge", args=[], sender_key=priv_key, contract_addr=contract_addr, value=10 ** 18, wait=True, check_status=True) assert_equal(client.get_balance(contract_addr), 10 ** 18) assert_equal(client.get_balance(addr), b0 - 10 ** 18 - gas + gas // 4) assert_equal(client.get_admin(contract_addr), addr) # transfer admin (fail) tx = self.call_contract_function( contract=admin_control_contract, name="set_admin", args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)], sender_key=priv_key2, contract_addr=Web3.toChecksumAddress("0x6060de9e1568e69811c4a398f92c3d10949dc891"), wait=True, check_status=True) assert_equal(client.get_admin(contract_addr), addr) # transfer admin (success) tx = self.call_contract_function( contract=admin_control_contract, name="set_admin", args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)], sender_key=priv_key, contract_addr=Web3.toChecksumAddress("0x6060de9e1568e69811c4a398f92c3d10949dc891"), wait=True, check_status=True) assert_equal(client.get_admin(contract_addr), addr2) # destroy tx = self.call_contract_function( contract=admin_control_contract, name="destroy", args=[Web3.toChecksumAddress(contract_addr)], sender_key=priv_key2, contract_addr=Web3.toChecksumAddress("0x6060de9e1568e69811c4a398f92c3d10949dc891"), wait=True, check_status=True) assert_equal(client.get_balance(contract_addr), 0) assert_equal(client.get_balance(addr2), 5999999999912500000 + gas // 4) self.log.info("Pass")
class MessageTest(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 0 self.conf_parameters = {"log_level":"\"error\""} def setup_network(self): self.setup_nodes() def run_test(self): # Start mininode connection default_node = DefaultNode() self.node = default_node kwargs = {} args = {} kwargs['dstport'] = 32323 kwargs['dstaddr'] = '127.0.0.1' default_node.peer_connect(*args, **kwargs) network_thread_start() default_node.wait_for_status() # Start rpc connection self.rpc_client = RpcClient(get_simple_rpc_proxy( "http://127.0.0.1:12537")) node_id = self.rpc_client.get_node_id() self.log.info("get nodeid %s", eth_utils.encode_hex(node_id)) block_gen_thread = BlockGenThread([self.rpc_client.node], self.log, num_txs = 100, interval_fixed=0.2) block_gen_thread.start() genesis_key = default_config["GENESIS_PRI_KEY"] balance_map = {genesis_key: default_config["TOTAL_COIN"]} self.log.info("Initial State: (sk:%d, addr:%s, balance:%d)", bytes_to_int(genesis_key), eth_utils.encode_hex(priv_to_addr(genesis_key)), balance_map[genesis_key]) nonce_map = {genesis_key: 0} '''Test Random Transactions''' all_txs = [] tx_n = 10000 gas_price = 1 self.log.info("start to generate %d transactions with about %d seconds", tx_n, tx_n/10/2) for i in range(tx_n): if i % 1000 == 0: self.log.info("generated %d tx", i) sender_key = random.choice(list(balance_map)) nonce = nonce_map[sender_key] if random.random() < 0.1 and balance_map[sender_key] > 21000 * 4 * tx_n: value = int(balance_map[sender_key] * 0.5) receiver_sk, _ = ec_random_keys() nonce_map[receiver_sk] = 0 balance_map[receiver_sk] = value else: value = 1 receiver_sk = random.choice(list(balance_map)) balance_map[receiver_sk] += value # not enough transaction fee (gas_price * gas_limit) should not happen for now assert balance_map[sender_key] >= value + gas_price * 21000 tx = create_transaction(pri_key=sender_key, receiver=priv_to_addr(receiver_sk), value=value, nonce=nonce, gas_price=gas_price) all_txs.append(tx) nonce_map[sender_key] = nonce + 1 balance_map[sender_key] -= value + gas_price * 21000 i = 0 for tx in all_txs: i += 1 if i % 1000 == 0: self.log.info("Sent %d tx", i) self.node.send_protocol_msg(Transactions(transactions=[tx])) for k in balance_map: wait_until(lambda: self.check_account(k, balance_map)) block_gen_thread.stop() block_gen_thread.join() self.log.info("Pass") while True: pass def send_msg(self, msg): self.node.send_protocol_msg(msg) def check_account(self, k, balance_map): addr = eth_utils.encode_hex(priv_to_addr(k)) try: balance = self.rpc_client.get_balance(addr) except Exception as e: self.log.info("Fail to get balance, error=%s", str(e)) return False if balance == balance_map[k]: return True else: self.log.info("Remote balance:%d, local balance:%d", balance, balance_map[k]) time.sleep(1) return False
def run_test(self): num_blocks = 200 snapshot_epoch = 150 # Generate checkpoint on node[0] archive_node_client = RpcClient(self.nodes[0]) self.genesis_nonce = archive_node_client.get_nonce( archive_node_client.GENESIS_ADDR) blocks_in_era = [] for i in range(num_blocks): txs = self._generate_txs(0, random.randint(50, 100)) block_hash = archive_node_client.generate_block_with_fake_txs(txs) if i >= snapshot_epoch: blocks_in_era.append(block_hash) sync_blocks(self.nodes[:-1]) self.log.info("All archive nodes synced") # Start node[full_node_index] as full node to sync checkpoint # Change phase from CatchUpSyncBlockHeader to CatchUpCheckpoint # only when there is at least one connected peer. full_node_index = self.num_nodes - 1 self.start_node(full_node_index, ["--full"], phase_to_wait=None) for i in range(self.num_nodes - 1): connect_nodes(self.nodes, full_node_index, i) self.log.info("Wait for full node to sync, index=%d", full_node_index) self.nodes[full_node_index].wait_for_phase(["NormalSyncPhase"], wait_time=240) sync_blocks(self.nodes, sync_count=False) full_node_client = RpcClient(self.nodes[full_node_index]) # At epoch 1, block header exists while body not synchronized try: print( full_node_client.block_by_epoch(full_node_client.EPOCH_NUM(1))) except ReceivedErrorResponseError as e: assert 'Internal error' == e.response.message # There is no state from epoch 1 to snapshot_epoch # Note, state of genesis epoch always exists assert full_node_client.epoch_number() >= snapshot_epoch wait_until( lambda: full_node_client.epoch_number() == archive_node_client. epoch_number() and full_node_client.epoch_number("latest_state") == archive_node_client.epoch_number("latest_state")) # We have snapshot_epoch for state execution but # don't offer snapshot_epoch for Rpc clients. for i in range(1, snapshot_epoch + 1): try: full_node_client.get_balance(full_node_client.GENESIS_ADDR, full_node_client.EPOCH_NUM(i)) raise AssertionError( "should not have state for epoch {}".format(i)) except ReceivedErrorResponseError as e: assert "State for epoch" in e.response.message assert "does not exist" in e.response.message # Wait for execution to complete. time.sleep(1) # There should be states after checkpoint for i in range(snapshot_epoch + 1, full_node_client.epoch_number() - 3): full_balance = full_node_client.get_balance( full_node_client.GENESIS_ADDR, full_node_client.EPOCH_NUM(i)) archive_balance = archive_node_client.get_balance( archive_node_client.GENESIS_ADDR, archive_node_client.EPOCH_NUM(i)) assert_equal(full_balance, archive_balance) # Blocks within execution defer (5 epochs) and reward_defer (12 epochs) do not have state_valid available_blocks = blocks_in_era[:-17] assert_blocks_valid(self.nodes[:-1], available_blocks) assert_blocks_valid(self.nodes[-1:], available_blocks)
def run_test(self): start_p2p_connection(self.nodes) block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() client = RpcClient(self.nodes[0]) file_dir = os.path.dirname(os.path.realpath(__file__)) self.log.info("Initializing contract") self.buggy_contract = get_contract_instance(source=os.path.join( file_dir, "contracts/reentrancy.sol"), contract_name="Reentrance") self.exploit_contract = get_contract_instance( source=os.path.join(file_dir, "contracts/reentrancy_exploit.sol"), contract_name="ReentranceExploit") user1, _ = ec_random_keys() user1_addr = priv_to_addr(user1) user1_addr_hex = eth_utils.encode_hex(user1_addr) user2, _ = ec_random_keys() user2_addr = priv_to_addr(user2) user2_addr_hex = eth_utils.encode_hex(user2_addr) # setup balance value = (10**15 + 2000) * 10**18 + ReentrancyTest.REQUEST_BASE['gas'] tx = create_transaction(pri_key=self.genesis_priv_key, receiver=user1_addr, value=value, nonce=self.get_nonce(self.genesis_addr), gas_price=ReentrancyTest.REQUEST_BASE['gas']) self.send_transaction(tx, True, False) tx = create_transaction(pri_key=self.genesis_priv_key, receiver=user2_addr, value=value, nonce=self.get_nonce(self.genesis_addr), gas_price=ReentrancyTest.REQUEST_BASE['gas']) self.send_transaction(tx, True, False) user1_balance = client.get_balance(user1_addr_hex) assert_equal(user1_balance, value) user2_balance_before_contract_construction = client.get_balance( user2_addr_hex) assert_equal(user2_balance_before_contract_construction, value) transaction = self.call_contract_function(self.buggy_contract, "constructor", [], self.genesis_priv_key, storage_limit=20000) contract_addr = self.wait_for_tx([transaction], True)[0]['contractCreated'] transaction = self.call_contract_function(self.exploit_contract, "constructor", [], user2, storage_limit=200000) exploit_addr = self.wait_for_tx([transaction], True)[0]['contractCreated'] user2_balance_after_contract_construction = client.get_balance( user2_addr_hex) self.log.debug("user2 balance contract created %s" % user2_balance_after_contract_construction) assert_greater_than_or_equal( user2_balance_before_contract_construction, user2_balance_after_contract_construction) user2_refund_upper_bound = \ user2_balance_before_contract_construction - \ user2_balance_after_contract_construction transaction = self.call_contract_function(self.buggy_contract, "addBalance", [], user1, 10**18, contract_addr, True, True, storage_limit=128) transaction = self.call_contract_function( self.exploit_contract, "deposit", [Web3.toChecksumAddress(contract_addr)], user2, 10**18, exploit_addr, True, True, storage_limit=128) user1_balance = client.get_balance(user1_addr_hex) assert_greater_than_or_equal(user1_balance, 899999999999999999999999950000000) user2_balance_after_deposit = client.get_balance(user2_addr_hex) # User2 paid storage collateral `vulnerable_contract` in deposit call. user2_refund_upper_bound += 10**18 // 16 self.log.debug("user2 balance after deposit %s" % user2_balance_after_deposit) assert_greater_than_or_equal(user2_balance_after_contract_construction, user2_balance_after_deposit + 10**18) assert_greater_than_or_equal(user2_balance_after_deposit, 899999999999999999999999900000000) contract_balance = client.get_balance(contract_addr) assert_equal(contract_balance, 2 * 10**18) user2_balance_in_contract = RpcClient(self.nodes[0]).call( contract_addr, self.buggy_contract.functions.balanceOf( Web3.toChecksumAddress(exploit_addr)).buildTransaction({ "from": user2_addr_hex, "to": contract_addr, "gas": int_to_hex(CONTRACT_DEFAULT_GAS), "gasPrice": int_to_hex(1), "chainId": 0 })["data"]) assert_equal(parse_as_int(user2_balance_in_contract), 10**18) transaction = self.call_contract_function(self.exploit_contract, "launch_attack", [], user2, 0, exploit_addr, True, True, storage_limit=128) transaction = self.call_contract_function(self.exploit_contract, "get_money", [], user2, 0, exploit_addr, True, True, storage_limit=128) user1_balance = client.get_balance(user1_addr_hex) assert_greater_than_or_equal(user1_balance, 899999999999999999999999950000000) contract_balance = client.get_balance(contract_addr) assert_equal(contract_balance, 1 * 10**18) user2_balance_in_contract = RpcClient(self.nodes[0]).call( contract_addr, self.buggy_contract.functions.balanceOf( Web3.toChecksumAddress(exploit_addr)).buildTransaction({ "from": user2_addr_hex, "to": contract_addr, "gas": int_to_hex(CONTRACT_DEFAULT_GAS), "gasPrice": int_to_hex(1), "chainId": 0 })["data"]) assert_equal(parse_as_int(user2_balance_in_contract), 0) self.log.debug("user2 balance in contract %s" % user2_balance_in_contract) user2_balance_after_contract_destruct = client.get_balance( user2_addr_hex) self.log.debug("user2 balance after contract destruct %s" % user2_balance_after_contract_destruct) assert_greater_than_or_equal( user2_balance_after_contract_destruct, user2_balance_after_deposit + user2_refund_upper_bound + 10**18) block_gen_thread.stop() block_gen_thread.join()
def run_test(self): file_dir = os.path.dirname(os.path.realpath(__file__)) file_path = os.path.join(file_dir, "..", "internal_contract", "metadata", "Staking.json") staking_contract_dict = json.loads(open(os.path.join(file_path), "r").read()) staking_contract = get_contract_instance(contract_dict=staking_contract_dict) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_key = default_config["GENESIS_PRI_KEY"] genesis_addr = priv_to_addr(genesis_key) nonce = 0 gas_price = 1 gas = CONTRACT_DEFAULT_GAS block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() self.tx_conf = {"from":Web3.toChecksumAddress(encode_hex_0x(genesis_addr)), "nonce":int_to_hex(nonce), "gas":int_to_hex(gas), "gasPrice":int_to_hex(gas_price), "chainId":0} total_num_blocks = 2 * 60 * 60 * 24 * 365 accumulate_interest_rate = [2 ** 80 * total_num_blocks] for _ in range(1000): accumulate_interest_rate.append(accumulate_interest_rate[-1] * ( 40000 + 1000000 * total_num_blocks) // (total_num_blocks * 1000000)) # Setup balance for node 0 node = self.nodes[0] client = RpcClient(node) (addr, priv_key) = client.rand_account() self.log.info("addr=%s priv_key=%s", addr, priv_key) tx = client.new_tx(value=5 * 10 ** 18, receiver=addr) client.send_tx(tx) self.wait_for_tx([tx]) assert_equal(client.get_balance(addr), 5 * 10 ** 18) assert_equal(client.get_staking_balance(addr), 0) self.tx_conf["to"] = Web3.toChecksumAddress("0888000000000000000000000000000000000002") # deposit 10**18 tx_data = decode_hex(staking_contract.functions.deposit(10 ** 18).buildTransaction(self.tx_conf)["data"]) tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key) client.send_tx(tx) self.wait_for_tx([tx]) deposit_time = self.get_block_number(client, tx.hash_hex()) assert_equal(client.get_staking_balance(addr), 10 ** 18) assert_equal(client.get_balance(addr), 4 * 10 ** 18 - charged_of_huge_gas(gas)) # withdraw 5 * 10**17 balance = client.get_balance(addr) capital = 5 * 10 ** 17 tx_data = decode_hex(staking_contract.functions.withdraw(capital).buildTransaction(self.tx_conf)["data"]) tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key) client.send_tx(tx) self.wait_for_tx([tx]) withdraw_time = self.get_block_number(client, tx.hash_hex()) interest = capital * accumulate_interest_rate[withdraw_time] // accumulate_interest_rate[deposit_time] - capital assert_equal(client.get_staking_balance(addr), 10 ** 18 - capital) assert_equal(client.get_balance(addr), balance + capital + interest - charged_of_huge_gas(gas)) # lock 4 * 10 ** 17 until block number 100000 balance = client.get_balance(addr) tx_data = decode_hex(staking_contract.functions.vote_lock(4 * 10 ** 17, 100000).buildTransaction(self.tx_conf)["data"]) tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key) client.send_tx(tx) self.wait_for_tx([tx]) assert_equal(client.get_balance(addr), balance - charged_of_huge_gas(gas)) assert_equal(client.get_staking_balance(addr), 5 * 10 ** 17) # withdraw 5 * 10**17 and it should fail balance = client.get_balance(addr) capital = 5 * 10 ** 17 tx_data = decode_hex(staking_contract.functions.withdraw(capital).buildTransaction(self.tx_conf)["data"]) tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key) client.send_tx(tx) self.wait_for_tx([tx]) assert_equal(client.get_balance(addr), balance - gas) assert_equal(client.get_staking_balance(addr), 5 * 10 ** 17) # withdraw 10**17 + 1 and it should fail balance = client.get_balance(addr) tx_data = decode_hex(staking_contract.functions.withdraw(10 ** 17 + 1).buildTransaction(self.tx_conf)["data"]) tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key) client.send_tx(tx) self.wait_for_tx([tx]) assert_equal(client.get_balance(addr), balance - gas) assert_equal(client.get_staking_balance(addr), 5 * 10 ** 17) # withdraw 10**17 and it should succeed balance = client.get_balance(addr) capital = 10 ** 17 tx_data = decode_hex(staking_contract.functions.withdraw(capital).buildTransaction(self.tx_conf)["data"]) tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key) client.send_tx(tx) self.wait_for_tx([tx]) withdraw_time = self.get_block_number(client, tx.hash_hex()) interest = capital * accumulate_interest_rate[withdraw_time] // accumulate_interest_rate[deposit_time] - capital assert_equal(client.get_balance(addr), balance + capital + interest - charged_of_huge_gas(gas)) assert_equal(client.get_staking_balance(addr), 5 * 10 ** 17 - capital) block_gen_thread.stop() block_gen_thread.join() sync_blocks(self.nodes) self.log.info("Pass")
def run_test(self): file_dir = os.path.dirname(os.path.realpath(__file__)) storage_contract = get_contract_instance( abi_file=os.path.join(file_dir, "contracts/simple_storage.abi"), bytecode_file=os.path.join(file_dir, "contracts/simple_storage.dat"), ) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_addr = self.genesis_addr self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr))) block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() client = RpcClient(self.nodes[0]) client1 = RpcClient(self.nodes[1]) tx = client.new_tx(value=int(0.625 * CFX) + GDrip, receiver=self.eth_hex_addr, nonce=self.get_nonce(genesis_addr)) client.send_tx(tx, True) assert_equal(client.get_balance(self.eth_hex_addr), int(0.625 * CFX) + GDrip) # deploy pay contract block_gen_thread.stop( ) # stop the block generation to test transaction relay. time.sleep(3) self.log.info("Deploying contract") tx = self.call_contract_function( contract=storage_contract, name="constructor", args=[], sender_key=self.eth_priv_key, eth_tx=True, ) assert_equal(tx["epoch_height"], 0xffff_ffff_ffff_ffff) wait_until(lambda: self.nodes[1].txpool_txWithPoolInfo(tx.hash_hex())[ 'exist'], timeout=5) block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() receipt = self.wait_for_tx([tx], True)[0] assert_equal(int(receipt["storageCollateralized"], 0), 640) contract_addr = receipt['contractCreated'] self.log.info("contract_addr={}".format(contract_addr)) assert_equal(client.get_collateral_for_storage(self.eth_hex_addr), int(0.625 * CFX)) assert_greater_than(GDrip, client.get_balance(self.eth_hex_addr)) storage_contract = get_contract_instance( abi_file=os.path.join(file_dir, "contracts/simple_storage.abi"), bytecode_file=os.path.join(file_dir, "contracts/simple_storage.dat"), ) # Should fail because of not enough balance for storage. self.log.info("Sending transaction without enough collateral") tx = self.call_contract_function( contract=storage_contract, contract_addr=contract_addr, name="setFresh", args=[], sender_key=self.eth_priv_key, eth_tx=True, ) receipt = self.wait_for_tx([tx])[0] assert_equal(int(receipt["outcomeStatus"], 0), 1) sponsor_whitelist_contract_addr = Web3.toChecksumAddress( "0888000000000000000000000000000000000001") file_dir = os.path.dirname(os.path.realpath(__file__)) control_contract_file_path = os.path.join( file_dir, "..", "internal_contract", "metadata", "SponsorWhitelistControl.json") control_contract_dict = json.loads( open(control_contract_file_path, "r").read()) control_contract = get_contract_instance( contract_dict=control_contract_dict) self.log.info("Setting sponsor for collateral") self.call_contract_function( contract=control_contract, name="setSponsorForCollateral", args=[Web3.toChecksumAddress(contract_addr)], value=1 * CFX, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True, check_status=True) self.log.info("Sending balance to eth_like tx") tx = client.new_tx(value=int(0.0625 * CFX), receiver=self.eth_hex_addr, nonce=self.get_nonce(genesis_addr)) client.send_tx(tx, True) self.log.info("Setting whitelist for all") self.call_contract_function( contract=control_contract, name="addPrivilegeByAdmin", args=[ Web3.toChecksumAddress(contract_addr), [Web3.toChecksumAddress("0x" + "0" * 40)] ], sender_key=self.eth_priv_key, contract_addr=sponsor_whitelist_contract_addr, eth_tx=True, wait=True, check_status=True) # Should not fail because of sponsored self.log.info("Sending transaction when sponsored") time.sleep(3) block_gen_thread.stop( ) # stop the block generation to test transaction relay in sponsorship tx = self.call_contract_function( contract=storage_contract, contract_addr=contract_addr, name="setFresh", args=[], sender_key=self.eth_priv_key, eth_tx=True, ) wait_until(lambda: self.nodes[1].txpool_txWithPoolInfo(tx.hash_hex())[ 'exist'], timeout=5) block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() receipt = self.wait_for_tx([tx])[0] assert_equal(receipt["storageCoveredBySponsor"], True) assert_equal(int(receipt["storageCollateralized"], 0), 64) wait_until(lambda: checktx(self.nodes[1], tx.hash_hex()), timeout=20) self.log.info("Pass")
class StorageMaintenanceTest(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True self.mining_author = "0x10000000000000000000000000000000000000aa" self.conf_parameters = { "mining_author": "\"10000000000000000000000000000000000000aa\"", "mining_type": "'disable'" } self.gasPrice = 1 def setup_network(self): self.log.info("setup nodes ...") self.setup_nodes() def run_test(self): self.rpc = RpcClient(self.nodes[0]) priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) # 7000000000000000000 plus genesis collateral_for_storage for PoS genesis accounts. block_reward = 7000000000118911719 # deploy storage test contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() # 1. Produce an empty block self.rpc.generate_block() # 2. Deploy a contract: this will create 6 blocks and the first block contains 'create contract' transaction, # the other 5 blocks are empty. receipt, _ = self.deploy_contract(sender, priv_key, bytecode) # 3. Produce 10 empty blocks, and the miner's reward for the first block will be updated to world-state for _ in range(10): self.rpc.generate_block() balance = self.rpc.get_balance(self.mining_author) count = self.rpc.get_block_count() expected = block_reward self.log.info("block count: %d, balance: %d, expected: %d", count, balance, expected) assert_equal(balance, expected) # 4. Produce 1 empty block, and the miner will receive reward for the second block. This block reward should # contains transaction fee. self.rpc.generate_blocks(1) balance = self.rpc.get_balance(self.mining_author) count = self.nodes[0].getblockcount() transaction_fee = parse_as_int(receipt['gasFee']) expected += block_reward + transaction_fee self.log.info( "block count: %d, balance: %d, expected: %d, transaction_fee: %d", count, balance, expected, transaction_fee) assert_equal(balance, expected) # TODO(lpl): Temp fix storage collateral precision issue. expected += 1 # 5. Produce 1 empty block, and the miner will receive reward for the third empty block. This block reward # should contains storage maintenance fee. self.rpc.generate_blocks(1) balance = self.rpc.get_balance(self.mining_author) count = self.nodes[0].getblockcount() collateral_for_storage = self.rpc.get_collateral_for_storage(sender) storage_fee = collateral_for_storage * 4 // 100 // 63072000 expected += block_reward + storage_fee self.log.info( "block count: %d, balance: %d, expected: %d, collateral_for_storage: %d, storage_fee: %d", count, balance, expected, collateral_for_storage, storage_fee) assert_equal(balance, expected) expected += 1 # 6. Produce 1 empty block, and the miner will receive reward for the forth empty block. This block reward # should contains storage maintenance fee. self.rpc.generate_blocks(1) balance = self.rpc.get_balance(self.mining_author) count = self.nodes[0].getblockcount() collateral_for_storage = self.rpc.get_collateral_for_storage(sender) storage_fee = collateral_for_storage * 4 // 100 // 63072000 expected += storage_fee + block_reward self.log.info( "block count: %d, balance: %d, expected: %d, collateral_for_storage: %d, storage_fee: %d", count, balance, expected, collateral_for_storage, storage_fee) assert_equal(balance, expected) def deploy_contract(self, sender, priv_key, data_hex): tx = self.rpc.new_contract_tx(receiver="", data_hex=data_hex, sender=sender, priv_key=priv_key, nonce=None, gas_price=self.gasPrice, storage_limit=20000) assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex()) receipt = self.rpc.get_transaction_receipt(tx.hash_hex()) address = receipt["contractCreated"] assert_is_hex_string(address) return receipt, address
def run_test(self): # Pos contract enabled, stake and register in the first hard-fork phase. client = RpcClient(self.nodes[self.num_nodes - 1]) client.generate_empty_blocks(300) sync_blocks(self.nodes) for node in self.nodes[:-1]: client = RpcClient(node) pos_identifier, _ = client.wait_for_pos_register() sync_blocks(self.nodes) client = RpcClient(self.nodes[self.num_nodes - 1]) # generate blocks until we are after pos initialization and before pos start. best_epoch = client.epoch_number() client.generate_empty_blocks(600 - best_epoch) sync_blocks(self.nodes) voting_power_map = {} pub_keys_map = {} logs = client.get_logs(filter=Filter(from_epoch="earliest", to_epoch="latest_state", address=["0x0888000000000000000000000000000000000005"])) for log in logs: pos_identifier = log["topics"][1] if log["topics"][0] == REGISTER_TOPIC: bls_pub_key, vrf_pub_key = eth_abi.decode_abi(["bytes", "bytes"], decode_hex(log["data"])) pub_keys_map[pos_identifier] = (encode_hex_0x(bls_pub_key), encode_hex_0x(vrf_pub_key)) elif log["topics"][0] == INCREASE_STAKE_TOPIC: assert pos_identifier in pub_keys_map voting_power_map[pos_identifier] = parse_as_int(log["data"]) with open(os.path.join(self.options.tmpdir, "public_keys"), "w") as f: for pos_identifier in pub_keys_map.keys(): f.write(",".join([pub_keys_map[pos_identifier][0][2:], pub_keys_map[pos_identifier][1][2:], str(voting_power_map[pos_identifier])]) + "\n") initialize_tg_config(self.options.tmpdir, len(self.nodes), len(self.nodes), DEFAULT_PY_TEST_CHAIN_ID, pkfile="public_keys") # generate blocks until pos start self.nodes[0].generate_empty_blocks(500) sync_blocks(self.nodes) pos_identifier, _ = client.wait_for_pos_register() client.generate_empty_blocks(400) sync_blocks(self.nodes) time.sleep(2) latest_pos_ref = self.latest_pos_ref() for i in range(55): print(i) if i == 10: self.stop_node(5, clean=True) self.start_node(5, phase_to_wait=None) self.nodes[5].wait_for_recovery(["NormalSyncPhase"], 30) if i == 12: self.maybe_restart_node(5, 1, 0) if i == 15: assert_equal(int(client.pos_get_account(pos_identifier)["status"]["availableVotes"], 0), 2000) client.pos_retire_self() if i == 30: self.maybe_restart_node(5, 1, 1) # Retire node 3 after 5 min. # Generate enough PoW block for PoS to progress self.nodes[0].generate_empty_blocks(60) # Leave some time for PoS to reach consensus time.sleep(3) self.nodes[0].generate_empty_blocks(1) new_pos_ref = self.latest_pos_ref() if i >= 10: assert_ne(latest_pos_ref, new_pos_ref) client.wait_for_unstake(client.node.pow_sk) assert client.get_balance(eth_utils.encode_hex(priv_to_addr(client.node.pow_sk))) > 10000 * 10**18 assert_equal(int(client.pos_get_account(pos_identifier)["status"]["availableVotes"], 0), 0)
def run_test(self): start_p2p_connection(self.nodes) block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() client = RpcClient(self.nodes[0]) file_dir = os.path.dirname(os.path.realpath(__file__)) self.log.info("Initializing contract") self.buggy_contract = get_contract_instance(source=os.path.join( file_dir, "contracts/reentrancy.sol"), contract_name="Reentrance") self.exploit_contract = get_contract_instance( source=os.path.join(file_dir, "contracts/reentrancy_exploit.sol"), contract_name="ReentranceExploit") reentrancy_config_addr = Web3.toChecksumAddress( "0888000000000000000000000000000000000003") file_dir = os.path.dirname(os.path.realpath(__file__)) control_contract_file_path = os.path.join(file_dir, "..", "internal_contract", "metadata", "ReentrancyConfig.json") control_contract_dict = json.loads( open(control_contract_file_path, "r").read()) control_contract = get_contract_instance( contract_dict=control_contract_dict) user1, _ = ec_random_keys() user1_addr = priv_to_addr(user1) user1_addr_hex = eth_utils.encode_hex(user1_addr) user2, _ = ec_random_keys() user2_addr = priv_to_addr(user2) user2_addr_hex = eth_utils.encode_hex(user2_addr) # setup balance value = (10**15 + 2000) * 10**18 + ReentrancyTest.REQUEST_BASE['gas'] tx = create_transaction(pri_key=self.genesis_priv_key, receiver=user1_addr, value=value, nonce=self.get_nonce(self.genesis_addr), gas_price=ReentrancyTest.REQUEST_BASE['gas']) self.send_transaction(tx, True, False) tx = create_transaction(pri_key=self.genesis_priv_key, receiver=user2_addr, value=value, nonce=self.get_nonce(self.genesis_addr), gas_price=ReentrancyTest.REQUEST_BASE['gas']) self.send_transaction(tx, True, False) user1_balance = client.get_balance(user1_addr_hex) assert_equal(user1_balance, value) user2_balance_before_contract_construction = client.get_balance( user2_addr_hex) assert_equal(user2_balance_before_contract_construction, value) transaction = self.call_contract_function(self.buggy_contract, "constructor", [], self.genesis_priv_key, storage_limit=20000) buggy_addr = self.wait_for_tx([transaction], True)[0]['contractCreated'] transaction = self.call_contract_function(self.exploit_contract, "constructor", [], user2, storage_limit=200000) exploit_addr = self.wait_for_tx([transaction], True)[0]['contractCreated'] if self.mode == NO_PROTECTION: self.log.info("Disabling anti-reentrancy") self.call_contract_function( contract=control_contract, name="allowReentrancyByAdmin", args=[Web3.toChecksumAddress(buggy_addr), True], sender_key=self.genesis_priv_key, contract_addr=reentrancy_config_addr, storage_limit=64, wait=True, check_status=True) self.call_contract_function( contract=control_contract, name="allowReentrancyByAdmin", args=[Web3.toChecksumAddress(exploit_addr), True], sender_key=user2, contract_addr=reentrancy_config_addr, storage_limit=64, wait=True, check_status=True) user2_balance_after_contract_construction = client.get_balance( user2_addr_hex) self.log.debug("user2 balance contract created %s" % user2_balance_after_contract_construction) assert_greater_than_or_equal( user2_balance_before_contract_construction, user2_balance_after_contract_construction) user2_refund_upper_bound = \ user2_balance_before_contract_construction - \ user2_balance_after_contract_construction transaction = self.call_contract_function(self.buggy_contract, "addBalance", [], user1, 10**18, buggy_addr, True, True, storage_limit=128) transaction = self.call_contract_function( self.exploit_contract, "deposit", [Web3.toChecksumAddress(buggy_addr)], user2, 10**18, exploit_addr, True, True, storage_limit=128) user1_balance = client.get_balance(user1_addr_hex) assert_greater_than_or_equal(user1_balance, 899999999999999999999999950000000) user2_balance_after_deposit = client.get_balance(user2_addr_hex) # User2 paid storage collateral `vulnerable_contract` in deposit call. user2_refund_upper_bound += 3 * 10**18 // 16 self.log.debug("user2 balance after deposit %s" % user2_balance_after_deposit) assert_greater_than_or_equal(user2_balance_after_contract_construction, user2_balance_after_deposit + 10**18) assert_greater_than_or_equal(user2_balance_after_deposit, 899999999999999999999999900000000) contract_balance = client.get_balance(buggy_addr) assert_equal(contract_balance, 2 * 10**18) user2_balance_in_contract = RpcClient(self.nodes[0]).call( buggy_addr, self.buggy_contract.functions.balanceOf( Web3.toChecksumAddress(exploit_addr)).buildTransaction({ "from": user2_addr_hex, "to": buggy_addr, "gas": int_to_hex(CONTRACT_DEFAULT_GAS), "gasPrice": int_to_hex(1), "chainId": 0 })["data"]) assert_equal(parse_as_int(user2_balance_in_contract), 10**18) transaction = self.call_contract_function(self.exploit_contract, "launch_attack", [], user2, 0, exploit_addr, True, True, storage_limit=128) transaction = self.call_contract_function(self.exploit_contract, "get_money", [], user2, 0, exploit_addr, True, True, storage_limit=128) user1_balance = client.get_balance(user1_addr_hex) assert_greater_than_or_equal(user1_balance, 899999999999999999999999950000000) contract_balance = client.get_balance(buggy_addr) attack_benefit = 0 if self.mode == OLD_MODE: # In the old mode, the second withdraw_balance will fail. rest_balance, attacker_rest = 1 * CFX, 0 elif self.mode == NEW_MODE: # In the new mode, the protection is closed. rest_balance, attacker_rest = 0, 0 attack_benefit = 1 * CFX else: raise Exception("Unrecognized reentrancy test mode") assert_equal(contract_balance, rest_balance) user2_balance_in_contract = RpcClient(self.nodes[0]).call( buggy_addr, self.buggy_contract.functions.balanceOf( Web3.toChecksumAddress(exploit_addr)).buildTransaction({ "from": user2_addr_hex, "to": buggy_addr, "gas": int_to_hex(CONTRACT_DEFAULT_GAS), "gasPrice": int_to_hex(1), "chainId": 0 })["data"]) assert_equal(parse_as_int(user2_balance_in_contract), attacker_rest) self.log.debug("user2 balance in contract %s" % user2_balance_in_contract) user2_balance_after_contract_destruct = client.get_balance( user2_addr_hex) self.log.debug("user2 balance after contract destruct %s" % user2_balance_after_contract_destruct) assert_greater_than_or_equal( user2_balance_after_deposit + user2_refund_upper_bound + 10**18 - attacker_rest + attack_benefit, user2_balance_after_contract_destruct, ) block_gen_thread.stop() block_gen_thread.join()
def run_test(self): file_dir = os.path.dirname(os.path.realpath(__file__)) pay_contract = get_contract_instance( abi_file=os.path.join(file_dir, "contracts/pay_abi.json"), bytecode_file=os.path.join(file_dir, "contracts/pay_bytecode.dat"), ) control_contract_file_path =os.path.join(file_dir, "../internal_contract/metadata/AdminControl.json") control_contract_dict = json.loads(open(control_contract_file_path, "r").read()) admin_control_contract = get_contract_instance(contract_dict=control_contract_dict) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_key = self.genesis_priv_key genesis_addr = self.genesis_addr self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr))) nonce = 0 gas_price = 1 gas = CONTRACT_DEFAULT_GAS block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() self.tx_conf = {"from":Web3.toChecksumAddress(encode_hex_0x(genesis_addr)), "nonce":int_to_hex(nonce), "gas":int_to_hex(gas), "gasPrice":int_to_hex(gas_price), "chainId":0} # Setup balance for node 0 node = self.nodes[0] client = RpcClient(node) (addr, priv_key) = client.rand_account() self.log.info("addr=%s priv_key=%s", addr, priv_key) tx = client.new_tx(value=5 * 10 ** 18, receiver=addr, nonce=self.get_nonce(genesis_addr)) client.send_tx(tx, True) assert_equal(client.get_balance(addr), 5000000000000000000) (addr2, priv_key2) = client.rand_account() self.log.info("addr2=%s priv_key2=%s", addr2, priv_key2) tx = client.new_tx(value=5 * 10 ** 18, receiver=addr2, nonce=self.get_nonce(genesis_addr)) client.send_tx(tx, True) assert_equal(client.get_balance(addr2), 5000000000000000000) # deploy pay contract tx = self.call_contract_function( contract=pay_contract, name="constructor", args=[], sender_key=priv_key, storage_limit=512) contract_addr = self.wait_for_tx([tx], True)[0]['contractCreated'] self.log.info("contract_addr={}".format(contract_addr)) assert_equal(client.get_collateral_for_storage(addr), 512 * 976562500000000) assert_equal(client.get_balance(contract_addr), 0) # deposit 10**18 b0 = int(node.cfx_getBalance(addr), 16) tx = self.call_contract_function( contract=pay_contract, name="recharge", args=[], sender_key=priv_key, contract_addr=contract_addr, value=10 ** 18, wait=True, check_status=True) assert_equal(client.get_balance(contract_addr), 10 ** 18) assert_equal(client.get_balance(addr), b0 - 10 ** 18 - charged_of_huge_gas(gas)) assert_equal(client.get_admin(contract_addr), addr) # transfer admin (fail) tx = self.call_contract_function( contract=admin_control_contract, name="setAdmin", args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)], sender_key=priv_key2, contract_addr=Web3.toChecksumAddress("0x0888000000000000000000000000000000000000"), wait=True, check_status=True) assert_equal(client.get_admin(contract_addr), addr) assert_equal(client.get_balance(addr2), 5 * 10 ** 18 - charged_of_huge_gas(gas)) # transfer admin (success) tx = self.call_contract_function( contract=admin_control_contract, name="setAdmin", args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)], sender_key=priv_key, contract_addr=Web3.toChecksumAddress("0x0888000000000000000000000000000000000000"), wait=True, check_status=True) assert_equal(client.get_admin(contract_addr), addr2) # destroy b0 = client.get_balance(addr) tx = self.call_contract_function( contract=admin_control_contract, name="destroy", args=[Web3.toChecksumAddress(contract_addr)], sender_key=priv_key2, contract_addr=Web3.toChecksumAddress("0x0888000000000000000000000000000000000000"), wait=True, check_status=True) assert_equal(client.get_balance(contract_addr), 0) assert_equal(client.get_balance(addr2), 6 * 10 ** 18 - charged_of_huge_gas(gas) * 2) assert_equal(client.get_collateral_for_storage(addr), 0) assert_equal(client.get_balance(addr), b0 + 512 * 976562500000000) self.log.info("Pass")
def run_test(self): sponsor_whitelist_contract_addr = Web3.toChecksumAddress( "0888000000000000000000000000000000000001") collateral_per_storage_key = 10**18 // 16 upper_bound = 5 * 10**7 file_dir = os.path.dirname(os.path.realpath(__file__)) control_contract_file_path = os.path.dirname( os.path.realpath(__file__)).split("/") control_contract_file_path.pop(-1) control_contract_file_path.extend( ["internal_contract", "metadata", "SponsorWhitelistControl.json"]) control_contract_file_path = "/".join(control_contract_file_path) control_contract_dict = json.loads( open(os.path.join(control_contract_file_path), "r").read()) control_contract = get_contract_instance( contract_dict=control_contract_dict) test_contract = get_contract_instance( abi_file=os.path.join( file_dir, "contracts/commission_privilege_test_abi.json"), bytecode_file=os.path.join( file_dir, "contracts/commission_privilege_test_bytecode.dat"), ) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_key = self.genesis_priv_key genesis_addr = encode_hex(self.genesis_addr) self.log.info("genesis_addr={}".format(genesis_addr)) nonce = 0 gas_price = 1 gas = CONTRACT_DEFAULT_GAS block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() self.tx_conf = { "from": Web3.toChecksumAddress(genesis_addr), "nonce": int_to_hex(nonce), "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } # Setup balance for node 0 node = self.nodes[0] client = RpcClient(node) (addr1, priv_key1) = client.rand_account() self.log.info("addr1={}".format(addr1)) tx = client.new_tx(sender=genesis_addr, priv_key=genesis_key, value=10**6, nonce=self.get_nonce(self.genesis_addr), receiver=addr1) client.send_tx(tx, True) assert_equal(client.get_balance(addr1), 10**6) # setup contract transaction = self.call_contract_function( contract=test_contract, name="constructor", args=[], sender_key=self.genesis_priv_key, storage_limit=20000) contract_addr = self.wait_for_tx([transaction], True)[0]['contractCreated'] self.log.info("contract_addr={}".format(contract_addr)) assert_equal(client.get_balance(contract_addr), 0) # sponsor the contract succeed b0 = client.get_balance(genesis_addr) self.call_contract_function( contract=control_contract, name="set_sponsor_for_gas", args=[Web3.toChecksumAddress(contract_addr), upper_bound], value=10**18, sender_key=self.genesis_priv_key, contract_addr=sponsor_whitelist_contract_addr, wait=True) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18) assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr) assert_equal(client.get_sponsor_gas_bound(contract_addr), upper_bound) assert_equal(client.get_balance(genesis_addr), b0 - 10**18 - charged_of_huge_gas(gas)) # set privilege for addr1 b0 = client.get_balance(genesis_addr) c0 = client.get_collateral_for_storage(genesis_addr) self.call_contract_function(contract=test_contract, name="add", args=[Web3.toChecksumAddress(addr1)], sender_key=genesis_key, contract_addr=contract_addr, wait=True, check_status=True, storage_limit=64) assert_equal( client.get_balance(genesis_addr), b0 - charged_of_huge_gas(gas) - collateral_per_storage_key) assert_equal(client.get_collateral_for_storage(genesis_addr), c0 + collateral_per_storage_key) # addr1 call contract with privilege without enough cfx for gas fee sb = client.get_sponsor_balance_for_gas(contract_addr) b1 = client.get_balance(addr1) self.call_contract_function(contract=test_contract, name="foo", args=[], sender_key=priv_key1, contract_addr=contract_addr, wait=True, check_status=True) assert_equal(client.get_balance(addr1), 10**6) assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb - charged_of_huge_gas(gas)) self.log.info("Pass")
def run_test(self): genesis_key = default_config["GENESIS_PRI_KEY"] receiver_sk, _ = ec_random_keys() receiver_addr = priv_to_addr(receiver_sk) client = RpcClient(self.nodes[0]) value = 100000000 tx = create_transaction(pri_key=genesis_key, receiver=receiver_addr, value=value, nonce=0, gas_price=1, epoch_height=0) client.send_tx(tx) block_gen_thread = BlockGenThread(self.nodes, self.log, interval_base=0.1) block_gen_thread.start() self.log.info( "Wait for the first transaction to go through with epoch_height = 0..." ) wait_until(lambda: client.get_balance( eth_utils.encode_hex(receiver_addr)) == value) self.log.info("Wait for generating more than 50 epochs") wait_until(lambda: parse_as_int( client.block_by_hash(client.best_block_hash())['height']) > 50) block_gen_thread.stop() self.log.info("Now block count:%d", self.nodes[0].getblockcount()) tx = create_transaction(pri_key=genesis_key, receiver=receiver_addr, value=value, nonce=1, gas_price=1, epoch_height=0) try: client.send_tx(tx) self.log.info("Bad transaction not rejected!") assert (False) except ReceivedErrorResponseError: self.log.info("Bad transaction rejected.") except: self.log.info("Unexpected error!") assert (False) assert (client.get_balance( eth_utils.encode_hex(receiver_addr)) == value) epoch_height = parse_as_int( client.block_by_hash(client.best_block_hash())['height']) tx = create_transaction(pri_key=genesis_key, receiver=receiver_addr, value=value, nonce=1, gas_price=1, epoch_height=epoch_height) client.send_tx(tx) block_gen_thread = BlockGenThread(self.nodes, self.log, interval_base=0.1) block_gen_thread.start() self.log.info( "Wait for the first transaction to go through with epoch_height = " + str(epoch_height) + "...") wait_until(lambda: client.get_balance( eth_utils.encode_hex(receiver_addr)) == 2 * value) block_gen_thread.stop() self.log.info("Now block count:%d", self.nodes[0].getblockcount()) self.log.info("Pass!")