-
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
Changes from 1 commit
90a4e56
143913b
16c9bff
f2c0303
57f3b53
3369f67
af721bb
e512bb8
8dc5e29
8dce2a5
cef8f21
1bf8383
9672438
2d42b73
ac2755c
3519c61
bf313a2
3093fcc
4d685db
6f63338
5ebf76a
b464b1e
75c8e9a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,13 @@ | ||
| import logging | ||
| import random | ||
| from hashlib import sha256 | ||
| from typing import NamedTuple | ||
| from solana.publickey import PublicKey | ||
| from eth_keys import keys as eth_keys | ||
| from construct import Bytes, Int8ul | ||
| from construct import Struct as cStruct | ||
| from spl.token.instructions import get_associated_token_address | ||
|
|
||
| from proxy.environment import ETH_TOKEN_MINT_ID | ||
| from proxy.environment import neon_cli | ||
|
|
||
|
|
||
| ACCOUNT_SEED_VERSION=b'\1' | ||
|
|
||
|
|
||
| ACCOUNT_INFO_LAYOUT = cStruct( | ||
| "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, | ||
| ) | ||
| from proxy.environment import neon_cli, ETH_TOKEN_MINT_ID, EVM_LOADER_ID | ||
| from proxy.common_neon.layouts import ACCOUNT_INFO_LAYOUT | ||
|
|
||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
@@ -54,8 +37,7 @@ def __repr__(self): | |
| def __bytes__(self): return self.data | ||
|
|
||
|
|
||
| def accountWithSeed(base, seed, program): | ||
| # logger.debug(type(base), str(base), type(seed), str(seed), type(program), str(program)) | ||
| 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 | ||
|
|
||
| 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 | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,23 +12,16 @@ | |
| from spl.token.instructions import transfer2, Transfer2Params | ||
| from sha3 import keccak_256 | ||
|
|
||
| from proxy.environment import evm_loader_id as EVM_LOADER_ID, ETH_TOKEN_MINT_ID , COLLATERAL_POOL_BASE, NEW_USER_AIRDROP_AMOUNT | ||
| from .constants import SYSVAR_INSTRUCTION_PUBKEY, INCINERATOR_PUBKEY, KECCAK_PROGRAM, COLLATERALL_POOL_MAX | ||
| from .address import accountWithSeed, ether2program, getTokenAddr | ||
| from proxy.environment import EVM_LOADER_ID, ETH_TOKEN_MINT_ID , COLLATERAL_POOL_BASE, NEW_USER_AIRDROP_AMOUNT | ||
| from proxy.common_neon.constants import SYSVAR_INSTRUCTION_PUBKEY, INCINERATOR_PUBKEY, KECCAK_PROGRAM, COLLATERALL_POOL_MAX | ||
| from proxy.common_neon.address import accountWithSeed, ether2program, getTokenAddr | ||
| from proxy.common_neon.layouts import CREATE_ACCOUNT_LAYOUT | ||
|
|
||
|
|
||
| logger = logging.getLogger(__name__) | ||
| logger.setLevel(logging.DEBUG) | ||
|
|
||
|
|
||
| CREATE_ACCOUNT_LAYOUT = cStruct( | ||
| "lamports" / Int64ul, | ||
| "space" / Int64ul, | ||
| "ether" / Bytes(20), | ||
| "nonce" / Int8ul | ||
| ) | ||
|
|
||
|
|
||
| obligatory_accounts = [ | ||
| AccountMeta(pubkey=EVM_LOADER_ID, is_signer=False, is_writable=False), | ||
| AccountMeta(pubkey=ETH_TOKEN_MINT_ID, is_signer=False, is_writable=False), | ||
|
|
@@ -37,6 +30,21 @@ | |
| ] | ||
|
|
||
|
|
||
| def create_account_with_seed_layout(base, seed, lamports, space): | ||
| return SYSTEM_INSTRUCTIONS_LAYOUT.build( | ||
| dict( | ||
| instruction_type = InstructionType.CREATE_ACCOUNT_WITH_SEED, | ||
| args=dict( | ||
| base=bytes(base), | ||
| seed=dict(length=len(seed), chars=seed), | ||
| lamports=lamports, | ||
| space=space, | ||
| program_id=bytes(PublicKey(EVM_LOADER_ID)) | ||
| ) | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| def create_account_layout(lamports, space, ether, nonce): | ||
| return bytes.fromhex("02000000")+CREATE_ACCOUNT_LAYOUT.build(dict( | ||
| lamports=lamports, | ||
|
|
@@ -78,82 +86,60 @@ def make_keccak_instruction_data(check_instruction_index, msg_len, data_start): | |
|
|
||
|
|
||
| class NeonInstruction: | ||
| def __init__(self, operator, eth_trx = None): | ||
| def __init__(self, operator): | ||
| self.operator = operator | ||
|
||
| self.operator_token = getTokenAddr(self.operator) | ||
|
||
|
|
||
| self.caller_token = None | ||
|
|
||
| self.eth_accounts = None | ||
|
|
||
| self.storage = None | ||
| self.holder = None | ||
| self.perm_accs_id = None | ||
| def init_eth_trx(self, eth_trx, eth_accounts, caller_token): | ||
| self.eth_accounts = eth_accounts | ||
| self.caller_token = caller_token | ||
|
|
||
| self.eth_trx = eth_trx | ||
|
|
||
| if eth_trx is not None: | ||
| self.msg = bytes.fromhex(self.eth_trx.sender()) + self.eth_trx.signature() + self.eth_trx.unsigned_msg() | ||
|
|
||
| hash = keccak_256(self.eth_trx.unsigned_msg()).digest() | ||
| collateral_pool_index = int().from_bytes(hash[:4], "little") % COLLATERALL_POOL_MAX | ||
| self.collateral_pool_index_buf = collateral_pool_index.to_bytes(4, 'little') | ||
| self.collateral_pool_address = self.create_collateral_pool_address(collateral_pool_index) | ||
| else: | ||
| self.msg = None | ||
| self.collateral_pool_index_buf = None | ||
| self.collateral_pool_address = None | ||
| self.msg = bytes.fromhex(self.eth_trx.sender()) + self.eth_trx.signature() + self.eth_trx.unsigned_msg() | ||
|
|
||
| hash = keccak_256(self.eth_trx.unsigned_msg()).digest() | ||
| collateral_pool_index = int().from_bytes(hash[:4], "little") % COLLATERALL_POOL_MAX | ||
| self.collateral_pool_index_buf = collateral_pool_index.to_bytes(4, 'little') | ||
| self.collateral_pool_address = self.create_collateral_pool_address(collateral_pool_index) | ||
|
|
||
| def set_accounts(self, eth_accounts, caller_token): | ||
| self.eth_accounts = eth_accounts | ||
| self.caller_token = caller_token | ||
| return self | ||
|
|
||
|
|
||
| def set_storage_and_holder(self, storage, holder, perm_accs_id): | ||
| def init_iterative(self, storage, holder, perm_accs_id): | ||
| self.storage = storage | ||
| self.holder = holder | ||
| self.perm_accs_id = perm_accs_id | ||
|
|
||
| return self | ||
|
|
||
|
|
||
| def create_collateral_pool_address(self, collateral_pool_index): | ||
|
||
| COLLATERAL_SEED_PREFIX = "collateral_seed_" | ||
| seed = COLLATERAL_SEED_PREFIX + str(collateral_pool_index) | ||
| return accountWithSeed(PublicKey(COLLATERAL_POOL_BASE), str.encode(seed), PublicKey(EVM_LOADER_ID)) | ||
| return accountWithSeed(PublicKey(COLLATERAL_POOL_BASE), str.encode(seed)) | ||
|
|
||
|
|
||
| def create_account_with_seed_trx(self, seed, lamports, space): | ||
| def create_account_with_seed_trx(self, account, seed, lamports, space): | ||
| seed_str = str(seed, 'utf8') | ||
| data = SYSTEM_INSTRUCTIONS_LAYOUT.build( | ||
| dict( | ||
| instruction_type = InstructionType.CREATE_ACCOUNT_WITH_SEED, | ||
| args=dict( | ||
| base=bytes(self.operator), | ||
| seed=dict(length=len(seed_str), chars=seed_str), | ||
| lamports=lamports, | ||
| space=space, | ||
| program_id=bytes(PublicKey(EVM_LOADER_ID)) | ||
| ) | ||
| ) | ||
| ) | ||
| logger.debug("createAccountWithSeedTrx %s %s %s", type(self.operator), self.operator, data.hex()) | ||
| created = accountWithSeed(self.operator, seed, PublicKey(EVM_LOADER_ID)) | ||
| logger.debug("created %s", created) | ||
| logger.debug("createAccountWithSeedTrx base(%s) account(%s) seed(%s)", type(self.operator),account, seed_str) | ||
| return TransactionInstruction( | ||
| keys=[ | ||
| AccountMeta(pubkey=self.operator, is_signer=True, is_writable=True), | ||
| AccountMeta(pubkey=created, is_signer=False, is_writable=True), | ||
| AccountMeta(pubkey=account, is_signer=False, is_writable=True), | ||
| AccountMeta(pubkey=self.operator, is_signer=True, is_writable=False), | ||
| ], | ||
| program_id=SYS_PROGRAM_ID, | ||
| data=data | ||
| data=create_account_with_seed_layout(self.operator, seed_str, lamports, space) | ||
| ) | ||
|
|
||
|
|
||
| def make_create_eth_account_trx(self, eth_address, code_acc=None): | ||
|
||
| solana_address, nonce = ether2program(eth_address) | ||
| token_acc_address = getTokenAddr(PublicKey(solana_address)) | ||
| logger.debug(f'Create eth account: {eth_address}, sol account: {solana_address}, token_acc_address: {token_acc_address}, nonce: {nonce}') | ||
|
|
||
| base = self.operator | ||
| data = create_account_layout(0, 0, bytes(eth_address), nonce) | ||
| trx = Transaction() | ||
|
|
@@ -237,6 +223,23 @@ def trx_with_create_and_airdrop(self, eth_account, code_acc=None) -> Transaction | |
| return trx | ||
|
|
||
|
|
||
| def make_resize_instruction(self, acc_desc, code_account_new, seed) -> TransactionInstruction: | ||
| return TransactionInstruction( | ||
| program_id = EVM_LOADER_ID, | ||
| data = bytearray.fromhex("11") + bytes(seed), # 17- ResizeStorageAccount | ||
| keys = [ | ||
| AccountMeta(pubkey=PublicKey(acc_desc["account"]), 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=self.operator, is_signer=True, is_writable=False) | ||
| ], | ||
| ) | ||
|
|
||
|
|
||
| def make_write_transaction(self, offset: int, data: bytes) -> Transaction: | ||
| return Transaction().add(TransactionInstruction( | ||
| program_id=EVM_LOADER_ID, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.