From 08b10f3574ade4b9088dfa1b296a610f9c2a7fb2 Mon Sep 17 00:00:00 2001 From: Anton Lisanin Date: Wed, 3 Nov 2021 10:36:42 +0300 Subject: [PATCH] #355 Resize storage without existing code account --- proxy/plugin/solana_rest_api_tools.py | 8 ++- proxy/test_create_account_block.py | 98 +++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 proxy/test_create_account_block.py diff --git a/proxy/plugin/solana_rest_api_tools.py b/proxy/plugin/solana_rest_api_tools.py index 45efa542d..647df4231 100644 --- a/proxy/plugin/solana_rest_api_tools.py +++ b/proxy/plugin/solana_rest_api_tools.py @@ -850,7 +850,7 @@ def create_account_list_by_emulate(signer, client, ethTrx): if acc_desc["new"] == False: address = bytes.fromhex(acc_desc["address"][2:]) - if acc_desc["code_size_current"] and acc_desc["code_size"]: + if acc_desc["code_size_current"] is not None and acc_desc["code_size"] is not None: if acc_desc["code_size"] > acc_desc["code_size_current"]: code_size = acc_desc["code_size"] + 2048 seed = b58encode(ACCOUNT_SEED_VERSION + os.urandom(20)) @@ -863,7 +863,11 @@ def create_account_list_by_emulate(signer, client, ethTrx): resize_instr.append(TransactionInstruction( keys=[ AccountMeta(pubkey=PublicKey(acc_desc["account"]), is_signer=False, is_writable=True), - AccountMeta(pubkey=acc_desc["contract"], is_signer=False, is_writable=True), + ( + AccountMeta(pubkey=acc_desc["contract"], is_signer=False, is_writable=True) + if acc_desc["contract"] else + AccountMeta(pubkey=PublicKey("11111111111111111111111111111111"), is_signer=False, is_writable=False) + ), AccountMeta(pubkey=code_account_new, is_signer=False, is_writable=True), AccountMeta(pubkey=signer.public_key(), is_signer=True, is_writable=False) ], diff --git a/proxy/test_create_account_block.py b/proxy/test_create_account_block.py new file mode 100644 index 000000000..42bfeee36 --- /dev/null +++ b/proxy/test_create_account_block.py @@ -0,0 +1,98 @@ +import unittest +import os +import rlp +from web3 import Web3 +from solcx import install_solc + +# install_solc(version='latest') +install_solc(version='0.7.0') +from solcx import compile_source + +proxy_url = os.environ.get('PROXY_URL', 'http://127.0.0.1:9090/solana') +proxy = Web3(Web3.HTTPProvider(proxy_url)) +eth_account = proxy.eth.account.create() +proxy.eth.default_account = eth_account.address + + +STORAGE_SOLIDITY_SOURCE = ''' +pragma solidity >=0.7.0 <0.9.0; + +contract Storage { + uint256 number; + /** + * @dev Store value in variable + * @param num value to store + */ + function store(uint256 num) public { + number = num; + } + /** + * @dev Return value + * @return value of 'number' + */ + function retrieve() public view returns (uint256){ + return number; + } +} +''' + + + +class Test_createAccountBlock(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("\n\nhttps://github.com/neonlabsorg/proxy-model.py/issues/147") + print('eth_account.address:', eth_account.address) + print('eth_account.key:', eth_account.key.hex()) + print('balance:', proxy.eth.get_balance(eth_account.address)) + + # Create caller account in NeonEVM + cls.deploy_contract(cls) + + def deploy_contract(self): + compiled_sol = compile_source(STORAGE_SOLIDITY_SOURCE) + contract_id, contract_interface = compiled_sol.popitem() + storage = proxy.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin']) + trx_deploy = proxy.eth.account.sign_transaction(dict( + nonce=proxy.eth.get_transaction_count(eth_account.address), + chainId=proxy.eth.chain_id, + gas=987654321, + gasPrice=0, + to='', + value=0, + data=storage.bytecode), + eth_account.key + ) + + trx_deploy_hash = proxy.eth.send_raw_transaction(trx_deploy.rawTransaction) + return proxy.eth.wait_for_transaction_receipt(trx_deploy_hash) + + def transfer(self, target_account, value): + trx_transfer = proxy.eth.account.sign_transaction(dict( + nonce=proxy.eth.get_transaction_count(eth_account.address), + chainId=proxy.eth.chain_id, + gas=987654321, + gasPrice=0, + to=bytes(target_account), + value=value), + eth_account.key + ) + + transfer_hash = proxy.eth.send_raw_transaction(trx_transfer.rawTransaction) + return proxy.eth.wait_for_transaction_receipt(transfer_hash) + + def test_blockAccount(self): + nonce = proxy.eth.get_transaction_count(eth_account.address) + expected_contract_address = proxy.keccak(rlp.encode((bytes.fromhex(eth_account.address[2:]), nonce + 1)))[-20:] + + # Create expected contract account + transfer_receipt = self.transfer(expected_contract_address, 1_000_000_000) + self.assertEqual(transfer_receipt["status"], 1) + + # Try to deploy to expected contract account + deploy_receipt = self.deploy_contract() + self.assertEqual(deploy_receipt["status"], 1) + + +if __name__ == '__main__': + unittest.main()