def run_test(self): # Prevent easysolc from configuring the root logger to print to stderr self.log.propagate = False solc = Solc() # erc20_contract = solc.get_contract_instance(source=os.path.dirname(os.path.realpath(__file__)) + "/erc20.sol", contract_name="FixedSupplyToken") file_dir = os.path.dirname(os.path.realpath(__file__)) erc20_contract = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/erc20_abi.json"), bytecode_file=os.path.join(file_dir, "contracts/erc20_bytecode.dat"), ) staking_contract = solc.get_contract_instance( abi_file=os.path.join( file_dir, "contracts/storage_interest_staking_abi.json"), bytecode_file=os.path.join( file_dir, "contracts/storage_interest_staking_bytecode.dat"), ) # lock tokens in bank gas_price = 1 gas = 50000000 self.tx_conf = { "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } staking_contract_addr = Web3.toChecksumAddress( "443c409373ffd5c0bec1dddb7bec830856757b65") self.tx_conf["to"] = staking_contract_addr tx_data = decode_hex( staking_contract.functions.deposit( 10000 * 10**18).buildTransaction(self.tx_conf)["data"]) node = self.nodes[0] client = RpcClient(node) genesis_key = default_config["GENESIS_PRI_KEY"] genesis_addr = privtoaddr(genesis_key) tx = client.new_tx(value=0, receiver=staking_contract_addr, nonce=0, data=tx_data, gas=gas, gas_price=gas_price) client.send_tx(tx, True) start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_key = default_config["GENESIS_PRI_KEY"] genesis_addr = privtoaddr(genesis_key) nonce = 1 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 } raw_create = erc20_contract.constructor().buildTransaction( self.tx_conf) tx_data = decode_hex(raw_create["data"]) tx_create = create_transaction(pri_key=genesis_key, receiver=b'', nonce=nonce, gas_price=gas_price, data=tx_data, gas=gas, value=0) self.nodes[0].p2p.send_protocol_msg( Transactions(transactions=[tx_create])) self.wait_for_tx([tx_create]) self.log.info("Contract created, start transfering tokens") tx_n = 10 self.tx_conf["to"] = Web3.toChecksumAddress( encode_hex_0x(sha3_256(rlp.encode([genesis_addr, nonce]))[-20:])) nonce += 1 balance_map = {genesis_key: 1000000 * 10**18} sender_key = genesis_key all_txs = [] for i in range(tx_n): value = int((balance_map[sender_key] - ((tx_n - i) * 21000 * gas_price)) * random.random()) receiver_sk, _ = ec_random_keys() balance_map[receiver_sk] = value tx_data = decode_hex( erc20_contract.functions.transfer( Web3.toChecksumAddress(encode_hex( privtoaddr(receiver_sk))), value).buildTransaction(self.tx_conf)["data"]) tx = create_transaction(pri_key=sender_key, receiver=decode_hex(self.tx_conf["to"]), value=0, nonce=nonce, gas=gas, gas_price=gas_price, data=tx_data) r = random.randint(0, self.num_nodes - 1) self.nodes[r].p2p.send_protocol_msg( Transactions(transactions=[tx])) nonce += 1 balance_map[sender_key] -= value all_txs.append(tx) self.log.info("Wait for transactions to be executed") self.wait_for_tx(all_txs) self.log.info("Check final token balance") for sk in balance_map: addr = privtoaddr(sk) assert_equal(self.get_balance(erc20_contract, addr, nonce), balance_map[sk]) block_gen_thread.stop() block_gen_thread.join() sync_blocks(self.nodes) self.log.info("Pass")
def run_test(self): sponsor_whitelist_contract_addr = Web3.toChecksumAddress( "8ad036480160591706c831f0da19d1a424e39469") 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): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) self.rpc = RpcClient(self.nodes[0]) # apply filter, we expect no logs filter = Filter(from_epoch="earliest", to_epoch="latest_mined") result = self.rpc.get_logs(filter) assert_equal(result, []) # deploy 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() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) # apply filter, we expect a single log with 2 topics filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs0 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs0) assert_equal(len(logs0), 1) assert_equal(len(logs0[0]["topics"]), 2) assert_equal(logs0[0]["topics"][0], CONSTRUCTED_TOPIC) assert_equal(logs0[0]["topics"][1], self.address_to_topic(sender)) assert_equal(logs0[0]["data"], self.address_to_topic(sender)) # call method receipt = self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=64) # apply filter, we expect two logs with 2 and 3 topics respectively filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs1 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs1) assert_equal(len(logs1), 2) assert_equal(logs1[0], logs0[0]) assert_equal(len(logs1[1]["topics"]), 3) assert_equal(logs1[1]["topics"][0], CALLED_TOPIC) assert_equal(logs1[1]["topics"][1], self.address_to_topic(sender)) assert_equal(logs1[1]["topics"][2], self.number_to_topic(1)) # apply filter for specific block, we expect a single log with 3 topics filter = Filter(block_hashes=[receipt["blockHash"]]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) assert_equal(logs[0], logs1[1]) # call many times for ii in range(0, NUM_CALLS - 2): self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=0) # apply filter, we expect NUM_CALLS log entries with inreasing uint32 fields filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) for ii in range(2, NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii)) # apply filter for specific topics filter = Filter(topics=[CONSTRUCTED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) filter = Filter(topics=[CALLED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS - 1) filter = Filter(topics=[None, self.address_to_topic(sender)]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) # find logs with `CALLED_TOPIC` as 1st topic and `3` or `4` as 3rd topic filter = Filter(topics=[ CALLED_TOPIC, None, [self.number_to_topic(3), self.number_to_topic(4)] ]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 2) # apply filter with limit filter = Filter(limit=("0x%x" % (NUM_CALLS // 2))) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS // 2) # apply filter for specific contract address _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode) filter = Filter(address=[contractAddr]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) filter = Filter(address=[contractAddr2]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) # apply filter to very first epoch, we expect no logs filter = Filter(from_epoch="0x0", to_epoch="0x0") result = self.rpc.get_logs(filter) assert_equal(result, []) self.log.info("Pass")
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): time.sleep(7) priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(privtoaddr(priv_key)) self.rpc = RpcClient(self.nodes[0]) # lock tokens in bank solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) staking_contract = solc.get_contract_instance( abi_file=os.path.join( file_dir, "contracts/storage_interest_staking_abi.json"), bytecode_file=os.path.join( file_dir, "contracts/storage_interest_staking_bytecode.dat"), ) gas_price = 1 gas = 50000000 self.tx_conf = { "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } staking_contract_addr = Web3.toChecksumAddress( "443c409373ffd5c0bec1dddb7bec830856757b65") self.tx_conf["to"] = staking_contract_addr tx_data = eth_utils.decode_hex( staking_contract.functions.deposit( 10000 * 10**18).buildTransaction(self.tx_conf)["data"]) genesis_key = default_config["GENESIS_PRI_KEY"] genesis_addr = privtoaddr(genesis_key) tx = self.rpc.new_tx(value=0, receiver=staking_contract_addr, nonce=0, data=tx_data, gas=gas, gas_price=gas_price) self.rpc.send_tx(tx, True) # apply filter, we expect no logs filter = Filter(from_epoch="earliest", to_epoch="latest_mined") result = self.rpc.get_logs(filter) assert_equal(result, []) # deploy 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() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) # apply filter, we expect a single log with 2 topics filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs0 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs0) assert_equal(len(logs0), 1) assert_equal(len(logs0[0]["topics"]), 2) assert_equal(logs0[0]["topics"][0], CONSTRUCTED_TOPIC) assert_equal(logs0[0]["topics"][1], self.address_to_topic(sender)) assert_equal(logs0[0]["data"], self.address_to_topic(sender)) # call method receipt = self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()"))) # apply filter, we expect two logs with 2 and 3 topics respectively filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs1 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs1) assert_equal(len(logs1), 2) assert_equal(logs1[0], logs0[0]) assert_equal(len(logs1[1]["topics"]), 3) assert_equal(logs1[1]["topics"][0], CALLED_TOPIC) assert_equal(logs1[1]["topics"][1], self.address_to_topic(sender)) assert_equal(logs1[1]["topics"][2], self.number_to_topic(1)) # apply filter for specific block, we expect a single log with 3 topics filter = Filter(block_hashes=[receipt["blockHash"]]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) assert_equal(logs[0], logs1[1]) # call many times for ii in range(0, NUM_CALLS - 2): self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()"))) # apply filter, we expect NUM_CALLS log entries with inreasing uint32 fields filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) for ii in range(2, NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii)) # apply filter for specific topics filter = Filter(topics=[CONSTRUCTED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) filter = Filter(topics=[CALLED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS - 1) filter = Filter(topics=[None, self.address_to_topic(sender)]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) # find logs with `CALLED_TOPIC` as 1st topic and `3` or `4` as 3rd topic filter = Filter(topics=[ CALLED_TOPIC, None, [self.number_to_topic(3), self.number_to_topic(4)] ]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 2) # apply filter with limit filter = Filter(limit=("0x%x" % (NUM_CALLS // 2))) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS // 2) # apply filter for specific contract address _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode) filter = Filter(address=[contractAddr]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) filter = Filter(address=[contractAddr2]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) # apply filter to very first epoch, we expect no logs filter = Filter(from_epoch="0x0", to_epoch="0x0") result = self.rpc.get_logs(filter) assert_equal(result, []) self.log.info("Pass")
class CrossSpaceLogFilteringTest(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 1 self.conf_parameters["evm_chain_id"] = str(10) self.conf_parameters["evm_transaction_block_ratio"] = str(1) def setup_network(self): self.add_nodes(self.num_nodes) self.start_node(0, ["--archive"]) self.rpc = RpcClient(self.nodes[0]) ip = self.nodes[0].ip port = self.nodes[0].rpcport self.w3 = Web3(Web3.HTTPProvider(f'http://{ip}:{port}/')) assert_equal(self.w3.isConnected(), True) def run_test(self): # initialize Conflux account self.cfxPrivkey = default_config['GENESIS_PRI_KEY'] self.cfxAccount = self.rpc.GENESIS_ADDR print(f'Using Conflux account {self.cfxAccount}') # initialize EVM account self.evmAccount = self.w3.eth.account.privateKeyToAccount( '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' ) print(f'Using EVM account {self.evmAccount.address}') self.cross_space_transfer(self.evmAccount.address, 1 * 10**18) assert_equal(self.nodes[0].eth_getBalance(self.evmAccount.address), hex(1 * 10**18)) # deploy Conflux space contract confluxContractAddr = self.deploy_conflux_space(CONFLUX_CONTRACT_PATH) print(f'Conflux contract: {confluxContractAddr}') # deploy EVM space contract evmContractAddr = self.deploy_evm_space(EVM_CONTRACT_PATH) print(f'EVM contract: {evmContractAddr}') # --- # .-----------------| D |.... # V --- | # --- --- --- --- # ... <-- | A | <- | B | <- | C | <- | E | <- ... # --- --- --- --- # # A --- B --- C --- D --- E # block number 0 | 1 | 2 | 3 | 4 | # epoch number 0 | 1 | 2 | 3 | cfx_next_nonce = self.rpc.get_nonce(self.cfxAccount) cfx_tx_hashes = [] evm_next_nonce = self.w3.eth.getTransactionCount( self.evmAccount.address) evm_tx_hashes = [] def emitConflux(n): nonlocal cfx_next_nonce, cfx_tx_hashes data_hex = (encode_hex_0x(keccak(b"emitConflux(uint256)"))[:10] + encode_u256(n)) tx = self.rpc.new_contract_tx(receiver=confluxContractAddr, data_hex=data_hex, nonce=cfx_next_nonce, sender=self.cfxAccount, priv_key=self.cfxPrivkey) cfx_next_nonce += 1 cfx_tx_hashes.append(tx.hash_hex()) return tx def emitBoth(n): nonlocal cfx_next_nonce, cfx_tx_hashes data_hex = encode_hex_0x( keccak(b"emitBoth(uint256,bytes20)"))[:10] + encode_u256( n) + encode_bytes20(evmContractAddr.replace('0x', '')) tx = self.rpc.new_contract_tx(receiver=confluxContractAddr, data_hex=data_hex, nonce=cfx_next_nonce, sender=self.cfxAccount, priv_key=self.cfxPrivkey) cfx_next_nonce += 1 cfx_tx_hashes.append(tx.hash_hex()) return tx def emitEVM(n): nonlocal evm_next_nonce, evm_tx_hashes data_hex = (encode_hex_0x(keccak(b"emitEVM(uint256)"))[:10] + encode_u256(n)) tx, hash = self.construct_evm_tx(receiver=evmContractAddr, data_hex=data_hex, nonce=evm_next_nonce) evm_next_nonce += 1 evm_tx_hashes.append(hash) return tx # generate ledger block_0 = self.rpc.block_by_epoch("latest_mined")['hash'] block_a = self.rpc.generate_custom_block(parent_hash=block_0, referee=[], txs=[ emitConflux(11), emitBoth(12), emitEVM(13), ]) block_b = self.rpc.generate_custom_block(parent_hash=block_a, referee=[], txs=[ emitConflux(14), emitBoth(15), emitEVM(16), ]) block_c = self.rpc.generate_custom_block(parent_hash=block_b, referee=[], txs=[]) block_d = self.rpc.generate_custom_block(parent_hash=block_a, referee=[], txs=[ emitConflux(21), emitBoth(22), emitEVM(23), ]) block_e = self.rpc.generate_custom_block(parent_hash=block_c, referee=[block_d], txs=[ emitConflux(24), emitBoth(25), emitEVM(26), ]) epoch_a = self.rpc.block_by_hash(block_a)['epochNumber'] epoch_b = self.rpc.block_by_hash(block_b)['epochNumber'] epoch_e = self.rpc.block_by_hash(block_e)['epochNumber'] # make sure transactions have been executed parent_hash = block_e for _ in range(5): block = self.rpc.generate_custom_block(parent_hash=parent_hash, referee=[], txs=[]) parent_hash = block for h in cfx_tx_hashes: receipt = self.rpc.get_transaction_receipt(h) assert_equal(receipt["outcomeStatus"], "0x0") for h in evm_tx_hashes: receipt = self.w3.eth.waitForTransactionReceipt(h) assert_equal(receipt["status"], 1) # check Conflux events filter = Filter(topics=[TEST_EVENT_TOPIC], from_epoch=epoch_a, to_epoch=epoch_e) logs = self.rpc.get_logs(filter) assert_equal(len(logs), 8) # --------------- 1 block per epoch --------------- # check EVM events # we expect 4 events: #12, #13, #15, #16 filter = { "topics": [TEST_EVENT_TOPIC], "fromBlock": epoch_a, "toBlock": epoch_b } logs = self.nodes[0].eth_getLogs(filter) assert_equal(len(logs), 4) # emitBoth: TestEvent(12) assert_equal(logs[0]["data"], number_to_topic(12)) assert_equal(logs[0]["address"], evmContractAddr.lower()) assert_equal(logs[0]["blockHash"], block_a) assert_equal(logs[0]["blockNumber"], epoch_a) assert_equal(logs[0]["transactionHash"], cfx_tx_hashes[1]) # TODO: should use phantom tx here # assert_equal(logs[0]["logIndex"], '0x0') # assert_equal(logs[0]["transactionIndex"], '0x0') # assert_equal(logs[0]["transactionLogIndex"], '0x0') assert_equal(logs[0]["removed"], False) # emitEVM: TestEvent(13) assert_equal(logs[1]["data"], number_to_topic(13)) assert_equal(logs[1]["address"], evmContractAddr.lower()) assert_equal(logs[1]["blockHash"], block_a) assert_equal(logs[1]["blockNumber"], epoch_a) assert_equal(logs[1]["transactionHash"], evm_tx_hashes[0].hex()) # assert_equal(logs[1]["logIndex"], '0x1') # assert_equal(logs[1]["transactionIndex"], '0x1') assert_equal(logs[1]["transactionLogIndex"], '0x0') assert_equal(logs[1]["removed"], False) # emitBoth: TestEvent(15) assert_equal(logs[2]["data"], number_to_topic(15)) assert_equal(logs[2]["address"], evmContractAddr.lower()) assert_equal(logs[2]["blockHash"], block_b) assert_equal(logs[2]["blockNumber"], epoch_b) assert_equal(logs[2]["transactionHash"], cfx_tx_hashes[3]) # TODO: should use phantom tx here # assert_equal(logs[2]["logIndex"], '0x0') # assert_equal(logs[2]["transactionIndex"], '0x0') # assert_equal(logs[2]["transactionLogIndex"], '0x0') assert_equal(logs[2]["removed"], False) # emitEVM: TestEvent(16) assert_equal(logs[3]["data"], number_to_topic(16)) assert_equal(logs[3]["address"], evmContractAddr.lower()) assert_equal(logs[3]["blockHash"], block_b) assert_equal(logs[3]["blockNumber"], epoch_b) assert_equal(logs[3]["transactionHash"], evm_tx_hashes[1].hex()) # assert_equal(logs[3]["logIndex"], '0x1') # assert_equal(logs[3]["transactionIndex"], '0x1') assert_equal(logs[3]["transactionLogIndex"], '0x0') assert_equal(logs[3]["removed"], False) # --------------- 2 blocks per epoch --------------- # check EVM events # we expect 4 events: #22, #23, #25, #26 filter = { "topics": [TEST_EVENT_TOPIC], "fromBlock": epoch_e, "toBlock": epoch_e } logs = self.nodes[0].eth_getLogs(filter) assert_equal(len(logs), 4) # emitBoth: TestEvent(22) assert_equal(logs[0]["data"], number_to_topic(22)) assert_equal(logs[0]["address"], evmContractAddr.lower()) assert_equal(logs[0]["blockHash"], block_e) assert_equal(logs[0]["blockNumber"], epoch_e) assert_equal(logs[0]["transactionHash"], cfx_tx_hashes[5]) # TODO: should use phantom tx here # assert_equal(logs[0]["logIndex"], '0x0') # assert_equal(logs[0]["transactionIndex"], '0x0') # assert_equal(logs[0]["transactionLogIndex"], '0x0') assert_equal(logs[0]["removed"], False) # emitEVM: TestEvent(23) assert_equal(logs[1]["data"], number_to_topic(23)) assert_equal(logs[1]["address"], evmContractAddr.lower()) assert_equal(logs[1]["blockHash"], block_e) assert_equal(logs[1]["blockNumber"], epoch_e) assert_equal(logs[1]["transactionHash"], evm_tx_hashes[2].hex()) # assert_equal(logs[1]["logIndex"], '0x1') # assert_equal(logs[1]["transactionIndex"], '0x1') assert_equal(logs[1]["transactionLogIndex"], '0x0') assert_equal(logs[1]["removed"], False) # emitBoth: TestEvent(25) assert_equal(logs[2]["data"], number_to_topic(25)) assert_equal(logs[2]["address"], evmContractAddr.lower()) assert_equal(logs[2]["blockHash"], block_e) assert_equal(logs[2]["blockNumber"], epoch_e) assert_equal(logs[2]["transactionHash"], cfx_tx_hashes[7]) # TODO: should use phantom tx here # assert_equal(logs[2]["logIndex"], '0x2') # assert_equal(logs[2]["transactionIndex"], '0x2') # assert_equal(logs[2]["transactionLogIndex"], '0x0') assert_equal(logs[2]["removed"], False) # emitEVM: TestEvent(26) assert_equal(logs[3]["data"], number_to_topic(26)) assert_equal(logs[3]["address"], evmContractAddr.lower()) assert_equal(logs[3]["blockHash"], block_e) assert_equal(logs[3]["blockNumber"], epoch_e) assert_equal(logs[3]["transactionHash"], evm_tx_hashes[3].hex()) # assert_equal(logs[3]["logIndex"], '0x3') # assert_equal(logs[3]["transactionIndex"], '0x3') assert_equal(logs[3]["transactionLogIndex"], '0x0') assert_equal(logs[3]["removed"], False) # --------------- other fields --------------- # filter by block hash filter = {"topics": [TEST_EVENT_TOPIC], "blockHash": block_c} logs_2 = self.nodes[0].eth_getLogs(filter) assert_equal(logs_2, []) filter = { "topics": [TEST_EVENT_TOPIC], "blockHash": block_d } # from EVM perspective, D does not exist assert_raises_rpc_error(None, None, self.nodes[0].eth_getLogs, filter) filter = {"topics": [TEST_EVENT_TOPIC], "blockHash": block_e} logs_2 = self.nodes[0].eth_getLogs(filter) assert_equal(logs_2, logs) # filter limit filter = { "topics": [TEST_EVENT_TOPIC], "blockHash": block_e, "limit": 1 } logs_2 = self.nodes[0].eth_getLogs(filter) assert_equal(logs_2, [logs[-1]]) # "earliest", "latest" filter = { "topics": [TEST_EVENT_TOPIC], "fromBlock": "earliest", "toBlock": "latest" } logs_2 = self.nodes[0].eth_getLogs(filter) assert_equal(len(logs_2), 8) filter = { "topics": [TEST_EVENT_TOPIC], "fromBlock": "earliest", "toBlock": "latest", "limit": 4 } logs_2 = self.nodes[0].eth_getLogs(filter) assert_equal(logs_2, logs) # address filter = {"address": confluxContractAddr} logs_2 = self.nodes[0].eth_getLogs(filter) assert_equal(logs_2, []) filter = {"address": evmContractAddr} logs_2 = self.nodes[0].eth_getLogs(filter) assert_equal(len(logs_2), 8) self.log.info("Pass") def cross_space_transfer(self, to, value): to = to.replace('0x', '') tx = self.rpc.new_tx( value=value, receiver="0x0888000000000000000000000000000000000006", data=decode_hex(f"0xda8d5daf{to}000000000000000000000000"), nonce=self.rpc.get_nonce(self.cfxAccount), gas=1000000, ) self.rpc.send_tx(tx, True) def deploy_conflux_space(self, bytecode_path): bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), bytecode_path) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() tx = self.rpc.new_contract_tx(receiver="", data_hex=bytecode, sender=self.cfxAccount, priv_key=self.cfxPrivkey, storage_limit=20000) assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex()) receipt = self.rpc.get_transaction_receipt(tx.hash_hex()) assert_equal(receipt["outcomeStatus"], "0x0") addr = receipt["contractCreated"] assert_is_hex_string(addr) return addr def deploy_evm_space(self, bytecode_path): bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), bytecode_path) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() nonce = self.w3.eth.getTransactionCount(self.evmAccount.address) signed = self.evmAccount.signTransaction({ "to": None, "value": 0, "gasPrice": 1, "gas": 210000, "nonce": nonce, "chainId": 10, "data": bytecode, }) tx_hash = signed["hash"] return_tx_hash = self.w3.eth.sendRawTransaction( signed["rawTransaction"]) assert_equal(tx_hash, return_tx_hash) self.rpc.generate_block(1) self.rpc.generate_blocks(20, 1) receipt = self.w3.eth.waitForTransactionReceipt(tx_hash) assert_equal(receipt["status"], 1) addr = receipt["contractAddress"] return addr def construct_evm_tx(self, receiver, data_hex, nonce): signed = self.evmAccount.signTransaction({ "to": receiver, "value": 0, "gasPrice": 1, "gas": 150000, "nonce": nonce, "chainId": 10, "data": data_hex, }) tx = [ nonce, 1, 150000, bytes.fromhex(receiver.replace('0x', '')), 0, bytes.fromhex(data_hex.replace('0x', '')), signed["v"], signed["r"], signed["s"] ] return tx, signed["hash"]
def run_test(self): sponsor_whitelist_contract_addr = Web3.toChecksumAddress( "0888000000000000000000000000000000000001") bytes_per_key = 64 collateral_per_storage_key = COLLATERAL_UNIT_IN_DRIP * 64 # change upper tx gas limit to (GENESIS_GAS_LIMIT/2 - 1); -1 because below gas is set to upper_bound + 1 tx_gas_upper_bound = int(default_config["GENESIS_GAS_LIMIT"] / 2 - 1) 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() (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=1536) 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), 1536 * COLLATERAL_UNIT_IN_DRIP) # 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="setSponsorForGas", args=[Web3.toChecksumAddress(contract_addr), tx_gas_upper_bound], value=tx_gas_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="setSponsorForGas", args=[Web3.toChecksumAddress(contract_addr), tx_gas_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), tx_gas_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=tx_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(tx_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="setSponsorForGas", args=[Web3.toChecksumAddress(contract_addr), tx_gas_upper_bound], 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="setSponsorForGas", args=[ Web3.toChecksumAddress(contract_addr), tx_gas_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), 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="setSponsorForGas", args=[ Web3.toChecksumAddress(contract_addr), tx_gas_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), tx_gas_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="setSponsorForCollateral", 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="setSponsorForCollateral", 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'], False) # 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="setSponsorForCollateral", 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="setSponsorForCollateral", 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="setSponsorForCollateral", 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): client = RpcClient(self.nodes[0]) self.test_throttled(client) self.test_recharged(client)
def new_client(rpc_url): return RpcClient(node=get_simple_rpc_proxy(rpc_url, timeout=10))
def run_test(self): file_dir = os.path.dirname(os.path.realpath(__file__)) erc20_contract = get_contract_instance( abi_file=os.path.join(file_dir, "contracts/erc20_abi.json"), bytecode_file=os.path.join(file_dir, "contracts/erc20_bytecode.dat"), ) gas_price = 1 gas = CONTRACT_DEFAULT_GAS start_p2p_connection(self.nodes) self.log.info("Initializing contract") genesis_key = default_config["GENESIS_PRI_KEY"] genesis_addr = encode_hex_0x(priv_to_addr(genesis_key)) nonce = 0 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 } raw_create = erc20_contract.constructor().buildTransaction( self.tx_conf) tx_data = decode_hex(raw_create["data"]) tx_create = create_transaction(pri_key=genesis_key, receiver=b'', nonce=nonce, gas_price=gas_price, data=tx_data, gas=gas, value=0, storage_limit=3382) client = RpcClient(self.nodes[0]) c0 = client.get_collateral_for_storage(genesis_addr) client.send_tx(tx_create, True) receipt = client.get_transaction_receipt(tx_create.hash_hex()) c1 = client.get_collateral_for_storage(genesis_addr) assert_equal(c1 - c0, 3382 * 10**18 / 1024) contract_addr = receipt['contractCreated'] self.log.info("Contract " + str(contract_addr) + " created, start transferring tokens") tx_n = 10 self.tx_conf["to"] = contract_addr nonce += 1 balance_map = {genesis_key: 1000000 * 10**18} sender_key = genesis_key all_txs = [] for i in range(tx_n): value = int((balance_map[sender_key] - ((tx_n - i) * 21000 * gas_price)) * random.random()) receiver_sk, _ = ec_random_keys() balance_map[receiver_sk] = value tx_data = decode_hex( erc20_contract.functions.transfer( Web3.toChecksumAddress( encode_hex(priv_to_addr(receiver_sk))), value).buildTransaction(self.tx_conf)["data"]) tx = create_transaction(pri_key=sender_key, receiver=decode_hex(self.tx_conf["to"]), value=0, nonce=nonce, gas=gas, gas_price=gas_price, data=tx_data, storage_limit=64) r = random.randint(0, self.num_nodes - 1) self.nodes[r].p2p.send_protocol_msg( Transactions(transactions=[tx])) nonce += 1 balance_map[sender_key] -= value all_txs.append(tx) self.log.info("Wait for transactions to be executed") self.wait_for_tx(all_txs) self.log.info("Check final token balance") for sk in balance_map: addr = priv_to_addr(sk) assert_equal(self.get_balance(erc20_contract, addr, nonce), balance_map[sk]) c2 = client.get_collateral_for_storage(genesis_addr) assert_equal(c2 - c1, 64 * tx_n * 10**18 / 1024) 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__)) 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 = client.get_balance(addr) 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 new_client(rpc_url): return RpcClient(node=get_rpc_proxy(rpc_url, 3))
def run_test(self): solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) staking_contract = solc.get_contract_instance( abi_file=os.path.join( file_dir, "contracts/storage_interest_staking_abi.json"), bytecode_file=os.path.join( file_dir, "contracts/storage_interest_staking_bytecode.dat"), ) staking_contract_addr = Web3.toChecksumAddress( "443c409373ffd5c0bec1dddb7bec830856757b65") self.problem = "0x2bc79b7514884ab00da924607d71542cc4fed3beb8518e747726ae30ab6c7944" self.solution = "0xc4d2751c52311d0d7efe44e5c4195e058ad5ef4bb89b3e1761b24dc277b132c2" self.priv_key = default_config["GENESIS_PRI_KEY"] self.sender = encode_hex_0x(privtoaddr(self.priv_key)) self.sender_checksum = Web3.toChecksumAddress(self.sender) self.pub = [] self.pri = [] self.rpc = RpcClient(self.nodes[0]) gas = 50000000 gas_price = 10 # lock token for genesis account self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.tx_conf['to'] = staking_contract_addr tx_data = decode_hex( staking_contract.functions.deposit( 1000000 * 10**18).buildTransaction(self.tx_conf)["data"]) tx = self.rpc.new_tx(value=0, receiver=staking_contract_addr, data=tx_data, gas=gas, gas_price=gas_price) self.rpc.send_tx(tx, True) for i in range(10): priv_key = random.randint(0, 2**256).to_bytes(32, "big") pub_key = encode_hex_0x(privtoaddr(priv_key)) self.pub.append(pub_key) self.pri.append(priv_key) transaction = self.rpc.new_tx(sender=self.sender, receiver=pub_key, value=1000000 * 10**18, priv_key=self.priv_key) self.rpc.send_tx(transaction, True) # deposit 10000 tokens tx_data = decode_hex( staking_contract.functions.deposit( 10000 * 10**18).buildTransaction(self.tx_conf)["data"]) tx = self.rpc.new_tx(value=0, sender=pub_key, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key) self.rpc.send_tx(tx) self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.filter = Filter(from_epoch="earliest", to_epoch="latest_mined") self.testEventContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testBallotContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testPayContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testHTLCContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testDaiContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testMappingContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testDaiJoinContract() self.log.info("Pass")
class ContractBenchTest(SmartContractBenchBase): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 1 def setup_network(self): self.setup_nodes() def testEventContract(self): CONTRACT_PATH = "contracts/event_bytecode_new.dat" logs = self.rpc.get_logs(self.filter) l = len(logs) # deploy 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().strip() receipt, contractAddr = self.deploy_contract(self.sender, self.priv_key, bytecode) contractAddr = Web3.toChecksumAddress(contractAddr) logs = self.rpc.get_logs(self.filter) assert_equal(len(logs), l + 1) # construct contract object solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) contract = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/event_abi_new.json"), bytecode_file=os.path.join(file_dir, CONTRACT_PATH), ) self.tx_conf["to"] = contractAddr # interact with foo() data = contract.functions.foo().buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) logs = self.rpc.get_logs(self.filter) assert_equal(len(logs), l + 2) assert_equal(logs[-1]["topics"][1], self.address_to_topic(self.sender)) assert_equal(logs[-1]["topics"][2], self.number_to_topic(1)) # interact with goo(10), will pass modifier, emit new event data = contract.functions.goo(10).buildTransaction( self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) logs = self.rpc.get_logs(self.filter) assert_equal(len(logs), l + 3) assert_equal(logs[-1]["topics"][1], self.address_to_topic(self.sender)) assert_equal(logs[-1]["topics"][2], self.number_to_topic(11)) # interact with goo(10), will not pass modifier, no event emitted data = contract.functions.goo(10).buildTransaction( self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) logs = self.rpc.get_logs(self.filter) assert_equal(len(logs), l + 3) # call const function hoo() data = contract.functions.hoo().buildTransaction(self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert_equal(result, self.number_to_topic(11)) # call const function byte32oo(solution) data = contract.functions.byte32oo(self.solution).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert_equal(result, self.solution) # call const function getSha256(solution) data = contract.functions.getSha256(self.solution).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert_equal(result, self.problem) def testBallotContract(self): CONTRACT_PATH = "contracts/ballot_bytecode.dat" logs = self.rpc.get_logs(self.filter) l = len(logs) # construct contract object solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) contract = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/ballot_abi.json"), bytecode_file=os.path.join(file_dir, CONTRACT_PATH), ) # deploy contract data = contract.constructor(10).buildTransaction(self.tx_conf)["data"] receipt, contractAddr = self.deploy_contract(self.sender, self.priv_key, data) contractAddr = Web3.toChecksumAddress(contractAddr) self.tx_conf["to"] = contractAddr # interact with vote() data = contract.functions.vote(5).buildTransaction( self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) logs = self.rpc.get_logs(self.filter) assert_equal(len(logs), l + 1) assert_equal(logs[-1]["data"], self.number_to_topic(5)) # call const function winningProposal() data = contract.functions.winningProposal().buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert_equal(result, self.number_to_topic(5)) def testHTLCContract(self): CONTRACT_PATH = "contracts/htlc_bytecode_new.dat" logs = self.rpc.get_logs(self.filter) l = len(logs) # construct contract object solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) contract = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/htlc_abi_new.json"), bytecode_file=os.path.join(file_dir, CONTRACT_PATH), ) # deploy contract data = contract.constructor().buildTransaction(self.tx_conf)["data"] receipt, contractAddr = self.deploy_contract(self.sender, self.priv_key, data) tx_hash = receipt['transactionHash'] contractAddr = Web3.toChecksumAddress(contractAddr) self.tx_conf["to"] = contractAddr logs = self.rpc.get_logs(self.filter) assert_equal(len(logs), l + 1) assert_equal(logs[-1]["topics"][1], self.address_to_topic(self.sender)) assert_equal(logs[-1]["topics"][2], self.number_to_topic(16)) # call getNow() data = contract.functions.getNow().buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert (int(result, 0) - int(time.time()) < 5) b0 = self.rpc.get_balance(self.sender) fee = 10000000 # interact with newContract(), sender send conflux to himself time_lock = int(time.time()) + 7200 data = contract.functions.newContract( self.sender_checksum, self.problem, time_lock).buildTransaction(self.tx_conf)["data"] cost = 5000000000000000000 result = self.call_contract(self.sender, self.priv_key, contractAddr, data, cost) logs = self.rpc.get_logs(self.filter) assert_equal(len(logs), l + 2) assert_equal(self.rpc.get_balance(contractAddr), cost) assert_greater_than_or_equal(self.rpc.get_balance(self.sender), b0 - cost - fee) contract_id = logs[-1]["topics"][1] # call getContract cid0 = contract_id data = contract.functions.getContract(contract_id).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) result = result[2:] res = ['0x' + result[i * 64:(i + 1) * 64] for i in range(8)] assert_equal(res[0][-20:], self.sender[-20:]) assert_equal(res[1][-20:], self.sender[-20:]) assert_equal(int(res[2], 0), cost) assert_equal(res[3], self.problem) assert_equal(int(res[4], 0), time_lock) assert_equal(int(res[5], 0), 0) assert_equal(int(res[6], 0), 0) assert_equal(int(res[7], 0), 0) # interact with withdraw() data = contract.functions.withdraw( contract_id, self.solution).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) assert_equal(self.rpc.get_balance(contractAddr), 0) assert_greater_than_or_equal(self.rpc.get_balance(self.sender), b0 - fee * 2) logs = self.rpc.get_logs(self.filter) assert_equal(len(logs), l + 3) # call getContract data = contract.functions.getContract(contract_id).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) result = result[2:] res = ['0x' + result[i * 64:(i + 1) * 64] for i in range(8)] assert_equal(res[0][-20:], self.sender[-20:]) assert_equal(res[1][-20:], self.sender[-20:]) assert_equal(int(res[2], 0), cost) assert_equal(res[3], self.problem) assert_equal(int(res[4], 0), time_lock) assert_equal(int(res[5], 0), 1) assert_equal(int(res[6], 0), 0) assert_equal(res[7], self.solution) receipt = self.rpc.get_transaction_receipt(tx_hash) def testPayContract(self): CONTRACT_PATH = "contracts/pay_bytecode.dat" logs = self.rpc.get_logs(self.filter) l = len(logs) # construct contract object solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) contract = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/pay_abi.json"), bytecode_file=os.path.join(file_dir, CONTRACT_PATH), ) # deploy contract data = contract.constructor().buildTransaction(self.tx_conf)["data"] receipt, contractAddr = self.deploy_contract(self.sender, self.priv_key, data) contractAddr = Web3.toChecksumAddress(contractAddr) self.tx_conf["to"] = contractAddr logs = self.rpc.get_logs(self.filter) l = len(logs) b0 = self.rpc.get_balance(self.sender) # interact with recharge() data = contract.functions.recharge().buildTransaction( self.tx_conf)["data"] cost = 5000000000000000000 result = self.call_contract(self.sender, self.priv_key, contractAddr, data, cost) b1 = self.rpc.get_balance(self.sender) bc = self.rpc.get_balance(contractAddr) assert_equal(bc, cost) #interact with withdraw data = contract.functions.withdraw( self.sender_checksum).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data, 0) b2 = self.rpc.get_balance(self.sender) bc = self.rpc.get_balance(contractAddr) logs = self.rpc.get_logs(self.filter) assert_equal(bc, 0) def testMappingContract(self): CONTRACT_PATH = "contracts/mapping_bytecode.dat" logs = self.rpc.get_logs(self.filter) l = len(logs) # construct contract object solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) contract = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/mapping_abi.json"), bytecode_file=os.path.join(file_dir, CONTRACT_PATH), ) # deploy contract data = contract.constructor(1).buildTransaction(self.tx_conf)["data"] receipt, contractAddr = self.deploy_contract(self.sender, self.priv_key, data) tx_hash = receipt['transactionHash'] contractAddr = Web3.toChecksumAddress(contractAddr) self.tx_conf["to"] = contractAddr c = "0x81f3521d71990945b99e1c592750d7157f2b545f" def check_wards(x, y, z): data = contract.functions.wards(Web3.toChecksumAddress( self.pub[0])).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) A = int(result, 0) assert (A == x) data = contract.functions.wards( self.sender_checksum).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) B = int(result, 0) assert (B == y) data = contract.functions.wards( Web3.toChecksumAddress(c)).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) C = int(result, 0) assert (C == z) # deny pub[0] check_wards(0, 2, 0) data = contract.functions.set1( Web3.toChecksumAddress(c)).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) check_wards(0, 2, 1) data = contract.functions.set2(Web3.toChecksumAddress( self.pub[0])).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) check_wards(2, 2, 1) data = contract.functions.set0( Web3.toChecksumAddress(c)).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) check_wards(2, 2, 0) data = contract.functions.set0(Web3.toChecksumAddress( self.pub[0])).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) check_wards(0, 2, 0) def testDaiContract(self): CONTRACT_PATH = "contracts/Dai_bytecode.dat" logs = self.rpc.get_logs(self.filter) l = len(logs) # construct contract object solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) contract = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/Dai_abi.json"), bytecode_file=os.path.join(file_dir, CONTRACT_PATH), ) # deploy contract data = contract.constructor(1).buildTransaction(self.tx_conf)["data"] receipt, contractAddr = self.deploy_contract(self.sender, self.priv_key, data) tx_hash = receipt['transactionHash'] contractAddr = Web3.toChecksumAddress(contractAddr) self.tx_conf["to"] = contractAddr # rely [0,5) for i in range(5): data = contract.functions.rely(Web3.toChecksumAddress( self.pub[i])).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data, 0) assert_equal(result["outcomeStatus"], 0) # deny 1, 3 for i in range(5): if (i % 2 == 1): data = contract.functions.deny( Web3.toChecksumAddress(self.pub[i])).buildTransaction( self.tx_conf)["data"] result = self.call_contract(self.pub[i - 1], self.pri[i - 1], contractAddr, data, 0) assert_equal(result["outcomeStatus"], 0) # check wards for i in range(5): data = contract.functions.wards(Web3.toChecksumAddress( self.pub[i])).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert_equal(int(result, 0), int(i % 2 == 0)) # mint tokens data = contract.functions.mint(Web3.toChecksumAddress( self.pub[0]), 100000).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data, 0) logs = self.rpc.get_logs(self.filter) # check balance data = contract.functions.balanceOf(Web3.toChecksumAddress( self.pub[0])).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert (int(result, 0) == 100000) # approve data = contract.functions.approve( self.sender_checksum, 50000).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.pub[0], self.pri[0], contractAddr, data) logs = self.rpc.get_logs(self.filter) # check allowance data = contract.functions.allowance( Web3.toChecksumAddress(self.pub[0]), self.sender_checksum).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert (int(result, 0) == 50000) # insufficient balance data = contract.functions.transfer(self.sender_checksum, 200000).buildTransaction( self.tx_conf)["data"] result = self.call_contract(self.pub[0], self.pri[0], contractAddr, data) assert (result["outcomeStatus"] != 0) # insuffcient allowance data = contract.functions.transferFrom( Web3.toChecksumAddress(self.pub[0]), self.sender_checksum, 10000).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.pub[1], self.pri[1], contractAddr, data) assert (result["outcomeStatus"] != 0) # transfer 50000 use allowance data = contract.functions.transferFrom( Web3.toChecksumAddress(self.pub[0]), Web3.toChecksumAddress(self.pub[1]), 50000).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, contractAddr, data) assert (result["outcomeStatus"] == 0) # get digest and sign it ts = int(time.time()) + 7200 data = contract.functions.getHash(Web3.toChecksumAddress(self.pub[0]), Web3.toChecksumAddress(self.pub[1]), 0, ts, True).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) v, r, s = ecsign(bytes.fromhex(result[2:]), self.pri[0]) r = self.fixto64(hex(r)) s = self.fixto64(hex(s)) assert (len(r) == 66) assert (len(s) == 66) # premit data = contract.functions.permit( Web3.toChecksumAddress(self.pub[0]), Web3.toChecksumAddress(self.pub[1]), 0, ts, True, v, r, s).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.pub[5], self.pri[5], contractAddr, data) assert (result["outcomeStatus"] == 0) # check allowance data = contract.functions.allowance( Web3.toChecksumAddress(self.pub[0]), self.sender_checksum).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert (int(result, 0) == 0) data = contract.functions.allowance( Web3.toChecksumAddress(self.pub[0]), Web3.toChecksumAddress(self.pub[1])).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert ( result == '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' ) # burn pub[0] data = contract.functions.burn(Web3.toChecksumAddress( self.pub[0]), 50000).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.pub[1], self.pri[1], contractAddr, data) assert (result["outcomeStatus"] == 0) # check balance data = contract.functions.balanceOf(Web3.toChecksumAddress( self.pub[0])).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert (int(result, 0) == 0) data = contract.functions.balanceOf(Web3.toChecksumAddress( self.pub[1])).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert (int(result, 0) == 50000) data = contract.functions.totalSupply().buildTransaction( self.tx_conf)["data"] result = self.rpc.call(contractAddr, data) assert (int(result, 0) == 50000) def testDaiJoinContract(self): solc = Solc() CONTRACT_PATH = "contracts/Dai_bytecode.dat" file_dir = os.path.dirname(os.path.realpath(__file__)) dai = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/Dai_abi.json"), bytecode_file=os.path.join(file_dir, CONTRACT_PATH), ) data = dai.constructor(1).buildTransaction(self.tx_conf)["data"] receipt, contractAddr = self.deploy_contract(self.sender, self.priv_key, data) dai_addr = Web3.toChecksumAddress(contractAddr) CONTRACT_PATH = "contracts/Vat_bytecode.dat" file_dir = os.path.dirname(os.path.realpath(__file__)) vat = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/Vat_abi.json"), bytecode_file=os.path.join(file_dir, CONTRACT_PATH), ) data = vat.constructor().buildTransaction(self.tx_conf)["data"] receipt, contractAddr = self.deploy_contract(self.sender, self.priv_key, data) vat_addr = Web3.toChecksumAddress(contractAddr) CONTRACT_PATH = "contracts/DaiJoin_bytecode.dat" file_dir = os.path.dirname(os.path.realpath(__file__)) dai_join = solc.get_contract_instance( abi_file=os.path.join(file_dir, "contracts/DaiJoin_abi.json"), bytecode_file=os.path.join(file_dir, CONTRACT_PATH), ) data = dai_join.constructor(vat_addr, dai_addr).buildTransaction( self.tx_conf)["data"] receipt, contractAddr = self.deploy_contract(self.sender, self.priv_key, data) dai_join_addr = Web3.toChecksumAddress(contractAddr) # mint dai tokens & give approval self.tx_conf["to"] = dai_addr data = dai.functions.mint(Web3.toChecksumAddress( self.pub[0]), 100000).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, dai_addr, data, 0) assert (result["outcomeStatus"] == 0) data = dai.functions.approve(dai_join_addr, 100000).buildTransaction( self.tx_conf)["data"] result = self.call_contract(self.pub[0], self.pri[0], dai_addr, data, 0) assert (result["outcomeStatus"] == 0) data = dai.functions.allowance(Web3.toChecksumAddress( self.pub[0]), dai_join_addr).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(dai_addr, data) assert_equal(int(result, 0), 100000) data = dai.functions.rely(dai_join_addr).buildTransaction( self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, dai_addr, data, 0) assert (result["outcomeStatus"] == 0) # mint dai tokens for join_addr in vat & add approval self.tx_conf["to"] = vat_addr data = vat.functions.mint( dai_join_addr, 100000000000).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.sender, self.priv_key, vat_addr, data, 0) assert (result["outcomeStatus"] == 0) data = vat.functions.hope(dai_join_addr).buildTransaction( self.tx_conf)["data"] result = self.call_contract(self.pub[0], self.pri[0], vat_addr, data, 0) assert (result["outcomeStatus"] == 0) data = vat.functions.balanceOf(dai_join_addr).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(vat_addr, data) assert_equal(int(result, 0), 100000000000) # join self.tx_conf["to"] = dai_join_addr data = dai_join.functions.join(Web3.toChecksumAddress( self.pub[0]), 50000).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.pub[0], self.pri[0], dai_join_addr, data, 0) assert (result["outcomeStatus"] == 0) # check self.tx_conf["to"] = dai_addr data = dai.functions.balanceOf(Web3.toChecksumAddress( self.pub[0])).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(dai_addr, data) assert_equal(int(result, 0), 50000) self.tx_conf["to"] = vat_addr data = vat.functions.can(dai_join_addr, Web3.toChecksumAddress( self.pub[0])).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(vat_addr, data) assert_equal(int(result, 0), 1) data = vat.functions.dai(Web3.toChecksumAddress( self.pub[0])).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(vat_addr, data) assert_equal(int(result, 0), 50000000000000000000000000000000) # exit self.tx_conf["to"] = dai_join_addr data = dai_join.functions.exit(Web3.toChecksumAddress( self.pub[0]), 50000).buildTransaction(self.tx_conf)["data"] result = self.call_contract(self.pub[0], self.pri[0], dai_join_addr, data, 0) assert (result["outcomeStatus"] == 0) # check self.tx_conf["to"] = dai_addr data = dai.functions.balanceOf(Web3.toChecksumAddress( self.pub[0])).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(dai_addr, data) assert_equal(int(result, 0), 100000) self.tx_conf["to"] = vat_addr data = vat.functions.can(dai_join_addr, Web3.toChecksumAddress( self.pub[0])).buildTransaction( self.tx_conf)["data"] result = self.rpc.call(vat_addr, data) assert_equal(int(result, 0), 0) data = vat.functions.dai(Web3.toChecksumAddress( self.pub[0])).buildTransaction(self.tx_conf)["data"] result = self.rpc.call(vat_addr, data) assert_equal(int(result, 0), 0) def run_test(self): solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) staking_contract = solc.get_contract_instance( abi_file=os.path.join( file_dir, "contracts/storage_interest_staking_abi.json"), bytecode_file=os.path.join( file_dir, "contracts/storage_interest_staking_bytecode.dat"), ) staking_contract_addr = Web3.toChecksumAddress( "443c409373ffd5c0bec1dddb7bec830856757b65") self.problem = "0x2bc79b7514884ab00da924607d71542cc4fed3beb8518e747726ae30ab6c7944" self.solution = "0xc4d2751c52311d0d7efe44e5c4195e058ad5ef4bb89b3e1761b24dc277b132c2" self.priv_key = default_config["GENESIS_PRI_KEY"] self.sender = encode_hex_0x(privtoaddr(self.priv_key)) self.sender_checksum = Web3.toChecksumAddress(self.sender) self.pub = [] self.pri = [] self.rpc = RpcClient(self.nodes[0]) gas = 50000000 gas_price = 10 # lock token for genesis account self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.tx_conf['to'] = staking_contract_addr tx_data = decode_hex( staking_contract.functions.deposit( 1000000 * 10**18).buildTransaction(self.tx_conf)["data"]) tx = self.rpc.new_tx(value=0, receiver=staking_contract_addr, data=tx_data, gas=gas, gas_price=gas_price) self.rpc.send_tx(tx, True) for i in range(10): priv_key = random.randint(0, 2**256).to_bytes(32, "big") pub_key = encode_hex_0x(privtoaddr(priv_key)) self.pub.append(pub_key) self.pri.append(priv_key) transaction = self.rpc.new_tx(sender=self.sender, receiver=pub_key, value=1000000 * 10**18, priv_key=self.priv_key) self.rpc.send_tx(transaction, True) # deposit 10000 tokens tx_data = decode_hex( staking_contract.functions.deposit( 10000 * 10**18).buildTransaction(self.tx_conf)["data"]) tx = self.rpc.new_tx(value=0, sender=pub_key, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key) self.rpc.send_tx(tx) self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.filter = Filter(from_epoch="earliest", to_epoch="latest_mined") self.testEventContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testBallotContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testPayContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testHTLCContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testDaiContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testMappingContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testDaiJoinContract() self.log.info("Pass") def address_to_topic(self, address): return "0x" + address[2:].zfill(64) def number_to_topic(self, number): return "0x" + ("%x" % number).zfill(64) 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) 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 call_contract(self, sender, priv_key, contract, data_hex, value=0): tx = self.rpc.new_contract_tx(receiver=contract, data_hex=data_hex, sender=sender, priv_key=priv_key, value=value) assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex()) receipt = self.rpc.get_transaction_receipt(tx.hash_hex()) return receipt def fixto64(self, x): return '0x' + ('0' * (66 - len(x))) + x[2:]
def run_test(self): start_p2p_connection(self.nodes) block_gen_thread = BlockGenThread(self.nodes, self.log) block_gen_thread.start() 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 = parse_as_int(self.nodes[0].cfx_getBalance(user1_addr_hex)) assert_equal(user1_balance, value) user2_balance_before_contract_construction = parse_as_int(self.nodes[0].cfx_getBalance(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 = parse_as_int(self.nodes[0].cfx_getBalance(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 = parse_as_int(self.nodes[0].cfx_getBalance(user1_addr_hex)) assert_greater_than_or_equal(user1_balance, 899999999999999999999999950000000) user2_balance_after_deposit = parse_as_int(self.nodes[0].cfx_getBalance(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 = parse_as_int(self.nodes[0].cfx_getBalance(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 = parse_as_int(self.nodes[0].cfx_getBalance(user1_addr_hex)) assert_greater_than_or_equal(user1_balance, 899999999999999999999999950000000) contract_balance = parse_as_int(self.nodes[0].cfx_getBalance(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 = parse_as_int(self.nodes[0].cfx_getBalance(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__)) 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].tx_inspect(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].tx_inspect(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")
def check_packed(): client = RpcClient(self.nodes[0]) client.generate_block(1) return checktx(self.nodes[0], tx.hash_hex())
def run_test(self): time.sleep(3) ip = self.nodes[0].ip port = self.nodes[0].ethrpcport self.w3 = Web3(Web3.HTTPProvider(f'http://{ip}:{port}/')) assert_equal(self.w3.isConnected(), True) account = self.w3.eth.account.privateKeyToAccount( '0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709' ) sender = account.address self.cross_space_transfer(sender, 1 * 10**18) assert_equal(1 * 10**18, self.w3.eth.get_balance(sender)) self.test_deploy_1820() # Send eip-155 transaction receiver = Web3.toChecksumAddress( "10000000000000000000000000000000000000aa") signed = account.signTransaction({ "to": receiver, "value": 1 * 10**17, "gasPrice": 1, "gas": 21000, "nonce": 0, "chainId": 10 }) tx_hash = signed["hash"] return_tx_hash = self.w3.eth.sendRawTransaction( signed["rawTransaction"]) assert_equal(tx_hash, return_tx_hash) client = RpcClient(self.nodes[0]) client.generate_block(1) client.generate_blocks(10) receipt = self.w3.eth.waitForTransactionReceipt(tx_hash) assert_equal(receipt["status"], 1) # Send pre eip-155 transaction signed = account.signTransaction({ "to": receiver, "value": 1 * 10**17, "gasPrice": 1, "gas": 21000, "nonce": 1 }) tx_hash = signed["hash"] return_tx_hash = self.w3.eth.sendRawTransaction( signed["rawTransaction"]) assert_equal(tx_hash, return_tx_hash) client.generate_block(1) client.generate_blocks(10) receipt = self.w3.eth.waitForTransactionReceipt(tx_hash) assert_equal(receipt["status"], 1) assert_equal(2 * 10**17, self.w3.eth.get_balance(receiver)) assert_equal(8 * 10**17 - 42000, self.w3.eth.get_balance(sender)) # Send to transaction mapped_sender = keccak_256(self.genesis_addr).digest()[-20:] receiver = Web3.toChecksumAddress(mapped_sender.hex()) signed = account.signTransaction({ "to": receiver, "value": 2 * 10**17, "gasPrice": 1, "gas": 21000, "nonce": 2 }) self.w3.eth.sendRawTransaction(signed["rawTransaction"]) client = RpcClient(self.nodes[0]) client.generate_block(1) client.generate_blocks(10) receipt = self.w3.eth.waitForTransactionReceipt(tx_hash) assert_equal(receipt["status"], 1) assert_equal(2 * 10**17, self.w3.eth.get_balance(mapped_sender)) # Withdraw transaction self.cross_space_withdraw(1 * 10**17) assert_equal(1 * 10**17, self.w3.eth.get_balance(mapped_sender)) # Send transaction with large chain-id, should not panic. signed = account.signTransaction({ "to": receiver, "value": 1 * 10**17, "gasPrice": 1, "gas": 21000, "nonce": 3, "chainId": 2**33 }) assert_raises(ValueError, self.w3.eth.sendRawTransaction, signed["rawTransaction"]) self.nodes[0].stop()
def run_test(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) self.rpc = RpcClient(self.nodes[0]) # apply filter, we expect no logs filter = Filter() result = self.rpc.get_logs(filter) assert_equal(result, []) # deploy 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() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) # apply filter, we expect a single log with 2 topics filter = Filter(from_epoch="earliest", to_epoch="latest_state") logs0 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs0) assert_equal(len(logs0), 1) assert_equal(len(logs0[0]["topics"]), 2) assert_equal(logs0[0]["topics"][0], CONSTRUCTED_TOPIC) assert_equal(logs0[0]["topics"][1], self.address_to_topic(sender)) assert_equal(logs0[0]["data"], self.address_to_topic(sender)) # call method receipt = self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=64) # apply filter, we expect two logs with 2 and 3 topics respectively filter = Filter(from_epoch="earliest", to_epoch="latest_state") logs1 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs1) assert_equal(len(logs1), 2) assert_equal(logs1[0], logs0[0]) assert_equal(len(logs1[1]["topics"]), 3) assert_equal(logs1[1]["topics"][0], CALLED_TOPIC) assert_equal(logs1[1]["topics"][1], self.address_to_topic(sender)) assert_equal(logs1[1]["topics"][2], self.number_to_topic(1)) # apply filter for specific block, we expect a single log with 3 topics filter = Filter(block_hashes=[receipt["blockHash"]]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) assert_equal(logs[0], logs1[1]) # call many times for ii in range(2, NUM_CALLS): self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=0) # apply filter, we expect NUM_CALLS log entries with increasing uint32 fields filter = Filter(from_epoch="earliest", to_epoch="latest_state") logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) for ii in range(2, NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii)) # apply filter for specific topics filter = Filter(topics=[CONSTRUCTED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) filter = Filter(topics=[CALLED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS - 1) filter = Filter(topics=[None, self.address_to_topic(sender)]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) # find logs with `CALLED_TOPIC` as 1st topic and `3` or `4` as 3rd topic filter = Filter(topics=[ CALLED_TOPIC, None, [self.number_to_topic(3), self.number_to_topic(4)] ]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 2) # apply filter with limit filter = Filter(limit=hex(NUM_CALLS // 2)) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS // 2) # apply filter for specific contract address _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode) filter = Filter(address=[contractAddr]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) filter = Filter(address=[contractAddr2]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) # apply filter to very first epoch, we expect no logs filter = Filter(from_epoch="earliest", to_epoch="earliest") result = self.rpc.get_logs(filter) assert_equal(result, []) # generate two blocks with `NUM_CALLS` valid logs in each parent_hash = self.rpc.block_by_epoch("latest_mined")['hash'] start_nonce = self.rpc.get_nonce(sender) txs = [ self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), sender=sender, priv_key=priv_key, storage_limit=64, nonce=start_nonce + ii) for ii in range(0, NUM_CALLS) ] block_hash_1 = self.rpc.generate_custom_block(parent_hash=parent_hash, referee=[], txs=txs) txs = [ self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), sender=sender, priv_key=priv_key, storage_limit=64, nonce=start_nonce + NUM_CALLS + ii) for ii in range(0, NUM_CALLS) ] block_hash_2 = self.rpc.generate_custom_block(parent_hash=block_hash_1, referee=[], txs=txs) # blocks not executed yet, filtering should fail filter = Filter(block_hashes=[block_hash_1, block_hash_2]) assert_raises_rpc_error(None, None, self.rpc.get_logs, filter) # generate some more blocks to ensure our two blocks are executed self.rpc.generate_blocks(10) # filtering for these two blocks should return logs in correct order filter = Filter(block_hashes=[block_hash_1, block_hash_2]) logs = self.rpc.get_logs(filter) assert_equal(len(logs), 2 * NUM_CALLS) for ii in range(0, 2 * NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii + NUM_CALLS)) # block hash order should not affect log order filter = Filter(block_hashes=[block_hash_2, block_hash_1]) logs2 = self.rpc.get_logs(filter) assert_equal(logs, logs2) # given a limit, we should receive the _last_ few logs filter = Filter(block_hashes=[block_hash_1, block_hash_2], limit=hex(NUM_CALLS + NUM_CALLS // 2)) logs = self.rpc.get_logs(filter) assert_equal(len(logs), NUM_CALLS + NUM_CALLS // 2) for ii in range(0, NUM_CALLS + NUM_CALLS // 2): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii + NUM_CALLS + NUM_CALLS // 2)) 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(node.cfx_getBalance(addr), hex(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(node.cfx_getBalance(contract_addr), hex(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): client = RpcClient(self.nodes[0]) # wait for the first epoch to end wait_until(lambda: client.pos_status()["latestVoted"] is not None) print(client.pos_status()) wait_until(lambda: int(client.pos_status()["latestCommitted"], 0) == 8) self.log.info("wait for empty rounds") self.stop_node(2) self.stop_node(3) time.sleep(5) self.start_node(2) self.start_node(3) self.log.info("restarts") print(client.pos_status()) # wait for the next epoch wait_until(lambda: int(client.pos_status()["epoch"], 0) == 2) parent = client.pos_get_block(2)["hash"] for v in range(3, 11): print(v) b = client.pos_get_block(v) assert_equal(b["parentHash"], parent) parent = b["hash"] wait_until(lambda: int(client.pos_status()["epoch"], 0) == 3) parent = client.pos_get_block(11)["hash"] for v in range(12, 21): print(v) b = client.pos_get_block(v) assert_equal(b["parentHash"], parent) parent = b["hash"] wait_until(lambda: client.pos_get_block(21) is not None) assert_equal(int(client.pos_get_block(21)["epoch"], 0), 3)
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, kill=True) genesis = self.nodes[0].cfx_getBlockByEpochNumber("0x0", False)["hash"] self.nodes[0].add_p2p_connection(P2PInterface(genesis)) 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 run_test(self): file_path = os.path.dirname(os.path.realpath(__file__)).split("/") file_path.pop(-1) file_path.extend(["internal_contract", "metadata", "Staking.json"]) file_path = "/".join(file_path) 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__)) 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")
def wait_for_txs(self, node, txs): client = RpcClient(node) for tx_hash in txs: while client.get_tx(tx_hash) is None: time.sleep(0.3)
class LogFilteringTest(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 1 def setup_network(self): self.setup_nodes() def run_test(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) self.rpc = RpcClient(self.nodes[0]) # apply filter, we expect no logs filter = Filter(from_epoch="earliest", to_epoch="latest_mined") result = self.rpc.get_logs(filter) assert_equal(result, []) # deploy 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() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) # apply filter, we expect a single log with 2 topics filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs0 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs0) assert_equal(len(logs0), 1) assert_equal(len(logs0[0]["topics"]), 2) assert_equal(logs0[0]["topics"][0], CONSTRUCTED_TOPIC) assert_equal(logs0[0]["topics"][1], self.address_to_topic(sender)) assert_equal(logs0[0]["data"], self.address_to_topic(sender)) # call method receipt = self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=64) # apply filter, we expect two logs with 2 and 3 topics respectively filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs1 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs1) assert_equal(len(logs1), 2) assert_equal(logs1[0], logs0[0]) assert_equal(len(logs1[1]["topics"]), 3) assert_equal(logs1[1]["topics"][0], CALLED_TOPIC) assert_equal(logs1[1]["topics"][1], self.address_to_topic(sender)) assert_equal(logs1[1]["topics"][2], self.number_to_topic(1)) # apply filter for specific block, we expect a single log with 3 topics filter = Filter(block_hashes=[receipt["blockHash"]]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) assert_equal(logs[0], logs1[1]) # call many times for ii in range(0, NUM_CALLS - 2): self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=0) # apply filter, we expect NUM_CALLS log entries with inreasing uint32 fields filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) for ii in range(2, NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii)) # apply filter for specific topics filter = Filter(topics=[CONSTRUCTED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) filter = Filter(topics=[CALLED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS - 1) filter = Filter(topics=[None, self.address_to_topic(sender)]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) # find logs with `CALLED_TOPIC` as 1st topic and `3` or `4` as 3rd topic filter = Filter(topics=[ CALLED_TOPIC, None, [self.number_to_topic(3), self.number_to_topic(4)] ]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 2) # apply filter with limit filter = Filter(limit=("0x%x" % (NUM_CALLS // 2))) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS // 2) # apply filter for specific contract address _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode) filter = Filter(address=[contractAddr]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) filter = Filter(address=[contractAddr2]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) # apply filter to very first epoch, we expect no logs filter = Filter(from_epoch="0x0", to_epoch="0x0") result = self.rpc.get_logs(filter) assert_equal(result, []) self.log.info("Pass") def address_to_topic(self, address): return "0x" + address[2:].zfill(64) def number_to_topic(self, number): return "0x" + ("%x" % number).zfill(64) def deploy_contract(self, sender, priv_key, data_hex): c0 = self.rpc.get_collateral_for_storage(sender) tx = self.rpc.new_contract_tx(receiver="", data_hex=data_hex, sender=sender, priv_key=priv_key, storage_limit=253) assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex()) receipt = self.rpc.get_transaction_receipt(tx.hash_hex()) assert_equal(receipt["outcomeStatus"], 0) address = receipt["contractCreated"] c1 = self.rpc.get_collateral_for_storage(sender) assert_equal(c1 - c0, 253 * 10**18 // 1024) assert_is_hex_string(address) return receipt, address def call_contract(self, sender, priv_key, contract, data_hex, storage_limit): c0 = self.rpc.get_collateral_for_storage(sender) tx = self.rpc.new_contract_tx(receiver=contract, data_hex=data_hex, sender=sender, priv_key=priv_key, storage_limit=storage_limit) assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex()) receipt = self.rpc.get_transaction_receipt(tx.hash_hex()) assert_equal(receipt["outcomeStatus"], 0) c1 = self.rpc.get_collateral_for_storage(sender) assert_equal(c1 - c0, storage_limit * 10**18 // 1024) return receipt def assert_response_format_correct(self, response): assert_equal(type(response), list) for log in response: self.assert_log_format_correct(log) def assert_log_format_correct(self, log): assert_is_hex_string(log["address"]) assert_is_hex_string(log["epochNumber"]) assert_is_hex_string(log["logIndex"]) assert_is_hex_string(log["transactionIndex"]) assert_is_hex_string(log["transactionLogIndex"]) assert_is_hash_string(log["blockHash"]) assert_is_hash_string(log["transactionHash"]) assert_equal(type(log["topics"]), list)
def run_test(self): num_nodes = len(self.nodes) if self.tx_propagation_enabled: # Setup balance for each node client = RpcClient(self.nodes[0]) for i in range(num_nodes): pub_key = self.nodes[i].key addr = self.nodes[i].addr self.log.info("%d has addr=%s pubkey=%s", i, encode_hex(addr), pub_key) tx = client.new_tx(value=int(default_config["TOTAL_COIN"]/(num_nodes + 1)) - 21000, receiver=encode_hex(addr), nonce=i) client.send_tx(tx) # setup monitor to report the current block count periodically cur_block_count = self.nodes[0].getblockcount() # The monitor will check the block_count of nodes[0] monitor_thread = threading.Thread(target=self.monitor, args=(cur_block_count, 100), daemon=True) monitor_thread.start() # generate blocks threads = {} rpc_times = [] for i in range(1, self.options.num_blocks + 1): wait_sec = random.expovariate(1000 / self.options.generation_period_ms) start = time.time() # find an idle node to generate block p = random.randint(0, num_nodes - 1) retry = 0 while retry < 10: pre_thread = threads.get(p) if pre_thread is not None and pre_thread.is_alive(): p = random.randint(0, num_nodes - 1) retry += 1 time.sleep(0.01) else: break if retry >= 10: self.log.warn("too many nodes are busy to generate block, stop to analyze logs.") break if self.tx_propagation_enabled: # Generate a block with the transactions in the node's local tx pool thread = SimpleGenerateThread(self.nodes, p, self.options.txs_per_block, self.options.generate_tx_data_len, self.log, rpc_times) else: # Generate a fixed-size block with fake tx thread = GenerateThread(self.nodes, p, self.options.txs_per_block, self.options.generate_tx_data_len, self.log, rpc_times) thread.start() threads[p] = thread if i % self.options.block_sync_step == 0: self.log.info("[PROGRESS] %d blocks generated async", i) elapsed = time.time() - start if elapsed < wait_sec: self.log.debug("%d generating block %.2f", p, elapsed) time.sleep(wait_sec - elapsed) else: self.log.warn("%d generating block slowly %.2f", p, elapsed) monitor_thread.join() self.sync_blocks() self.log.info("generateoneblock RPC latency: {}".format(Statistics(rpc_times, 3).__dict__)) self.log.info("Best block: {}".format(RpcClient(self.nodes[0]).best_block_hash()))
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].txpool_txWithPoolInfo(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): file_path = os.path.dirname(os.path.realpath(__file__)).split("/") file_path.pop(-1) file_path.extend(["internal_contract", "metadata", "Staking.json"]) file_path = "/".join(file_path) staking_contract_dict = json.loads( open(os.path.join(file_path), "r").read()) staking_contract = get_contract_instance( contract_dict=staking_contract_dict) staking_contract_addr = Web3.toChecksumAddress( "0888000000000000000000000000000000000002") self.problem = "0x2bc79b7514884ab00da924607d71542cc4fed3beb8518e747726ae30ab6c7944" self.solution = "0xc4d2751c52311d0d7efe44e5c4195e058ad5ef4bb89b3e1761b24dc277b132c2" self.priv_key = default_config["GENESIS_PRI_KEY"] self.sender = encode_hex_0x(priv_to_addr(self.priv_key)) self.sender_checksum = Web3.toChecksumAddress(self.sender) self.pub = [] self.pri = [] self.rpc = RpcClient(self.nodes[0]) gas = CONTRACT_DEFAULT_GAS gas_price = 10 # lock token for genesis account self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.tx_conf['to'] = staking_contract_addr tx_data = decode_hex( staking_contract.functions.deposit( 1000000 * 10**18).buildTransaction(self.tx_conf)["data"]) tx = self.rpc.new_tx(value=0, receiver=staking_contract_addr, data=tx_data, gas=gas, gas_price=gas_price) self.rpc.send_tx(tx, True) for i in range(10): priv_key = random.randint(0, 2**256).to_bytes(32, "big") pub_key = encode_hex_0x(priv_to_addr(priv_key)) self.pub.append(pub_key) self.pri.append(priv_key) transaction = self.rpc.new_tx(sender=self.sender, receiver=pub_key, value=1000000 * 10**18, priv_key=self.priv_key) self.rpc.send_tx(transaction, True) # deposit 10000 tokens tx_data = decode_hex( staking_contract.functions.deposit( 10000 * 10**18).buildTransaction(self.tx_conf)["data"]) tx = self.rpc.new_tx(value=0, sender=pub_key, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key) self.rpc.send_tx(tx) self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.filter = Filter(from_epoch="earliest", to_epoch="latest_state") self.testEventContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testBallotContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testPayContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testHTLCContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testDaiContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testMappingContract() self.tx_conf = { "from": self.sender, "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } self.testDaiJoinContract() self.log.info("Pass")