Skip to content

Commit

Permalink
Fix sending of simple iterative txs. #701
Browse files Browse the repository at this point in the history
  • Loading branch information
afalaleev committed Apr 6, 2022
1 parent 93dcdb2 commit fd21a3b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 20 deletions.
44 changes: 27 additions & 17 deletions proxy/common_neon/transaction_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,13 @@ def __init__(self, sender, account: PublicKey):
self._storage = self.s.solana.get_storage_account_info(account)

def _cancel_tx(self):
key_list = []
for is_writable, account in self._storage.account_list:
key_list.append(AccountMeta(pubkey=account, is_signer=False, is_writable=is_writable))

return self.s.builder.make_cancel_transaction(storage=self._account,
nonce=self._storage.nonce,
cancel_keys=self._storage.account_list)
cancel_keys=key_list)

def build(self):
assert self._is_empty()
Expand Down Expand Up @@ -458,7 +462,7 @@ def _create_perm_accounts(self, seed_list):
elif account.tag not in (FINALIZED_STORAGE_TAG, EMPTY_STORAGE_TAG):
raise RuntimeError(f"not empty, not finalized: {str(stage.sol_account)}")

if len(tx.instructions):
if len(tx_name_list):
SolTxListSender(self._s, [tx], ' + '.join(tx_name_list)).send()
else:
self.debug(f"Use existing accounts for resource {opkey}:{rid}")
Expand Down Expand Up @@ -695,7 +699,7 @@ def execute(self) -> (NeonTxResultInfo, [str]):
return NeonTxResultInfo(), []

@abc.abstractmethod
def build_tx(self) -> Transaction:
def build_tx(self, _=0) -> Transaction:
return TransactionWithComputeBudget()

@abc.abstractmethod
Expand Down Expand Up @@ -775,7 +779,7 @@ def _validate_steps(self) -> bool:
return False
return True

def build_tx(self) -> Transaction:
def build_tx(self, _=0) -> Transaction:
tx = TransactionWithComputeBudget()
if not self._skip_create_account:
tx.add(self.s.create_account_tx)
Expand Down Expand Up @@ -822,15 +826,24 @@ def _cancel(self):
self._tx_list = [self._s.builder.make_cancel_transaction()]

def _decrease_steps(self):
self._strategy.steps -= 150
self.debug(f'Decrease EVM steps to {self._strategy.steps}')
if self._strategy.steps < 50:
prev_total_cnt = len(self._get_full_list())
prev_steps = self._strategy.steps
total_steps = prev_total_cnt * self._strategy.steps

if self._strategy.steps <= 10:
return self._cancel()

total_cnt = len(self._get_full_list()) * 2
if self._strategy.steps < 150:
self._strategy.steps = 10
else:
self._strategy.steps -= 150
total_cnt = math.ceil(total_steps / self._strategy.steps)

self.debug(f'Decrease EVM steps from {prev_steps} to {self._strategy.steps}, ' +
f'iterations increase from {prev_total_cnt} to {total_cnt}')

self.clear()
self._tx_list = [self._strategy.build_tx() for _ in range(total_cnt)]
self._tx_list = [self._strategy.build_tx(idx) for idx in range(total_cnt)]

def _on_success_send(self, tx: Transaction, receipt: {}):
if self._is_canceled:
Expand Down Expand Up @@ -915,10 +928,9 @@ def _validate_evm_steps(self):
return False
return True

def build_tx(self) -> Transaction:
def build_tx(self, idx=0) -> Transaction:
# generate unique tx
self.steps -= 1
return self.s.builder.make_partial_call_or_continue_transaction(self.steps)
return self.s.builder.make_partial_call_or_continue_transaction(self.steps + idx)

def _build_preparation_txs(self) -> [Transaction]:
self._preparation_txs_name = self.s.account_txs_name
Expand All @@ -932,7 +944,7 @@ def execute(self) -> (NeonTxResultInfo, [str]):

cnt = math.ceil(self.s.steps_emulated / self.steps)
cnt = math.ceil(self.s.steps_emulated / (self.steps - cnt)) + 2 # +1 on begin, +1 on end
tx_list = [self.build_tx() for _ in range(cnt)]
tx_list = [self.build_tx(idx) for idx in range(cnt)]
self.debug(f'Total iterations {len(tx_list)} for {self.s.steps_emulated} ({self.steps}) EVM steps')
tx_sender = IterativeNeonTxSender(self, self.s, tx_list, self.NAME)
tx_sender.send()
Expand All @@ -944,15 +956,13 @@ class HolderNeonTxStrategy(IterativeNeonTxStrategy, abc.ABC):
NAME = 'ExecuteTrxFromAccountDataIterativeOrContinue'

def __init__(self, *args, **kwargs):
self._tx_idx = 0
IterativeNeonTxStrategy.__init__(self, *args, **kwargs)

def _validate(self) -> bool:
return self._validate_txsize()

def build_tx(self) -> Transaction:
self._tx_idx += 1
return self.s.builder.make_partial_call_or_continue_from_account_data(self.steps, self._tx_idx)
def build_tx(self, idx=0) -> Transaction:
return self.s.builder.make_partial_call_or_continue_from_account_data(self.steps, idx)

def _build_preparation_txs(self) -> [Transaction]:
tx_list = super()._build_preparation_txs()
Expand Down
6 changes: 3 additions & 3 deletions proxy/plugin/solana_rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,15 +432,15 @@ def eth_getCode(self, account: str, tag) -> str:

def eth_sendRawTransaction(self, rawTrx: str) -> str:
trx = EthTrx.fromString(bytearray.fromhex(rawTrx[2:]))
self.debug(f"{json.dumps(trx.as_dict(), cls=JsonEncoder, sort_keys=True)}")
eth_signature = '0x' + trx.hash_signed().hex()
self.debug(f"sendRawTransaction {eth_signature}: {json.dumps(trx.as_dict(), cls=JsonEncoder, sort_keys=True)}")

min_gas_price = self.gas_price_calculator.get_min_gas_price()

if trx.gasPrice < min_gas_price:
raise EthereumError(message="The transaction gasPrice is less than the minimum allowable value" +
f"({trx.gasPrice}<{min_gas_price})")

eth_signature = '0x' + trx.hash_signed().hex()

try:
tx_sender = NeonTxSender(self._db, self._solana, trx, steps=EVM_STEP_COUNT)
tx_sender.execute()
Expand Down

0 comments on commit fd21a3b

Please sign in to comment.