-
Notifications
You must be signed in to change notification settings - Fork 20
#291 Proxy refactoring #324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 10 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
90a4e56
#291 extract transaction sender class
otselnik 143913b
#291 move perm accs to transaction sender
otselnik 16c9bff
#291 fix state
otselnik f2c0303
#291 fix errors
otselnik 57f3b53
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik 3369f67
#291 merge fixes
otselnik af721bb
#291 refactoring
otselnik e512bb8
#291 move EXTRA_GAS to environment
otselnik 8dc5e29
#291 capitalize CONFIRMATION_CHECK_DELAY
otselnik 8dce2a5
#291 sort imports
otselnik cef8f21
#291 relative paths
otselnik 1bf8383
#291 Should be fixed in #326
otselnik 9672438
#291 testing chnages
otselnik 2d42b73
fix storage account check
sinev-valentine ac2755c
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik 3519c61
Merge branch '371_add_FinalizedStorage_to_check' into 291_proxy_refac…
otselnik bf313a2
#291 rename `trx_with_create_and_airdrop` -> `make_trx_with_create_an…
otselnik 3093fcc
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik 4d685db
#291 pull request fixes
otselnik 6f63338
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik 5ebf76a
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik b464b1e
#291 merge fix
otselnik 75c8e9a
#291 rename operator and associated token accounts
otselnik File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| import logging | ||
| import random | ||
|
|
||
| from eth_keys import keys as eth_keys | ||
| from hashlib import sha256 | ||
| from solana.publickey import PublicKey | ||
| from spl.token.instructions import get_associated_token_address | ||
| from typing import NamedTuple | ||
|
|
||
| from proxy.common_neon.layouts import ACCOUNT_INFO_LAYOUT | ||
| from proxy.environment import neon_cli, ETH_TOKEN_MINT_ID, EVM_LOADER_ID | ||
|
|
||
|
|
||
| logger = logging.getLogger(__name__) | ||
| logger.setLevel(logging.DEBUG) | ||
|
|
||
|
|
||
| class EthereumAddress: | ||
| def __init__(self, data, private=None): | ||
| if isinstance(data, str): | ||
| data = bytes(bytearray.fromhex(data[2:])) | ||
| self.data = data | ||
| self.private = private | ||
|
|
||
| @staticmethod | ||
| def random(): | ||
| letters = '0123456789abcdef' | ||
| data = bytearray.fromhex(''.join([random.choice(letters) for k in range(64)])) | ||
| pk = eth_keys.PrivateKey(data) | ||
| return EthereumAddress(pk.public_key.to_canonical_address(), pk) | ||
|
|
||
| def __str__(self): | ||
| return '0x'+self.data.hex() | ||
|
|
||
| def __repr__(self): | ||
| return self.__str__() | ||
|
|
||
| def __bytes__(self): return self.data | ||
|
|
||
|
|
||
| def accountWithSeed(base, seed, program=PublicKey(EVM_LOADER_ID)): | ||
|
||
| result = PublicKey(sha256(bytes(base) + bytes(seed) + bytes(program)).digest()) | ||
| logger.debug('accountWithSeed %s', str(result)) | ||
|
||
| return result | ||
|
|
||
|
|
||
| def ether2program(ether): | ||
| if isinstance(ether, str): | ||
| pass | ||
| elif isinstance(ether, EthereumAddress): | ||
| ether = str(ether) | ||
| else: | ||
| ether = ether.hex() | ||
| output = neon_cli().call("create-program-address", ether) | ||
| items = output.rstrip().split(' ') | ||
| return items[0], int(items[1]) | ||
|
|
||
|
|
||
| def getTokenAddr(account): | ||
| return get_associated_token_address(PublicKey(account), ETH_TOKEN_MINT_ID) | ||
|
|
||
|
|
||
| class AccountInfo(NamedTuple): | ||
| ether: eth_keys.PublicKey | ||
| trx_count: int | ||
| code_account: PublicKey | ||
|
|
||
| @staticmethod | ||
| def frombytes(data): | ||
| cont = ACCOUNT_INFO_LAYOUT.parse(data) | ||
| return AccountInfo(cont.ether, cont.trx_count, PublicKey(cont.code_account)) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| KECCAK_PROGRAM = "KeccakSecp256k11111111111111111111111111111" | ||
| INCINERATOR_PUBKEY = "1nc1nerator11111111111111111111111111111111" | ||
| SYSVAR_INSTRUCTION_PUBKEY = "Sysvar1nstructions1111111111111111111111111" | ||
|
|
||
| STORAGE_SIZE = 128*1024 | ||
|
|
||
| ACCOUNT_SEED_VERSION=b'\1' | ||
|
|
||
| COLLATERALL_POOL_MAX=10 | ||
|
|
||
| EMPTY_STORAGE_TAG=0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| import base58 | ||
| import psycopg2 | ||
|
|
||
| from proxy.environment import EVM_LOADER_ID | ||
| from proxy.indexer.sql_dict import POSTGRES_USER, POSTGRES_HOST, POSTGRES_DB, POSTGRES_PASSWORD | ||
|
|
||
| class SQLCost(): | ||
| def __init__(self): | ||
|
|
||
| self.conn = psycopg2.connect( | ||
| dbname=POSTGRES_DB, | ||
| user=POSTGRES_USER, | ||
| password=POSTGRES_PASSWORD, | ||
| host=POSTGRES_HOST | ||
| ) | ||
|
|
||
| self.conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) | ||
| cur = self.conn.cursor() | ||
| cur.execute(''' | ||
| CREATE TABLE IF NOT EXISTS OPERATOR_COST | ||
| ( | ||
| hash char(64), | ||
| cost bigint, | ||
| used_gas bigint, | ||
| sender char(40), | ||
| to_address char(40) , | ||
| sig char(100), | ||
| status varchar(100), | ||
| reason varchar(100) | ||
| )''' | ||
| ) | ||
|
|
||
| def close(self): | ||
| self.conn.close() | ||
|
|
||
| def insert(self, hash, cost, used_gas, sender, to_address, sig, status, reason): | ||
| cur = self.conn.cursor() | ||
| cur.execute(''' | ||
| INSERT INTO OPERATOR_COST (hash, cost, used_gas, sender, to_address, sig, status, reason) | ||
| VALUES (%s,%s,%s,%s,%s,%s,%s,%s) | ||
| ''', | ||
| (hash, cost, used_gas, sender, to_address, sig, status, reason) | ||
| ) | ||
|
|
||
|
|
||
| class CostSingleton(object): | ||
| def __new__(cls): | ||
| if not hasattr(cls, 'instance'): | ||
| cls.instance = super(CostSingleton, cls).__new__(cls) | ||
| cls.instance.operator_cost = SQLCost() | ||
| return cls.instance | ||
|
|
||
|
|
||
| def update_transaction_cost(receipt, eth_trx, extra_sol_trx=False, reason=None): | ||
| cost = receipt['result']['meta']['preBalances'][0] - receipt['result']['meta']['postBalances'][0] | ||
| if eth_trx: | ||
| hash = eth_trx.hash_signed().hex() | ||
| sender = eth_trx.sender() | ||
| to_address = eth_trx.toAddress.hex() if eth_trx.toAddress else "None" | ||
| else: | ||
| hash = None | ||
| sender = None | ||
| to_address = None | ||
|
|
||
| sig = receipt['result']['transaction']['signatures'][0] | ||
| used_gas=None | ||
|
|
||
| tx_info = receipt['result'] | ||
| accounts = tx_info["transaction"]["message"]["accountKeys"] | ||
| evm_loader_instructions = [] | ||
|
|
||
| for idx, instruction in enumerate(tx_info["transaction"]["message"]["instructions"]): | ||
| if accounts[instruction["programIdIndex"]] == EVM_LOADER_ID: | ||
| evm_loader_instructions.append(idx) | ||
|
|
||
| for inner in (tx_info['meta']['innerInstructions']): | ||
| if inner["index"] in evm_loader_instructions: | ||
| for event in inner['instructions']: | ||
| if accounts[event['programIdIndex']] == EVM_LOADER_ID: | ||
| used_gas = base58.b58decode(event['data'])[2:10] | ||
| used_gas = int().from_bytes(used_gas, "little") | ||
|
|
||
| table = CostSingleton().operator_cost | ||
| table.insert( | ||
| hash, | ||
| cost, | ||
| used_gas if used_gas else 0, | ||
| sender, | ||
| to_address, | ||
| sig, | ||
| 'extra' if extra_sol_trx else 'ok', | ||
| reason if reason else '' | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import json | ||
| import logging | ||
|
|
||
| from proxy.common_neon.errors import EthereumError | ||
| from proxy.environment import neon_cli | ||
rozhkovdmitrii marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| logger = logging.getLogger(__name__) | ||
| logger.setLevel(logging.DEBUG) | ||
|
|
||
|
|
||
| def call_emulated(contract_id, caller_id, data=None, value=None): | ||
| output = emulator(contract_id, caller_id, data, value) | ||
| logger.debug("call_emulated %s %s %s %s return %s", contract_id, caller_id, data, value, output) | ||
| result = json.loads(output) | ||
| exit_status = result['exit_status'] | ||
| if exit_status == 'revert': | ||
| result_value = result['result'] | ||
| if len(result_value) < 8 or result_value[:8] != '08c379a0': | ||
| raise EthereumError(code=3, message='execution reverted') | ||
|
|
||
| offset = int(result_value[8:8+64], 16) | ||
| length = int(result_value[8+64:8+64+64], 16) | ||
| message = str(bytes.fromhex(result_value[8+offset*2+64:8+offset*2+64+length*2]), 'utf8') | ||
| raise EthereumError(code=3, message='execution reverted: '+message, data='0x'+result_value) | ||
| if result["exit_status"] != "succeed": | ||
| raise Exception("evm emulator error ", result) | ||
| return result | ||
|
|
||
|
|
||
| def emulator(contract, sender, data, value): | ||
| data = data or "none" | ||
| value = value or "" | ||
| return neon_cli().call("emulate", sender, contract, data, value) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
|
|
||
| from construct import Bytes, Int8ul, Int64ul | ||
| from construct import Struct | ||
|
|
||
| STORAGE_ACCOUNT_INFO_LAYOUT = Struct( | ||
| # "tag" / Int8ul, | ||
| "caller" / Bytes(20), | ||
| "nonce" / Int64ul, | ||
| "gas_limit" / Int64ul, | ||
| "gas_price" / Int64ul, | ||
| "slot" / Int64ul, | ||
| "operator" / Bytes(32), | ||
| "accounts_len" / Int64ul, | ||
| "executor_data_size" / Int64ul, | ||
| "evm_data_size" / Int64ul, | ||
| "gas_used_and_paid" / Int64ul, | ||
| "number_of_payments" / Int64ul, | ||
| ) | ||
|
|
||
| ACCOUNT_INFO_LAYOUT = Struct( | ||
| "type" / Int8ul, | ||
| "ether" / Bytes(20), | ||
| "nonce" / Int8ul, | ||
| "trx_count" / Bytes(8), | ||
| "code_account" / Bytes(32), | ||
| "is_rw_blocked" / Int8ul, | ||
| "rw_blocked_acc" / Bytes(32), | ||
| "eth_token_account" / Bytes(32), | ||
| "ro_blocked_cnt" / Int8ul, | ||
| ) | ||
|
|
||
|
|
||
| CREATE_ACCOUNT_LAYOUT = Struct( | ||
| "lamports" / Int64ul, | ||
| "space" / Int64ul, | ||
| "ether" / Bytes(20), | ||
| "nonce" / Int8ul | ||
| ) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.