imp(tests): prune node integration tests (#1212)
* first pass * extra comment * fixed pruned node tests. Fix getBalance on pruned. Fix BaseFee on pruned. * fix tests execution * check logs on tests * address pr comments * address comments * Update rpc/namespaces/ethereum/eth/api.go * update error msg check * fix lint * fix linter * fix linter * fix py lint * test lint * fix lint * pin golangcli version * pin golanci version * pin lint to version 0.48 * fix linter * fix last linter last file Co-authored-by: ramacarlucho <ramirocarlucho@gmail.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
7331cd2065
commit
ccbaf1fe05
4
.github/workflows/lint.yml
vendored
4
.github/workflows/lint.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
go.sum
|
go.sum
|
||||||
- uses: golangci/golangci-lint-action@v3
|
- uses: golangci/golangci-lint-action@v3
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: v1.48.0
|
||||||
args: --timeout 10m
|
args: --timeout 10m
|
||||||
github-token: ${{ secrets.github_token }}
|
github-token: ${{ secrets.github_token }}
|
||||||
# Check only if there are differences in the source code
|
# Check only if there are differences in the source code
|
||||||
@ -59,7 +59,7 @@ jobs:
|
|||||||
PATTERNS: |
|
PATTERNS: |
|
||||||
**/**.py
|
**/**.py
|
||||||
- run: |
|
- run: |
|
||||||
nix-shell -I nixpkgs=./nix -p test-env --run "make lint-py"
|
nix-shell -I nixpkgs=./nix -p test-env --run "make lint-py"
|
||||||
if: env.GIT_DIFF
|
if: env.GIT_DIFF
|
||||||
gomod2nix:
|
gomod2nix:
|
||||||
name: Check gomod2nix.toml file is up to date
|
name: Check gomod2nix.toml file is up to date
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/*Package ante defines the SDK auth module's AnteHandler as well as an internal
|
/*
|
||||||
|
Package ante defines the SDK auth module's AnteHandler as well as an internal
|
||||||
AnteHandler for an Ethereum transaction (i.e MsgEthereumTx).
|
AnteHandler for an Ethereum transaction (i.e MsgEthereumTx).
|
||||||
|
|
||||||
During CheckTx, the transaction is passed through a series of
|
During CheckTx, the transaction is passed through a series of
|
||||||
|
@ -62,7 +62,7 @@ func (app *EthermintApp) ExportAppStateAndValidators(
|
|||||||
|
|
||||||
// prepare for fresh start at zero height
|
// prepare for fresh start at zero height
|
||||||
// NOTE zero height genesis is a temporary feature which will be deprecated
|
// NOTE zero height genesis is a temporary feature which will be deprecated
|
||||||
// in favor of export at a block height
|
// in favor of export at a block height
|
||||||
func (app *EthermintApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) error {
|
func (app *EthermintApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) error {
|
||||||
applyAllowedAddrs := false
|
applyAllowedAddrs := false
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ func TestAppImportExport(t *testing.T) {
|
|||||||
|
|
||||||
fmt.Printf("importing genesis...\n")
|
fmt.Printf("importing genesis...\n")
|
||||||
|
|
||||||
// nolint: dogsled
|
//nolint: dogsled
|
||||||
_, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
_, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
||||||
require.NoError(t, err, "simulation setup failed")
|
require.NoError(t, err, "simulation setup failed")
|
||||||
|
|
||||||
|
@ -38,14 +38,16 @@ const (
|
|||||||
mnemonicEntropySize = 256
|
mnemonicEntropySize = 256
|
||||||
)
|
)
|
||||||
|
|
||||||
/* RunAddCmd
|
/*
|
||||||
|
RunAddCmd
|
||||||
input
|
input
|
||||||
- bip39 mnemonic
|
- bip39 mnemonic
|
||||||
- bip39 passphrase
|
- bip39 passphrase
|
||||||
- bip44 path
|
- bip44 path
|
||||||
- local encryption password
|
- local encryption password
|
||||||
|
|
||||||
output
|
output
|
||||||
- armor encrypted private key (saved to file)
|
- armor encrypted private key (saved to file)
|
||||||
*/
|
*/
|
||||||
func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *bufio.Reader) error {
|
func RunAddCmd(ctx client.Context, cmd *cobra.Command, args []string, inBuf *bufio.Reader) error {
|
||||||
var err error
|
var err error
|
||||||
|
@ -40,7 +40,7 @@ func SetBech32Prefixes(config *sdk.Config) {
|
|||||||
func SetBip44CoinType(config *sdk.Config) {
|
func SetBip44CoinType(config *sdk.Config) {
|
||||||
config.SetCoinType(ethermint.Bip44CoinType)
|
config.SetCoinType(ethermint.Bip44CoinType)
|
||||||
config.SetPurpose(sdk.Purpose) // Shared
|
config.SetPurpose(sdk.Purpose) // Shared
|
||||||
config.SetFullFundraiserPath(ethermint.BIP44HDPath) // nolint: staticcheck
|
config.SetFullFundraiserPath(ethermint.BIP44HDPath) //nolint: staticcheck
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterDenoms registers the base and display denominations to the SDK.
|
// RegisterDenoms registers the base and display denominations to the SDK.
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// BackendI implements the Cosmos and EVM backend.
|
// BackendI implements the Cosmos and EVM backend.
|
||||||
type BackendI interface { // nolint: revive
|
type BackendI interface { //nolint: revive
|
||||||
CosmosBackend
|
CosmosBackend
|
||||||
EVMBackend
|
EVMBackend
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ func (a *API) BlockProfile(file string, nsec uint) error {
|
|||||||
|
|
||||||
// CpuProfile turns on CPU profiling for nsec seconds and writes
|
// CpuProfile turns on CPU profiling for nsec seconds and writes
|
||||||
// profile data to file.
|
// profile data to file.
|
||||||
func (a *API) CpuProfile(file string, nsec uint) error { // nolint: golint, stylecheck, revive
|
func (a *API) CpuProfile(file string, nsec uint) error { //nolint: golint, stylecheck, revive
|
||||||
a.logger.Debug("debug_cpuProfile", "file", file, "nsec", nsec)
|
a.logger.Debug("debug_cpuProfile", "file", file, "nsec", nsec)
|
||||||
if err := a.StartCPUProfile(file); err != nil {
|
if err := a.StartCPUProfile(file); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -128,7 +128,7 @@ func (e *PublicAPI) ProtocolVersion() hexutil.Uint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config.
|
// ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config.
|
||||||
func (e *PublicAPI) ChainId() (*hexutil.Big, error) { // nolint
|
func (e *PublicAPI) ChainId() (*hexutil.Big, error) { //nolint
|
||||||
e.logger.Debug("eth_chainId")
|
e.logger.Debug("eth_chainId")
|
||||||
// if current block is at or past the EIP-155 replay-protection fork block, return chainID from config
|
// if current block is at or past the EIP-155 replay-protection fork block, return chainID from config
|
||||||
bn, err := e.backend.BlockNumber()
|
bn, err := e.backend.BlockNumber()
|
||||||
@ -294,6 +294,11 @@ func (e *PublicAPI) GetBalance(address common.Address, blockNrOrHash rpctypes.Bl
|
|||||||
return nil, errors.New("invalid balance")
|
return nil, errors.New("invalid balance")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// balance can only be negative in case of pruned node
|
||||||
|
if val.IsNegative() {
|
||||||
|
return nil, errors.New("couldn't fetch balance. Node state is pruned")
|
||||||
|
}
|
||||||
|
|
||||||
return (*hexutil.Big)(val.BigInt()), nil
|
return (*hexutil.Big)(val.BigInt()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ func NewRangeFilter(logger log.Logger, backend Backend, begin, end int64, addres
|
|||||||
// Flatten the address and topic filter clauses into a single bloombits filter
|
// Flatten the address and topic filter clauses into a single bloombits filter
|
||||||
// system. Since the bloombits are not positional, nil topics are permitted,
|
// system. Since the bloombits are not positional, nil topics are permitted,
|
||||||
// which get flattened into a nil byte slice.
|
// which get flattened into a nil byte slice.
|
||||||
var filtersBz [][][]byte // nolint: prealloc
|
var filtersBz [][][]byte //nolint: prealloc
|
||||||
if len(addresses) > 0 {
|
if len(addresses) > 0 {
|
||||||
filter := make([][]byte, len(addresses))
|
filter := make([][]byte, len(addresses))
|
||||||
for i, address := range addresses {
|
for i, address := range addresses {
|
||||||
|
@ -15,9 +15,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// QueryClient defines a gRPC Client used for:
|
// QueryClient defines a gRPC Client used for:
|
||||||
// - Transaction simulation
|
// - Transaction simulation
|
||||||
// - EVM module queries
|
// - EVM module queries
|
||||||
// - Fee market module queries
|
// - Fee market module queries
|
||||||
type QueryClient struct {
|
type QueryClient struct {
|
||||||
tx.ServiceClient
|
tx.ServiceClient
|
||||||
evmtypes.QueryClient
|
evmtypes.QueryClient
|
||||||
|
9
tests/integration_tests/.isort.cfg
Normal file
9
tests/integration_tests/.isort.cfg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[settings]
|
||||||
|
# compatible with black
|
||||||
|
# https://black.readthedocs.io/en/stable/the_black_code_style.html
|
||||||
|
multi_line_output = 3
|
||||||
|
include_trailing_comma = True
|
||||||
|
force_grid_wrap = 0
|
||||||
|
use_parentheses = True
|
||||||
|
ensure_newline_before_comments = True
|
||||||
|
line_length = 88
|
12
tests/integration_tests/configs/pruned_node.jsonnet
Normal file
12
tests/integration_tests/configs/pruned_node.jsonnet
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
local config = import 'default.jsonnet';
|
||||||
|
|
||||||
|
config {
|
||||||
|
'ethermint_9000-1'+: {
|
||||||
|
'app-config'+: {
|
||||||
|
pruning: 'everything',
|
||||||
|
'state-sync'+: {
|
||||||
|
'snapshot-interval': 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
142
tests/integration_tests/test_pruned_node.py
Normal file
142
tests/integration_tests/test_pruned_node.py
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from eth_bloom import BloomFilter
|
||||||
|
from eth_utils import abi, big_endian_to_int
|
||||||
|
from hexbytes import HexBytes
|
||||||
|
from web3.datastructures import AttributeDict
|
||||||
|
|
||||||
|
from .network import setup_custom_ethermint
|
||||||
|
from .utils import (
|
||||||
|
ADDRS,
|
||||||
|
CONTRACTS,
|
||||||
|
KEYS,
|
||||||
|
deploy_contract,
|
||||||
|
sign_transaction,
|
||||||
|
w3_wait_for_new_blocks,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def pruned(request, tmp_path_factory):
|
||||||
|
"""start-cronos
|
||||||
|
params: enable_auto_deployment
|
||||||
|
"""
|
||||||
|
yield from setup_custom_ethermint(
|
||||||
|
tmp_path_factory.mktemp("pruned"),
|
||||||
|
26900,
|
||||||
|
Path(__file__).parent / "configs/pruned_node.jsonnet",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_pruned_node(pruned):
|
||||||
|
"""
|
||||||
|
test basic json-rpc apis works in pruned node
|
||||||
|
"""
|
||||||
|
w3 = pruned.w3
|
||||||
|
erc20 = deploy_contract(
|
||||||
|
w3,
|
||||||
|
CONTRACTS["TestERC20A"],
|
||||||
|
key=KEYS["validator"],
|
||||||
|
)
|
||||||
|
tx = erc20.functions.transfer(ADDRS["community"], 10).buildTransaction(
|
||||||
|
{"from": ADDRS["validator"]}
|
||||||
|
)
|
||||||
|
signed = sign_transaction(w3, tx, KEYS["validator"])
|
||||||
|
txhash = w3.eth.send_raw_transaction(signed.rawTransaction)
|
||||||
|
print("wait for prunning happens")
|
||||||
|
w3_wait_for_new_blocks(w3, 10)
|
||||||
|
|
||||||
|
tx_receipt = w3.eth.get_transaction_receipt(txhash.hex())
|
||||||
|
assert len(tx_receipt.logs) == 1
|
||||||
|
expect_log = {
|
||||||
|
"address": erc20.address,
|
||||||
|
"topics": [
|
||||||
|
HexBytes(
|
||||||
|
abi.event_signature_to_log_topic("Transfer(address,address,uint256)")
|
||||||
|
),
|
||||||
|
HexBytes(b"\x00" * 12 + HexBytes(ADDRS["validator"])),
|
||||||
|
HexBytes(b"\x00" * 12 + HexBytes(ADDRS["community"])),
|
||||||
|
],
|
||||||
|
"data": "0x000000000000000000000000000000000000000000000000000000000000000a",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"logIndex": 0,
|
||||||
|
"removed": False,
|
||||||
|
}
|
||||||
|
assert expect_log.items() <= tx_receipt.logs[0].items()
|
||||||
|
|
||||||
|
# check get_balance and eth_call don't work on pruned state
|
||||||
|
# we need to check error message here.
|
||||||
|
# `get_balance` returns unmarshallJson and thats not what it should
|
||||||
|
res = w3.eth.get_balance(ADDRS["validator"], "latest")
|
||||||
|
assert res > 0
|
||||||
|
|
||||||
|
pruned_res = pruned.w3.provider.make_request(
|
||||||
|
"eth_getBalance", [ADDRS["validator"], hex(tx_receipt.blockNumber)]
|
||||||
|
)
|
||||||
|
assert "error" in pruned_res
|
||||||
|
assert (
|
||||||
|
pruned_res["error"]["message"] == "couldn't fetch balance. Node state is pruned"
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
erc20.caller(block_identifier=tx_receipt.blockNumber).balanceOf(
|
||||||
|
ADDRS["validator"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# check block bloom
|
||||||
|
block = w3.eth.get_block(tx_receipt.blockNumber)
|
||||||
|
|
||||||
|
assert "baseFeePerGas" in block
|
||||||
|
assert block.miner == "0x0000000000000000000000000000000000000000"
|
||||||
|
bloom = BloomFilter(big_endian_to_int(block.logsBloom))
|
||||||
|
assert HexBytes(erc20.address) in bloom
|
||||||
|
for topic in expect_log["topics"]:
|
||||||
|
assert topic in bloom
|
||||||
|
|
||||||
|
tx1 = w3.eth.get_transaction(txhash)
|
||||||
|
tx2 = w3.eth.get_transaction_by_block(
|
||||||
|
tx_receipt.blockNumber, tx_receipt.transactionIndex
|
||||||
|
)
|
||||||
|
exp_tx = AttributeDict(
|
||||||
|
{
|
||||||
|
"from": "0x57f96e6B86CdeFdB3d412547816a82E3E0EbF9D2",
|
||||||
|
"gas": 51542,
|
||||||
|
"input": (
|
||||||
|
"0xa9059cbb000000000000000000000000378c50d9264c63f3f92b806d4ee56e"
|
||||||
|
"9d86ffb3ec000000000000000000000000000000000000000000000000000000"
|
||||||
|
"000000000a"
|
||||||
|
),
|
||||||
|
"nonce": 2,
|
||||||
|
"to": erc20.address,
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"value": 0,
|
||||||
|
"type": "0x2",
|
||||||
|
"accessList": [],
|
||||||
|
"chainId": "0x2328",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert tx1 == tx2
|
||||||
|
for name in exp_tx.keys():
|
||||||
|
assert tx1[name] == tx2[name] == exp_tx[name]
|
||||||
|
|
||||||
|
logs = w3.eth.get_logs(
|
||||||
|
{
|
||||||
|
"fromBlock": tx_receipt.blockNumber,
|
||||||
|
"toBlock": tx_receipt.blockNumber,
|
||||||
|
}
|
||||||
|
)[0]
|
||||||
|
assert (
|
||||||
|
"address" in logs
|
||||||
|
and logs["address"] == "0x68542BD12B41F5D51D6282Ec7D91D7d0D78E4503"
|
||||||
|
)
|
||||||
|
assert "topics" in logs and len(logs["topics"]) == 3
|
||||||
|
assert logs["topics"][0] == HexBytes(
|
||||||
|
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
|
||||||
|
)
|
||||||
|
assert logs["topics"][1] == HexBytes(
|
||||||
|
"0x00000000000000000000000057f96e6b86cdefdb3d412547816a82e3e0ebf9d2"
|
||||||
|
)
|
||||||
|
assert logs["topics"][2] == HexBytes(
|
||||||
|
"0x000000000000000000000000378c50d9264c63f3f92b806d4ee56e9d86ffb3ec"
|
||||||
|
)
|
@ -1,10 +1,44 @@
|
|||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
from eth_account import Account
|
from eth_account import Account
|
||||||
from web3._utils.transactions import fill_nonce, fill_transaction_defaults
|
from web3._utils.transactions import fill_nonce, fill_transaction_defaults
|
||||||
|
|
||||||
|
load_dotenv(Path(__file__).parent.parent.parent / "scripts/.env")
|
||||||
|
Account.enable_unaudited_hdwallet_features()
|
||||||
|
ACCOUNTS = {
|
||||||
|
"validator": Account.from_mnemonic(os.getenv("VALIDATOR1_MNEMONIC")),
|
||||||
|
"community": Account.from_mnemonic(os.getenv("COMMUNITY_MNEMONIC")),
|
||||||
|
"signer1": Account.from_mnemonic(os.getenv("SIGNER1_MNEMONIC")),
|
||||||
|
"signer2": Account.from_mnemonic(os.getenv("SIGNER2_MNEMONIC")),
|
||||||
|
}
|
||||||
|
KEYS = {name: account.key for name, account in ACCOUNTS.items()}
|
||||||
|
ADDRS = {name: account.address for name, account in ACCOUNTS.items()}
|
||||||
|
ETHERMINT_ADDRESS_PREFIX = "ethm"
|
||||||
|
TEST_CONTRACTS = {
|
||||||
|
"TestERC20A": "TestERC20A.sol",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def contract_path(name, filename):
|
||||||
|
return (
|
||||||
|
Path(__file__).parent
|
||||||
|
/ "contracts/artifacts/contracts/"
|
||||||
|
/ filename
|
||||||
|
/ (name + ".json")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
CONTRACTS = {
|
||||||
|
**{
|
||||||
|
name: contract_path(name, filename) for name, filename in TEST_CONTRACTS.items()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
Account.enable_unaudited_hdwallet_features()
|
Account.enable_unaudited_hdwallet_features()
|
||||||
|
|
||||||
ACCOUNTS = {
|
ACCOUNTS = {
|
||||||
@ -32,6 +66,29 @@ def wait_for_port(port, host="127.0.0.1", timeout=40.0):
|
|||||||
) from ex
|
) from ex
|
||||||
|
|
||||||
|
|
||||||
|
def w3_wait_for_new_blocks(w3, n):
|
||||||
|
begin_height = w3.eth.block_number
|
||||||
|
while True:
|
||||||
|
time.sleep(0.5)
|
||||||
|
cur_height = w3.eth.block_number
|
||||||
|
if cur_height - begin_height >= n:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def deploy_contract(w3, jsonfile, args=(), key=KEYS["validator"]):
|
||||||
|
"""
|
||||||
|
deploy contract and return the deployed contract instance
|
||||||
|
"""
|
||||||
|
acct = Account.from_key(key)
|
||||||
|
info = json.loads(jsonfile.read_text())
|
||||||
|
contract = w3.eth.contract(abi=info["abi"], bytecode=info["bytecode"])
|
||||||
|
tx = contract.constructor(*args).buildTransaction({"from": acct.address})
|
||||||
|
txreceipt = send_transaction(w3, tx, key)
|
||||||
|
assert txreceipt.status == 1
|
||||||
|
address = txreceipt.contractAddress
|
||||||
|
return w3.eth.contract(address=address, abi=info["abi"])
|
||||||
|
|
||||||
|
|
||||||
def fill_defaults(w3, tx):
|
def fill_defaults(w3, tx):
|
||||||
return fill_nonce(w3, fill_transaction_defaults(w3, tx))
|
return fill_nonce(w3, fill_transaction_defaults(w3, tx))
|
||||||
|
|
||||||
|
@ -283,8 +283,13 @@ func (k *Keeper) GetNonce(ctx sdk.Context, addr common.Address) uint64 {
|
|||||||
// GetBalance load account's balance of gas token
|
// GetBalance load account's balance of gas token
|
||||||
func (k *Keeper) GetBalance(ctx sdk.Context, addr common.Address) *big.Int {
|
func (k *Keeper) GetBalance(ctx sdk.Context, addr common.Address) *big.Int {
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
params := k.GetParams(ctx)
|
evmDenom := ""
|
||||||
coin := k.bankKeeper.GetBalance(ctx, cosmosAddr, params.EvmDenom)
|
k.paramSpace.GetIfExists(ctx, types.ParamStoreKeyEVMDenom, &evmDenom)
|
||||||
|
// if node is pruned, params is empty. Return invalid value
|
||||||
|
if evmDenom == "" {
|
||||||
|
return big.NewInt(-1)
|
||||||
|
}
|
||||||
|
coin := k.bankKeeper.GetBalance(ctx, cosmosAddr, evmDenom)
|
||||||
return coin.Amount.BigInt()
|
return coin.Amount.BigInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ func (k Keeper) GetHashFn(ctx sdk.Context) vm.GetHashFunc {
|
|||||||
// ApplyTransaction runs and attempts to perform a state transition with the given transaction (i.e Message), that will
|
// ApplyTransaction runs and attempts to perform a state transition with the given transaction (i.e Message), that will
|
||||||
// only be persisted (committed) to the underlying KVStore if the transaction does not fail.
|
// only be persisted (committed) to the underlying KVStore if the transaction does not fail.
|
||||||
//
|
//
|
||||||
// Gas tracking
|
// # Gas tracking
|
||||||
//
|
//
|
||||||
// Ethereum consumes gas according to the EVM opcodes instead of general reads and writes to store. Because of this, the
|
// Ethereum consumes gas according to the EVM opcodes instead of general reads and writes to store. Because of this, the
|
||||||
// state transition needs to ignore the SDK gas consumption mechanism defined by the GasKVStore and instead consume the
|
// state transition needs to ignore the SDK gas consumption mechanism defined by the GasKVStore and instead consume the
|
||||||
@ -309,18 +309,18 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t
|
|||||||
// If the message fails, the VM execution error with the reason will be returned to the client
|
// If the message fails, the VM execution error with the reason will be returned to the client
|
||||||
// and the transaction won't be committed to the store.
|
// and the transaction won't be committed to the store.
|
||||||
//
|
//
|
||||||
// Reverted state
|
// # Reverted state
|
||||||
//
|
//
|
||||||
// The snapshot and rollback are supported by the `statedb.StateDB`.
|
// The snapshot and rollback are supported by the `statedb.StateDB`.
|
||||||
//
|
//
|
||||||
// Different Callers
|
// # Different Callers
|
||||||
//
|
//
|
||||||
// It's called in three scenarios:
|
// It's called in three scenarios:
|
||||||
// 1. `ApplyTransaction`, in the transaction processing flow.
|
// 1. `ApplyTransaction`, in the transaction processing flow.
|
||||||
// 2. `EthCall/EthEstimateGas` grpc query handler.
|
// 2. `EthCall/EthEstimateGas` grpc query handler.
|
||||||
// 3. Called by other native modules directly.
|
// 3. Called by other native modules directly.
|
||||||
//
|
//
|
||||||
// Prechecks and Preprocessing
|
// # Prechecks and Preprocessing
|
||||||
//
|
//
|
||||||
// All relevant state transition prechecks for the MsgEthereumTx are performed on the AnteHandler,
|
// All relevant state transition prechecks for the MsgEthereumTx are performed on the AnteHandler,
|
||||||
// prior to running the transaction against the state. The prechecks run are the following:
|
// prior to running the transaction against the state. The prechecks run are the following:
|
||||||
@ -336,11 +336,11 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t
|
|||||||
//
|
//
|
||||||
// 1. set up the initial access list (iff fork > Berlin)
|
// 1. set up the initial access list (iff fork > Berlin)
|
||||||
//
|
//
|
||||||
// Tracer parameter
|
// # Tracer parameter
|
||||||
//
|
//
|
||||||
// It should be a `vm.Tracer` object or nil, if pass `nil`, it'll create a default one based on keeper options.
|
// It should be a `vm.Tracer` object or nil, if pass `nil`, it'll create a default one based on keeper options.
|
||||||
//
|
//
|
||||||
// Commit parameter
|
// # Commit parameter
|
||||||
//
|
//
|
||||||
// If commit is true, the `StateDB` will be committed, otherwise discarded.
|
// If commit is true, the `StateDB` will be committed, otherwise discarded.
|
||||||
func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context, msg core.Message, tracer vm.EVMLogger, commit bool, cfg *types.EVMConfig, txConfig statedb.TxConfig) (*types.MsgEthereumTxResponse, error) {
|
func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context, msg core.Message, tracer vm.EVMLogger, commit bool, cfg *types.EVMConfig, txConfig statedb.TxConfig) (*types.MsgEthereumTxResponse, error) {
|
||||||
|
@ -250,8 +250,8 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
|
|||||||
// CreateAccount is called during the EVM CREATE operation. The situation might arise that
|
// CreateAccount is called during the EVM CREATE operation. The situation might arise that
|
||||||
// a contract does the following:
|
// a contract does the following:
|
||||||
//
|
//
|
||||||
// 1. sends funds to sha(account ++ (nonce + 1))
|
// 1. sends funds to sha(account ++ (nonce + 1))
|
||||||
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
|
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
|
||||||
//
|
//
|
||||||
// Carrying over the balance ensures that Ether doesn't disappear.
|
// Carrying over the balance ensures that Ether doesn't disappear.
|
||||||
func (s *StateDB) CreateAccount(addr common.Address) {
|
func (s *StateDB) CreateAccount(addr common.Address) {
|
||||||
|
@ -89,7 +89,7 @@ func (log *Log) ToEthereum() *ethtypes.Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewLogsFromEth(ethlogs []*ethtypes.Log) []*Log {
|
func NewLogsFromEth(ethlogs []*ethtypes.Log) []*Log {
|
||||||
var logs []*Log // nolint: prealloc
|
var logs []*Log //nolint: prealloc
|
||||||
for _, ethlog := range ethlogs {
|
for _, ethlog := range ethlogs {
|
||||||
logs = append(logs, NewLogFromEth(ethlog))
|
logs = append(logs, NewLogFromEth(ethlog))
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ func NewLogsFromEth(ethlogs []*ethtypes.Log) []*Log {
|
|||||||
|
|
||||||
// LogsToEthereum casts the Ethermint Logs to a slice of Ethereum Logs.
|
// LogsToEthereum casts the Ethermint Logs to a slice of Ethereum Logs.
|
||||||
func LogsToEthereum(logs []*Log) []*ethtypes.Log {
|
func LogsToEthereum(logs []*Log) []*ethtypes.Log {
|
||||||
var ethLogs []*ethtypes.Log // nolint: prealloc
|
var ethLogs []*ethtypes.Log //nolint: prealloc
|
||||||
for i := range logs {
|
for i := range logs {
|
||||||
ethLogs = append(ethLogs, logs[i].ToEthereum())
|
ethLogs = append(ethLogs, logs[i].ToEthereum())
|
||||||
}
|
}
|
||||||
|
@ -71,8 +71,9 @@ func NewTxDataFromTx(tx *ethtypes.Transaction) (TxData, error) {
|
|||||||
//
|
//
|
||||||
// CONTRACT: v value is either:
|
// CONTRACT: v value is either:
|
||||||
//
|
//
|
||||||
// - {0,1} + CHAIN_ID * 2 + 35, if EIP155 is used
|
// - {0,1} + CHAIN_ID * 2 + 35, if EIP155 is used
|
||||||
// - {0,1} + 27, otherwise
|
// - {0,1} + 27, otherwise
|
||||||
|
//
|
||||||
// Ref: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
|
// Ref: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
|
||||||
func DeriveChainID(v *big.Int) *big.Int {
|
func DeriveChainID(v *big.Int) *big.Int {
|
||||||
if v == nil || v.Sign() < 1 {
|
if v == nil || v.Sign() < 1 {
|
||||||
|
@ -19,7 +19,7 @@ const (
|
|||||||
// prefix bytes for the feemarket persistent store
|
// prefix bytes for the feemarket persistent store
|
||||||
const (
|
const (
|
||||||
prefixBlockGasWanted = iota + 1
|
prefixBlockGasWanted = iota + 1
|
||||||
deprecatedPrefixBaseFee // nolint
|
deprecatedPrefixBaseFee //nolint
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
Loading…
Reference in New Issue
Block a user