Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
1 change: 1 addition & 0 deletions proxy/core/acceptor/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
LOCK = multiprocessing.Lock()

proxy_id_glob = multiprocessing.Value('i', 0)
new_acc_id_glob = multiprocessing.Value('i', 0)


class AcceptorPool:
Expand Down
29 changes: 3 additions & 26 deletions proxy/plugin/solana_rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@
import base58
import traceback
import threading
from .solana_rest_api_tools import EthereumAddress, create_account_with_seed, getTokens, \
getAccountInfo, call_signed, call_emulated, \
Trx, EthereumError, create_collateral_pool_address, getTokenAddr, STORAGE_SIZE, neon_config_load, MINIMAL_GAS_PRICE
from .solana_rest_api_tools import EthereumAddress, getTokens, getAccountInfo, \
call_signed, call_emulated, EthereumError, neon_config_load, MINIMAL_GAS_PRICE
from solana.rpc.commitment import Commitment, Confirmed
from web3 import Web3
import logging
Expand All @@ -45,27 +44,6 @@

EXTRA_GAS = int(os.environ.get("EXTRA_GAS", "0"))

class PermanentAccounts:
def __init__(self, client, signer, proxy_id):
self.operator = signer.public_key()
self.operator_token = getTokenAddr(self.operator)
self.proxy_id = proxy_id

proxy_id_bytes = proxy_id.to_bytes((proxy_id.bit_length() + 7) // 8, 'big')

storage_seed = keccak_256(b"storage" + proxy_id_bytes).hexdigest()[:32]
storage_seed = bytes(storage_seed, 'utf8')
self.storage = create_account_with_seed(client, funding=signer, base=signer, seed=storage_seed, storage_size=STORAGE_SIZE)

holder_seed = keccak_256(b"holder" + proxy_id_bytes).hexdigest()[:32]
holder_seed = bytes(holder_seed, 'utf8')
self.holder = create_account_with_seed(client, funding=signer, base=signer, seed=holder_seed, storage_size=STORAGE_SIZE)

collateral_pool_index = proxy_id % 4
self.collateral_pool_index_buf = collateral_pool_index.to_bytes(4, 'little')
self.collateral_pool_address = create_collateral_pool_address(collateral_pool_index)


class EthereumModel:
def __init__(self):
# Initialize user account
Expand Down Expand Up @@ -98,7 +76,6 @@ def __init__(self):
proxy_id_glob.value += 1
logger.debug("worker id {}".format(self.proxy_id))

self.perm_accs = PermanentAccounts(self.client, self.signer, self.proxy_id)
neon_config_load(self)
pass

Expand Down Expand Up @@ -415,7 +392,7 @@ def eth_sendRawTransaction(self, rawTrx):
]
})
try:
signature = call_signed(self.signer, self.client, trx, self.perm_accs, steps=250)
signature = call_signed(self.signer, self.client, trx, steps=250)

logger.debug('Transaction signature: %s %s', signature, eth_signature)

Expand Down
100 changes: 96 additions & 4 deletions proxy/plugin/solana_rest_api_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from web3.auto import w3
from proxy.environment import neon_cli, evm_loader_id, ETH_TOKEN_MINT_ID, COLLATERAL_POOL_BASE, read_elf_params
from .eth_proto import Trx
from ..core.acceptor.pool import new_acc_id_glob

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
Expand Down Expand Up @@ -88,6 +89,55 @@
]


class PermanentAccounts:
def __init__(self, client, signer):
with new_acc_id_glob.get_lock():
self.acc_id = new_acc_id_glob.value
new_acc_id_glob.value += 1

logger.debug("LOCK RESOURCES {}".format(self.acc_id))
logger.debug("worker id {}".format(self.acc_id))

self.client = client
self.signer = signer
self.operator = signer.public_key()
self.operator_token = getTokenAddr(self.operator)

