Skip to content

Commit e900ff7

Browse files
authored
Merge branch 'develop' into 748_indexer_mem_usage
2 parents 98be48c + 4d8698f commit e900ff7

15 files changed

+673
-621
lines changed

.buildkite/pipeline.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ steps:
3838
commands:
3939
- ".buildkite/steps/full_test_suite/run_full_test_suite.sh"
4040
env:
41-
FTS_THRESHOLD: 1700
41+
FTS_THRESHOLD: 1920
4242
FTS_CONTAINER_NAME: fts_${BUILDKITE_BUILD_NUMBER}
4343
FTS_IMAGE: neonlabsorg/full_test_suite:develop
4444
FTS_USERS_NUMBER: 15
@@ -73,4 +73,4 @@ steps:
7373
- "create_infrastructure"
7474
allow_dependency_failure: true
7575

76-
76+

proxy/common_neon/account_whitelist.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
@logged_group("neon.AccountWhitelist")
1919
class AccountWhitelist:
20-
def __init__(self, solana: SolanaInteractor, payer: SolanaAccount, permission_update_int: int):
20+
def __init__(self, solana: SolanaInteractor, permission_update_int: int):
2121
self.solana = solana
2222
self.account_cache = {}
2323
self.permission_update_int = permission_update_int
@@ -31,13 +31,8 @@ def __init__(self, solana: SolanaInteractor, payer: SolanaAccount, permission_up
3131
self.error(f'Wrong proxy configuration: allowance and denial tokens must both exist or absent!')
3232
raise Exception("NEON service is unhealthy. Try again later")
3333

34-
self.allowance_token = PermissionToken(self.solana,
35-
PublicKey(ALLOWANCE_TOKEN_ADDR),
36-
payer)
37-
38-
self.denial_token = PermissionToken(self.solana,
39-
PublicKey(DENIAL_TOKEN_ADDR),
40-
payer)
34+
self.allowance_token = PermissionToken(self.solana, PublicKey(ALLOWANCE_TOKEN_ADDR))
35+
self.denial_token = PermissionToken(self.solana, PublicKey(DENIAL_TOKEN_ADDR))
4136

4237
def read_balance_diff(self, ether_addr: Union[str, EthereumAddress]) -> int:
4338
token_list = [
@@ -50,30 +45,30 @@ def read_balance_diff(self, ether_addr: Union[str, EthereumAddress]) -> int:
5045
denial_balance = balance_list[1]
5146
return allowance_balance - denial_balance
5247

53-
def grant_permissions(self, ether_addr: Union[str, EthereumAddress], min_balance: int):
48+
def grant_permissions(self, ether_addr: Union[str, EthereumAddress], min_balance: int, signer: SolanaAccount):
5449
try:
5550
diff = self.read_balance_diff(ether_addr)
5651
if diff >= min_balance:
5752
self.info(f'{ether_addr} already has permission')
5853
return True
5954

6055
to_mint = min_balance - diff
61-
self.allowance_token.mint_to(to_mint, ether_addr)
56+
self.allowance_token.mint_to(to_mint, ether_addr, signer)
6257
self.info(f'Permissions granted to {ether_addr}')
6358
return True
6459
except Exception as err:
6560
self.error(f'Failed to grant permissions to {ether_addr}: {type(err)}: {err}')
6661
return False
6762

68-
def deprive_permissions(self, ether_addr: Union[str, EthereumAddress], min_balance: int):
63+
def deprive_permissions(self, ether_addr: Union[str, EthereumAddress], min_balance: int, signer: SolanaAccount):
6964
try:
7065
diff = self.read_balance_diff(ether_addr)
7166
if diff < min_balance:
7267
self.info(f'{ether_addr} already deprived')
7368
return True
7469

7570
to_mint = diff - min_balance + 1
76-
self.denial_token.mint_to(to_mint, ether_addr)
71+
self.denial_token.mint_to(to_mint, ether_addr, signer)
7772
self.info(f'Permissions deprived to {ether_addr}')
7873
return True
7974
except Exception as err:

proxy/common_neon/emulator_interactor.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,40 @@
33
from logged_groups import logged_group
44

55
from typing import Optional, Dict, Any
6-
from .errors import EthereumError
6+
from ethereum.transactions import Transaction as NeonTrx
7+
78
from ..environment import neon_cli, NEON_TOKEN_MINT, CHAIN_ID
89

10+
from .errors import EthereumError
11+
from .types import NeonEmulatingResult
12+
913

1014
@logged_group("neon.Proxy")
11-
def call_emulated(contract_id, caller_id, data=None, value=None, *, logger):
15+
def call_emulated(contract_id, caller_id, data=None, value=None, *, logger) -> NeonEmulatingResult:
1216
output = emulator(contract_id, caller_id, data, value)
1317
logger.debug(f"Call emulated. contract_id: {contract_id}, caller_id: {caller_id}, data: {data}, value: {value}, return: {output}")
1418
result = json.loads(output)
1519
check_emulated_exit_status(result)
1620
return result
1721

1822

23+
@logged_group("neon.Proxy")
24+
def call_trx_emulated(neon_trx: NeonTrx, *, logger) -> NeonEmulatingResult:
25+
neon_sender_acc = neon_trx.sender()
26+
contract = neon_trx.contract()
27+
logger.debug(f'sender address: 0x{neon_sender_acc}')
28+
if contract:
29+
dst = 'deploy'
30+
logger.debug(f'deploy contract: {contract}')
31+
else:
32+
dst = neon_trx.toAddress.hex()
33+
logger.debug(f'destination address {dst}')
34+
logger.debug(f"Calling data: {(dst, neon_sender_acc, neon_trx.callData.hex(), hex(neon_trx.value))}")
35+
emulator_json = call_emulated(dst, neon_sender_acc, neon_trx.callData.hex(), hex(neon_trx.value))
36+
logger.debug(f'emulator returns: {json.dumps(emulator_json, sort_keys=True)}')
37+
return emulator_json
38+
39+
1940
@logged_group("neon.Proxy")
2041
def check_emulated_exit_status(result: Dict[str, Any], *, logger):
2142
exit_status = result['exit_status']

proxy/common_neon/permission_token.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,8 @@
1212

1313

1414
class PermissionToken:
15-
def __init__(self,
16-
solana: SolanaInteractor,
17-
token_mint: PublicKey,
18-
payer: SolanaAccount):
15+
def __init__(self, solana: SolanaInteractor, token_mint: PublicKey):
1916
self.solana = solana
20-
self.signer = payer
2117
self.waiter = None
2218
self.token_mint = token_mint
2319

@@ -29,28 +25,24 @@ def get_balance(self, ether_addr: Union[str, EthereumAddress]):
2925
token_account = self.get_token_account_address(ether_addr)
3026
return self.solana.get_token_account_balance(token_account)
3127

32-
def create_account_if_needed(self,
33-
ether_addr: Union[str, EthereumAddress]):
28+
def create_account_if_needed(self, ether_addr: Union[str, EthereumAddress], signer: SolanaAccount):
3429
token_account = self.get_token_account_address(ether_addr)
3530
info = self.solana.get_account_info(token_account)
3631
if info is not None:
3732
return token_account
3833

3934
txn = TransactionWithComputeBudget()
4035
create_txn = spl_token.create_associated_token_account(
41-
payer=self.signer.public_key(),
36+
payer=signer.public_key(),
4237
owner=PublicKey(ether2program(ether_addr)[0]),
4338
mint=self.token_mint
4439
)
4540
txn.add(create_txn)
46-
SolTxListSender(self, [txn], 'CreateAssociatedTokenAccount(1)', skip_preflight=True).send()
41+
SolTxListSender(self, [txn], 'CreateAssociatedTokenAccount(1)', skip_preflight=True).send(signer)
4742
return token_account
4843

49-
def mint_to(self,
50-
amount: int,
51-
ether_addr: Union[str, EthereumAddress],
52-
mint_authority_file: str):
53-
token_account = self.create_account_if_needed(ether_addr)
44+
def mint_to(self, amount: int, ether_addr: Union[str, EthereumAddress], mint_authority_file: str, signer: SolanaAccount):
45+
token_account = self.create_account_if_needed(ether_addr, signer)
5446
mint_command = f'spl-token mint "{str(self.token_mint)}" {Decimal(amount) * pow(Decimal(10), -9)}'
5547
mint_command += f' --owner {mint_authority_file} -- "{str(token_account)}"'
5648
os.system(mint_command)

proxy/common_neon/solana_tx_list_sender.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
from solana.account import Account as SolanaAccount
34
import time
45

56
from logged_groups import logged_group
@@ -50,9 +51,8 @@ def clear(self):
5051
def _get_full_list(self):
5152
return [tx for lst in self._all_tx_list for tx in lst]
5253

53-
def send(self) -> SolTxListSender:
54+
def send(self, signer: SolanaAccount) -> SolTxListSender:
5455
solana = self._s.solana
55-
signer = self._s.signer
5656
waiter = self._s.waiter
5757
skip = self._skip_preflight
5858
commitment = self._preflight_commitment

proxy/common_neon/types.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
from __future__ import annotations
2+
3+
from dataclasses import dataclass
4+
from typing import Dict, Any
5+
6+
17
class Result:
28
def __init__(self, reason: str = None):
39
self._reason = reason
@@ -7,3 +13,12 @@ def __bool__(self) -> bool:
713

814
def __str__(self) -> str:
915
return self._reason if self._reason is not None else ""
16+
17+
18+
@dataclass
19+
class NeonTxPrecheckResult:
20+
is_underpriced_tx_without_chainid: bool
21+
emulating_result: NeonEmulatingResult
22+
23+
24+
NeonEmulatingResult = Dict[str, Any]

proxy/indexer/canceller.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def unlock_accounts(self, blocked_storages):
4242
self.debug(f"Send Cancel: {len(tx_list)}")
4343

4444
try:
45-
SolTxListSender(self, tx_list, f'CancelWithNonce({len(tx_list)})').send()
45+
SolTxListSender(self, tx_list, f'CancelWithNonce({len(tx_list)})').send(self.signer)
4646
except Exception as err:
4747
err_tb = "".join(traceback.format_tb(err.__traceback__))
4848
self.warning('Exception on submitting transaction. ' +

proxy/neon_rpc_api_model/neon_rpc_api_model.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,23 @@
88
from web3.auto import w3
99

1010
from ..common_neon.address import EthereumAddress
11-
from ..common_neon.emulator_interactor import call_emulated
11+
from ..common_neon.emulator_interactor import call_emulated, call_trx_emulated
1212
from ..common_neon.errors import EthereumError, InvalidParamError, PendingTxError
1313
from ..common_neon.estimate import GasEstimate
1414
from ..common_neon.eth_proto import Trx as EthTrx
1515
from ..common_neon.keys_storage import KeyStorage
1616
from ..common_neon.solana_interactor import SolanaInteractor
1717
from ..common_neon.utils import SolanaBlockInfo
18+
from ..common_neon.types import NeonTxPrecheckResult, NeonEmulatingResult
1819
from ..environment import SOLANA_URL, PP_SOLANA_URL, PYTH_MAPPING_ACCOUNT, NEON_EVM_VERSION, NEON_EVM_REVISION, \
1920
CHAIN_ID, neon_cli, EVM_STEP_COUNT
2021
from ..memdb.memdb import MemDB
2122
from ..common_neon.gas_price_calculator import GasPriceCalculator
2223
from ..statistics_exporter.proxy_metrics_interface import StatisticsExporter
2324

2425
from .transaction_sender import NeonTxSender
26+
from .operator_resource_list import OperatorResourceList
27+
from .transaction_validator import NeonTxValidator
2528

2629
NEON_PROXY_PKG_VERSION = '0.7.16-dev'
2730
NEON_PROXY_REVISION = 'NEON_PROXY_REVISION_TO_BE_REPLACED'
@@ -437,13 +440,14 @@ def eth_sendRawTransaction(self, rawTrx: str) -> str:
437440
eth_signature = '0x' + trx.hash_signed().hex()
438441
self.debug(f"sendRawTransaction {eth_signature}: {json.dumps(trx.as_dict(), cls=JsonEncoder, sort_keys=True)}")
439442

440-
min_gas_price = self.gas_price_calculator.get_min_gas_price()
441-
442443
self._stat_tx_begin()
443-
444444
try:
445-
tx_sender = NeonTxSender(self._db, self._solana, trx, steps=EVM_STEP_COUNT, min_gas_price=min_gas_price)
446-
tx_sender.execute()
445+
neon_tx_precheck_result = self.precheck(trx)
446+
447+
tx_sender = NeonTxSender(self._db, self._solana, trx, steps=EVM_STEP_COUNT)
448+
with OperatorResourceList(tx_sender):
449+
tx_sender.execute(neon_tx_precheck_result)
450+
447451
self._stat_tx_success()
448452
return eth_signature
449453

@@ -458,6 +462,14 @@ def eth_sendRawTransaction(self, rawTrx: str) -> str:
458462
self._stat_tx_failed()
459463
raise
460464

465+
def precheck(self, neon_trx: EthTrx) -> NeonTxPrecheckResult:
466+
467+
min_gas_price = self.gas_price_calculator.get_min_gas_price()
468+
neon_validator = NeonTxValidator(self._solana, neon_trx, min_gas_price)
469+
precheck_result = neon_validator.precheck()
470+
471+
return precheck_result
472+
461473
def _stat_tx_begin(self):
462474
self._stat_exporter.stat_commit_tx_begin()
463475

0 commit comments

Comments
 (0)