Skip to content
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

updated eip-1559 tests #503

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
123 changes: 100 additions & 23 deletions integration/tests/basic/erc/test_EIP1559.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import pytest
import web3
import web3.types
from solana.rpc.commitment import Confirmed
from solders.signature import Signature
from eth_account.signers.local import LocalAccount
from web3._utils.fee_utils import _fee_history_priority_fee_estimate # noqa
Expand All @@ -15,6 +14,7 @@

from utils import helpers
from utils.apiclient import JsonRPCSession
from utils.consts import InstructionTags, COMPUTE_BUDGET_ID
from utils.faucet import Faucet
from utils.models.fee_history_model import EthFeeHistoryResult
from utils.solana_client import SolanaClient
Expand Down Expand Up @@ -104,7 +104,7 @@ def validate_transfer_positive(
base_fee_multiplier = 1.1
max_fee_per_gas = int((base_fee_multiplier * base_fee_per_gas) + max_priority_fee_per_gas)

value = balance_sender_before // 2
value = 10

tx_params = web3_client.make_raw_tx_eip_1559(
chain_id="auto",
Expand Down Expand Up @@ -176,7 +176,7 @@ def validate_deploy_positive(
latest_block: web3.types.BlockData = web3_client._web3.eth.get_block(block_identifier="latest") # noqa
base_fee_per_gas = latest_block.baseFeePerGas # noqa
max_priority_fee_per_gas = web3_client._web3.eth._max_priority_fee() # noqa
max_fee_per_gas = (5 * base_fee_per_gas) + max_priority_fee_per_gas
max_fee_per_gas = (2 * base_fee_per_gas) + max_priority_fee_per_gas

tx_params = web3_client.make_raw_tx_eip_1559(
chain_id="auto",
Expand Down Expand Up @@ -207,7 +207,7 @@ def validate_deploy_positive(

# Validate that sender's balance decreased by at least the gas fee
assert (
balance_before - balance_after <= total_fee_paid
balance_before - total_fee_paid == balance_after
), f"Sender balance did not decrease by gas fee: {balance_before, balance_after, total_fee_paid}"

# Verify that the effective gas price does not exceed the max fee per gas
Expand All @@ -227,6 +227,7 @@ def validate_deploy_positive(
@allure.feature("EIP Verifications")
@allure.story("EIP-1559: New Transaction Type Support in Neon")
@pytest.mark.usefixtures("accounts", "web3_client")
@pytest.mark.eip_1559
class TestEIP1559:
web3_client: NeonChainWeb3Client
accounts: EthAccounts
Expand Down Expand Up @@ -446,23 +447,22 @@ def test_too_low_fee(
self.web3_client.send_transaction(account=sender, transaction=tx_params, timeout=TX_TIMEOUT)

@pytest.mark.neon_only
@pytest.mark.parametrize("base_fee_multiplier", [1.1, 1.5])
def test_compute_unit_price(
def test_compute_unit_price_default_value(
self,
accounts: EthAccounts,
web3_client: NeonChainWeb3Client,
json_rpc_client: JsonRPCSession,
sol_client: SolanaClient,
base_fee_multiplier,
):
sender = accounts[0]
recipient = accounts[1]

max_priority_fee_per_gas = web3_client.max_priority_fee_per_gas()
base_fee_per_gas = web3_client.base_fee_per_gas()
base_fee_multiplier = 1.1
max_fee_per_gas = int((base_fee_multiplier * base_fee_per_gas) + max_priority_fee_per_gas)

value = 1029380121
value = 10

tx_params = web3_client.make_raw_tx_eip_1559(
chain_id="auto",
Expand All @@ -480,28 +480,102 @@ def test_compute_unit_price(

receipt = web3_client.send_transaction(account=sender, transaction=tx_params)
assert receipt.type == 2
solana_transaction_hash = web3_client.get_solana_trx_by_neon(receipt["transactionHash"].hex())["result"][0]
solana_transaction = sol_client.get_transaction(
Signature.from_string(solana_transaction_hash), commitment=Confirmed
solana_transactions = web3_client.get_solana_trx_by_neon(receipt["transactionHash"].hex())["result"]
assert len(solana_transactions) == 1
solana_transaction = sol_client.get_transaction_with_wait(Signature.from_string(solana_transactions[0]))

# get ComputeBudget key index
compute_budget_index = -1
for index, account_key in enumerate(solana_transaction.value.transaction.transaction.message.account_keys):
if account_key == COMPUTE_BUDGET_ID:
compute_budget_index = index
break
assert compute_budget_index >= 0, "ComputeBudget not found"

# get setComputeUnitPrice value
cu_price_actual = 0
for instruction in solana_transaction.value.transaction.transaction.message.instructions:
if instruction.program_id_index == compute_budget_index:
decoded_data = base58.b58decode(instruction.data)
instruction_code = decoded_data[:1]
instruction_data = int.from_bytes(decoded_data[1:], "little")
if instruction_code == InstructionTags.SET_COMPUTE_UNIT_PRICE:
cu_price_actual = instruction_data

# make sure the compute unit price equals default value set by var DEFAULT_CU_PRICE in proxy
assert cu_price_actual == 10500

@pytest.mark.neon_only
def test_compute_unit_price_estimated_value(
self,
accounts: EthAccounts,
web3_client: NeonChainWeb3Client,
json_rpc_client: JsonRPCSession,
sol_client: SolanaClient,
):
account = accounts[0]
contract_iface = helpers.get_contract_interface(
contract="common/Common.sol",
version="0.8.12",
contract_name="Common",
)

data_list = [instr.data for instr in solana_transaction.value.transaction.transaction.message.instructions]
max_priority_fee_per_gas = web3_client.max_priority_fee_per_gas()
base_fee = int(web3_client.base_fee_per_gas() / 40000) # make it small
max_fee_per_gas = base_fee + max_priority_fee_per_gas

cu_price = None
for data in data_list:
instruction_code = base58.b58decode(data).hex()[0:2]
if instruction_code == "03":
cu_price = int.from_bytes(bytes.fromhex(base58.b58decode(data).hex()[2:]), "little")
tx_params = web3_client.make_raw_tx_eip_1559(
chain_id="auto",
from_=account.address,
to=None,
value=0,
nonce="auto",
gas="auto",
max_priority_fee_per_gas=max_priority_fee_per_gas,
max_fee_per_gas=max_fee_per_gas,
data=contract_iface["bin"],
access_list=None,
)

if cu_price is not None:
assert cu_price > 0
else:
raise Exception(f"Compute Budget instruction is not found in Solana transaction {solana_transaction}")
receipt = web3_client.send_transaction(account=account, transaction=tx_params)
solana_transaction_hashes = web3_client.get_solana_trx_by_neon(receipt["transactionHash"].hex())["result"]
assert len(solana_transaction_hashes) > 1

# first transactions are "WriteToHolder", so we're interested only in the last one
solana_transaction_hash = solana_transaction_hashes[-1]
solana_transaction = sol_client.get_transaction_with_wait(Signature.from_string(solana_transaction_hash))

# get ComputeBudget index
compute_budget_index = -1
for index, account_key in enumerate(solana_transaction.value.transaction.transaction.message.account_keys):
if account_key == COMPUTE_BUDGET_ID:
compute_budget_index = index
break
assert compute_budget_index >= 0, "ComputeBudget not found"

# get setComputeUnitLimit and setComputeUnitPrice values
cu_price_actual = compute_unit_limit = 0
for instruction in solana_transaction.value.transaction.transaction.message.instructions:
if instruction.program_id_index == compute_budget_index:
decoded_data = base58.b58decode(instruction.data)
instruction_code = decoded_data[:1]
instruction_data = int.from_bytes(decoded_data[1:], "little")

match instruction_code:
case InstructionTags.SET_COMPUTE_UNIT_PRICE:
cu_price_actual = instruction_data
case InstructionTags.SET_COMPUTE_UNIT_LIMIT:
compute_unit_limit = instruction_data

# validate formula computeUnitPrice = baseFeePerGas∗10^{10} / computeUnitLimit / maxPriorityFeePerGas
cu_price_expected = int(base_fee * 10**10 / compute_unit_limit / max_priority_fee_per_gas)
assert cu_price_actual == cu_price_expected, f"Actual: {cu_price_actual}, Expected: {cu_price_expected}"


@allure.feature("EIP Verifications")
@allure.story("EIP-1559: Verify JSON-RPC method eth_maxPriorityFeePerGas")
@pytest.mark.usefixtures("eip1559_setup")
@pytest.mark.eip_1559
class TestRpcMaxPriorityFeePerGas:
@pytest.mark.need_eip1559_blocks(10)
def test_positive(
Expand All @@ -514,14 +588,15 @@ def test_positive(
max_priority_fee_per_gas = int(response["result"], 16)

fee_history: web3.types.FeeHistory = web3_client._web3.eth.fee_history(10, "pending", [5])
estimated_max_priority_fee_per_gas = _fee_history_priority_fee_estimate(fee_history=fee_history)
assert abs(max_priority_fee_per_gas - estimated_max_priority_fee_per_gas) <= 2000000000
expected_max_priority_fee_per_gas = fee_history["reward"][-1][-1] # latest reward
assert max_priority_fee_per_gas == expected_max_priority_fee_per_gas


@allure.feature("EIP Verifications")
@allure.story("EIP-1559: Verify JSON-RPC method eth_feeHistory")
@pytest.mark.usefixtures("eip1559_setup")
@pytest.mark.neon_only
@pytest.mark.eip_1559
class TestRpcFeeHistory:
"""
eth_feeHistory
Expand Down Expand Up @@ -761,6 +836,7 @@ def test_negative_cases(
@allure.feature("EIP Verifications")
@allure.story("EIP-1559: Verify accessList does not break transactions")
@pytest.mark.usefixtures("accounts", "web3_client")
@pytest.mark.eip_1559
class TestAccessList:
web3_client: NeonChainWeb3Client
accounts: EthAccounts
Expand Down Expand Up @@ -810,6 +886,7 @@ def test_deploy(
@allure.feature("EIP Verifications")
@allure.story("EIP-1559: multiple tokens")
@pytest.mark.neon_only
@pytest.mark.eip_1559
class TestMultipleTokens:
@pytest.mark.multipletokens
def test_transfer_positive(
Expand Down
8 changes: 4 additions & 4 deletions integration/tests/basic/evm/opcodes/test_base_opcodes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import allure
import pytest
import web3
from web3.contract import Contract

from utils.accounts import EthAccounts
from utils.consts import ZERO_HASH
Expand All @@ -26,7 +27,7 @@ def mcopy_checker(self, web3_client, faucet, accounts):
return contract

@pytest.fixture(scope="class")
def basefee_checker(self, web3_client, accounts):
def basefee_checker(self, web3_client, accounts) -> Contract:
contract, _ = web3_client.deploy_and_get_contract(
contract="opcodes/EIP1559BaseFee.sol",
contract_name="BaseFeeOpcode",
Expand Down Expand Up @@ -124,16 +125,15 @@ def test_base_fee_trx_type_0(
base_fee_from_log = basefee_checker.events.Log().process_receipt(resp)[0]["args"]["baseFee"]
assert base_fee_from_log == web3_client.gas_price()

@pytest.mark.eip_1559
def test_base_fee_trx_type_2(
self,
web3_client: NeonChainWeb3Client,
accounts: EthAccounts,
basefee_checker,
basefee_checker: Contract,
):
tx = web3_client.make_raw_tx(accounts[0], tx_type=TransactionType.EIP_1559)
instruction_tx = basefee_checker.functions.baseFeeTrx().build_transaction(tx)
instruction_tx["maxFeePerGas"] = 3000000000
instruction_tx["maxPriorityFeePerGas"] = 2500000000
resp = web3_client.send_transaction(accounts[0], instruction_tx)
base_fee_from_log = basefee_checker.events.Log().process_receipt(resp)[0]["args"]["baseFee"]
# Neon specific, it uses maxPriorityFee to pay an Operator
Expand Down
3 changes: 2 additions & 1 deletion integration/tests/basic/rpc/test_eip_1559_eth_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@allure.feature("EIP Verifications")
@allure.story("EIP-1559: Verify new fields in eth_ JSON-RPC methods")
@pytest.mark.neon_only
@pytest.mark.eip_1559
class TestRpcEthMethods:
def test_get_transaction_by_hash(
self,
Expand All @@ -22,7 +23,7 @@ def test_get_transaction_by_hash(

base_fee_per_gas = web3_client.base_fee_per_gas()
max_priority_fee_per_gas = web3_client._web3.eth._max_priority_fee() # noqa
max_fee_per_gas = (5 * base_fee_per_gas) + max_priority_fee_per_gas
max_fee_per_gas = (2 * base_fee_per_gas) + max_priority_fee_per_gas

receipt = web3_client.send_tokens_eip_1559(
from_=sender,
Expand Down
5 changes: 3 additions & 2 deletions integration/tests/basic/rpc/test_eip_1559_neon_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@allure.feature("EIP Verifications")
@allure.story("EIP-1559: Verify new fields in neon_ JSON-RPC methods")
@pytest.mark.neon_only
@pytest.mark.eip_1559
class TestRpcNeonMethods:
def test_neon_get_transaction_by_sender_nonce(
self,
Expand All @@ -21,7 +22,7 @@ def test_neon_get_transaction_by_sender_nonce(
nonce = web3_client.get_nonce(address=sender.address)
base_fee_per_gas = web3_client.base_fee_per_gas()
max_priority_fee_per_gas = web3_client._web3.eth._max_priority_fee() # noqa
max_fee_per_gas = (5 * base_fee_per_gas) + max_priority_fee_per_gas
max_fee_per_gas = (2 * base_fee_per_gas) + max_priority_fee_per_gas

web3_client.send_tokens_eip_1559(
from_=sender,
Expand Down Expand Up @@ -75,7 +76,7 @@ def test_neon_get_transaction_receipt(

base_fee_per_gas = web3_client.base_fee_per_gas()
max_priority_fee_per_gas = web3_client.max_priority_fee_per_gas()
max_fee_per_gas = (5 * base_fee_per_gas) + max_priority_fee_per_gas
max_fee_per_gas = (2 * base_fee_per_gas) + max_priority_fee_per_gas

receipt = web3_client.send_tokens_eip_1559(
from_=sender,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def test_send_simple_single_trx(self, web3_client_sol, neon_user, common_contrac
assert pending_trx[hex(tx.nonce)][0]["status"] in ("Done", "InProgress")
assert common_contract.functions.getNumber().call() == contract_data

@pytest.mark.eip_1559
def test_multiple_scheduled_trx(self, web3_client_sol, neon_user, common_contract, evm_loader, treasury_pool):
nonce = web3_client_sol.get_nonce(neon_user.checksum_address)
contract_data = 18
Expand Down Expand Up @@ -77,6 +78,7 @@ def test_multiple_scheduled_trx(self, web3_client_sol, neon_user, common_contrac
assert pending_trx[hex(nonce)][0]["status"] == "Done"
assert pending_trx[hex(nonce)][0]["hash"][2:] == trxs[0].hash().hex()

@pytest.mark.eip_1559
def test_multiple_scheduled_trx_with_failed_trx(
self, web3_client_sol, neon_user, treasury_pool, revert_contract_caller, event_caller_contract, evm_loader
):
Expand Down Expand Up @@ -225,6 +227,7 @@ def test_scheduled_trx_send_tokens_to_sol_chain_contract(
assert event_logs[0].args.value == value
assert event_logs[0].event == "IndexedArgs"

@pytest.mark.eip_1559
def test_scheduled_trx_with_timestamp(
self, block_timestamp_contract, web3_client_sol, neon_user, treasury_pool, evm_loader, json_rpc_client
):
Expand Down Expand Up @@ -277,6 +280,7 @@ def test_scheduled_trx_with_timestamp(
assert added_timestamp <= int(tx_block_timestamp, 16)
assert contract.functions.getDataFromMapping(added_timestamp).call() == [v1, v2]

@pytest.mark.eip_1559
def test_scheduled_trx_with_small_gas_limit(
self, block_timestamp_contract, web3_client_sol, neon_user, treasury_pool, evm_loader, event_caller_contract
):
Expand Down
Loading
Loading