acc_id_bytes = self.acc_id.to_bytes((self.acc_id.bit_length() + 7) // 8, 'big')

storage_seed = keccak_256(b"storage" + acc_id_bytes).hexdigest()[:32]
storage_seed = bytes(storage_seed, 'utf8')

holder_seed = keccak_256(b"holder" + acc_id_bytes).hexdigest()[:32]
holder_seed = bytes(holder_seed, 'utf8')

accounts = create_multiple_accounts_with_seed(
client,
funding=signer,
base=signer,
seeds=[storage_seed, holder_seed],
sizes=[STORAGE_SIZE, STORAGE_SIZE])
self.storage = accounts[0]
self.holder = accounts[1]

collateral_pool_index = self.acc_id % 10
self.collateral_pool_index_buf = collateral_pool_index.to_bytes(4, 'little')
self.collateral_pool_address = create_collateral_pool_address(collateral_pool_index)

def __del__(self):
logger.debug("FREE RESOURCES {}".format(self.acc_id))

acc_id_bytes = self.acc_id.to_bytes((self.acc_id.bit_length() + 7) // 8, 'big')

storage_seed = keccak_256(b"storage" + acc_id_bytes).hexdigest()[:32]
storage_seed = bytes(storage_seed, 'utf8')

holder_seed = keccak_256(b"holder" + acc_id_bytes).hexdigest()[:32]
holder_seed = bytes(holder_seed, 'utf8')

refund_accounts(self.client, self.signer, [storage_seed, holder_seed])


class TransactionInfo:
def __init__(self, caller_token, eth_accounts, nonce):
self.caller_token = caller_token
Expand Down Expand Up @@ -173,6 +223,47 @@ def create_account_with_seed(client, funding, base, seed, storage_size):
return account


def create_multiple_accounts_with_seed(client, funding, base, seeds, sizes):
accounts = []
trx = Transaction()

for seed, storage_size in zip(seeds, sizes):
account = accountWithSeed(base.public_key(), seed, PublicKey(evm_loader_id))
accounts.append(account)

if client.get_balance(account, commitment=Confirmed)['result']['value'] == 0:
minimum_balance = client.get_minimum_balance_for_rent_exemption(storage_size, commitment=Confirmed)["result"]
logger.debug("Minimum balance required for account {}".format(minimum_balance))

trx.add(createAccountWithSeedTrx(funding.public_key(), base.public_key(), seed, minimum_balance, storage_size, PublicKey(evm_loader_id)))

if len(trx.instructions) > 0:
send_transaction(client, trx, funding)

return accounts


def refund_accounts(client, owner, seeds):
trx = Transaction()
for seed in seeds:
account = accountWithSeed(owner.public_key(), seed, PublicKey(evm_loader_id))
if client.get_balance(account, commitment=Confirmed)['result']['value'] != 0:
trx.add(make_refund_tx(account, owner, seed))

if len(trx.instructions) > 0:
send_transaction(client, trx, owner)


def make_refund_tx(del_key, owner, seed):
return TransactionInstruction(
program_id=PublicKey(evm_loader_id),
data=bytearray.fromhex("10") + bytes(seed),
keys=[
AccountMeta(pubkey=del_key, is_signer=False, is_writable=True),
AccountMeta(pubkey=owner.public_key(), is_signer=True, is_writable=True),
])


def make_keccak_instruction_data(check_instruction_index, msg_len, data_start):
if check_instruction_index > 255 and check_instruction_index < 0:
raise Exception("Invalid index for instruction - {}".format(check_instruction_index))
Expand Down Expand Up @@ -940,7 +1031,8 @@ def create_account_list_by_emulate(signer, client, ethTrx):
return (trx_accs, sender_ether, trx)


def call_signed(signer, client, ethTrx, perm_accs, steps):
def call_signed(signer, client, ethTrx, steps):
perm_accs = PermanentAccounts(client, signer)

(trx_accs, sender_ether, create_acc_trx) = create_account_list_by_emulate(signer, client, ethTrx)

Expand Down Expand Up @@ -1024,7 +1116,7 @@ def call_signed_noniterative(signer, client, ethTrx, perm_accs, trx_accs, msg, c

def call_signed_with_holder_acc(signer, client, ethTrx, perm_accs, trx_accs, steps, create_acc_trx):

write_trx_to_holder_account(signer, client, perm_accs.holder, perm_accs.proxy_id, ethTrx)
write_trx_to_holder_account(signer, client, perm_accs.holder, perm_accs.acc_id, ethTrx)

if len(create_acc_trx.instructions):
precall_txs = Transaction()
Expand Down Expand Up @@ -1107,7 +1199,7 @@ def createERC20TokenAccountTrx(signer, token_info):



def write_trx_to_holder_account(signer, client, holder, proxy_id, ethTrx):
def write_trx_to_holder_account(signer, client, holder, acc_id, ethTrx):
msg = ethTrx.signature() + len(ethTrx.unsigned_msg()).to_bytes(8, byteorder="little") + ethTrx.unsigned_msg()

# Write transaction to transaction holder account
Expand All @@ -1119,7 +1211,7 @@ def write_trx_to_holder_account(signer, client, holder, proxy_id, ethTrx):
trx = Transaction()
# logger.debug("sender_sol %s %s %s", sender_sol, holder, acc.public_key())
trx.add(TransactionInstruction(program_id=evm_loader_id,
data=write_holder_layout(proxy_id, offset, part),
data=write_holder_layout(acc_id, offset, part),
keys=[
AccountMeta(pubkey=holder, is_signer=False, is_writable=True),
AccountMeta(pubkey=signer.public_key(), is_signer=True, is_writable=False),
Expand Down