Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
90a4e56
#291 extract transaction sender class
otselnik Nov 14, 2021
143913b
#291 move perm accs to transaction sender
otselnik Nov 16, 2021
16c9bff
#291 fix state
otselnik Nov 22, 2021
f2c0303
#291 fix errors
otselnik Nov 23, 2021
57f3b53
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik Nov 23, 2021
3369f67
#291 merge fixes
otselnik Nov 23, 2021
af721bb
#291 refactoring
otselnik Nov 23, 2021
e512bb8
#291 move EXTRA_GAS to environment
otselnik Nov 23, 2021
8dc5e29
#291 capitalize CONFIRMATION_CHECK_DELAY
otselnik Nov 23, 2021
8dce2a5
#291 sort imports
otselnik Nov 23, 2021
cef8f21
#291 relative paths
otselnik Nov 24, 2021
1bf8383
#291 Should be fixed in #326
otselnik Nov 24, 2021
9672438
#291 testing chnages
otselnik Nov 24, 2021
2d42b73
fix storage account check
sinev-valentine Nov 24, 2021
ac2755c
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik Nov 24, 2021
3519c61
Merge branch '371_add_FinalizedStorage_to_check' into 291_proxy_refac…
otselnik Nov 24, 2021
bf313a2
#291 rename `trx_with_create_and_airdrop` -> `make_trx_with_create_an…
otselnik Nov 24, 2021
3093fcc
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik Nov 24, 2021
4d685db
#291 pull request fixes
otselnik Nov 25, 2021
6f63338
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik Nov 25, 2021
5ebf76a
Merge remote-tracking branch 'origin/develop' into 291_proxy_refactoring
otselnik Dec 2, 2021
b464b1e
#291 merge fix
otselnik Dec 2, 2021
75c8e9a
#291 rename operator and associated token accounts
otselnik Dec 2, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
#291 refactoring
  • Loading branch information
otselnik committed Nov 23, 2021
commit af721bba4b6c4b2f66d9bae6e11f14157919a273
26 changes: 4 additions & 22 deletions proxy/common_neon/address.py
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__)
Expand Down Expand Up @@ -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)):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

program redundant

result = PublicKey(sha256(bytes(base) + bytes(seed) + bytes(program)).digest())
logger.debug('accountWithSeed %s', str(result))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logging here redundant

return result
Expand Down
6 changes: 3 additions & 3 deletions proxy/common_neon/costs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from ..indexer.sql_dict import POSTGRES_USER, POSTGRES_HOST, POSTGRES_DB, POSTGRES_PASSWORD
import psycopg2
import base58
from proxy.environment import evm_loader_id
from proxy.environment import EVM_LOADER_ID


class SQLCost():
Expand Down Expand Up @@ -70,13 +70,13 @@ def update_transaction_cost(receipt, eth_trx, extra_sol_trx=False, reason=None):
evm_loader_instructions = []

for idx, instruction in enumerate(tx_info["transaction"]["message"]["instructions"]):
if accounts[instruction["programIdIndex"]] == evm_loader_id:
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:
if accounts[event['programIdIndex']] == EVM_LOADER_ID:
used_gas = base58.b58decode(event['data'])[2:10]
used_gas = int().from_bytes(used_gas, "little")

Expand Down
38 changes: 38 additions & 0 deletions proxy/common_neon/layouts.py
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
)
107 changes: 55 additions & 52 deletions proxy/common_neon/neon_instruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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,
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.operator_pda_account: SolanaAccount = operator_pda_account

self.operator_token = getTokenAddr(self.operator)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

operator_associated_token_address: PulicKey = ...


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):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

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):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original definition is:

def make_create_eth_account_trx(signer: SolanaAccount, eth_address: EthereumAddress, evm_loader_id, code_acc=None) \
                                -> Tuple[Transaction, PublicKey]:

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()
Expand Down Expand Up @@ -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,
Expand Down
Loading