Skip to content

Instantly share code, notes, and snippets.

@jbowen93
Last active February 14, 2022 17:35
Show Gist options
  • Save jbowen93/6e811954cac6aa634e123dfd12ab6321 to your computer and use it in GitHub Desktop.
Save jbowen93/6e811954cac6aa634e123dfd12ab6321 to your computer and use it in GitHub Desktop.

Still Working through evmos issue #11

Debugging why eth_GetTransactionReceipt isn't working

Debugging in optimint/state/txindex/kv/kv.go

First stop

for i, c := range conditions {

Second stop:

filteredHashes = txi.match(ctx, c, startKeyForCondition(c, height), filteredHashes, true)

One condition with
Composite Key: ethereum_tx.ethereumTxHash
OP: 4 (Equals)
Operand: 0x8f65e44b2f9aaafa89be3c71f22d73e96c4b9822c8a17208793209a9308492fb

Third stop:

func (txi *TxIndex) match(

Fourth stop:

it := txi.store.PrefixIterator(startKeyBz)

Fifth stop:

if len(tmpHashes) == 0 || firstRun {

So we're looking through all the coniditions and trying to find a match for the an OpEquals for the ethereum TX hash.

Lets go look at the StoreBatch calls and see what is getting stored

Our Tx hash is: 0xfbf11b76caa58558e4376b04bcb3d5caa4cc683358e2bebb3d7f79fcd1a79135

Debugging in optimint/state/txindex/kv/kv.go

First stop

storeBatch.Set(keyForHeight(result)

We get the above Tx in batch.ops[0]

Second stop

err := txi.indexEvents(result, hash, storeBatch)

The indexEvents result.Result.Events slice is empty. Why?

Look at

func (txi *TxIndex) Index(result *abci.TxResult) error {

Up one level to optimint/state/txindex/indexer_service.go

First stop

batch := NewBatch(eventDataHeader.NumTxs)

Second stop

txResult := msg2.Data().(types.EventDataTx).TxResult

This call results in a txResult.Results.Events slice that is nil! Is a peer to peer transaction supposed to have an event?

First error

0: (code: -32000, message: rpc error: code = Unknown desc = rpc error: code = Internal desc = failed to load evm config: unknown request, data: None)

Matching Cevmos log

10:59PM INF ABCIQuery data=0AF5047B2266726F6D223A22307837343530633461643161353038613835336235356562646233653262356364346534346330356366222C22746F223A6E756C6C2C22676173223A6E756C6C2C226761735072696365223A6E756C6C2C226D6178466565506572476173223A6E756C6C2C226D61785072696F72697479466565506572476173223A6E756C6C2C2276616C7565223A6E756C6C2C226E6F6E6365223A22307839222C2264617461223A2230783630383036303430353233343830313536303066353736303030383066643562353036306163383036313030316536303030333936303030663366653630383036303430353233343830313536303066353736303030383066643562353036303034333631303630333235373630303033353630653031633830363332653634636563313134363033373537383036333630353733363164313436303463353735623630303038306664356236303030353436303430353139303831353236303230303136303430353138303931303339306633356236303563363035373336363030343630356535363562363030303535353635623030356236303030363032303832383430333132313536303666353736303030383066643562353033353931393035303536666561323634363937303636373335383232313232303636363736323664333365353362303431313435366536373266386233626534326331303134313239396635313565313035336365616436663834313736623336343733366636633633343330303038306130303333222C22696E707574223A6E756C6C2C226163636573734C697374223A5B5D2C22636861696E4964223A22307832333238227D10C0F0F50B module=events path=/ethermint.evm.v1.Query/EstimateGas result={"code":6,"codespace":"sdk","height":"98","index":"0","info":"","key":null,"log":"rpc error: code = Internal desc = failed to load evm config: unknown request","proofOps":null,"value":null}

From ethermint/x/evm/keeper/grpc_query.go

cfg, err := k.EVMConfig(ctx)

Failing to load coinbase address...

From ethermint/x/evm/keeper/state_transition.go

func (k Keeper) GetCoinbaseAddress(ctx sdk.Context) (common.Address, error) {

Idk how the hell this was still there but whatever it's fixed now.

Contract deployment has so many errors!

12:11AM ERR account not found error="account evmos1ww2crxtfc8kdnd7k42yz4k37mgps32grlcvex0 does not exist: unknown address" cosmos-address=evmos1ww2crxtfc8kdnd7k42yz4k37mgps32grlcvex0 ethereum-address=0x7395819969c1ECD9b7D6Aa882ADA3eDa0308A903 module=evm

From ethermint/x/evm/keeper/statedb.go

cosmosAddr := sdk.AccAddress(addr.Bytes())

From ethereum/[email protected]/core/vm/evm.go

contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))

then

func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode) ([]byte, common.Address, uint64, error) {

Error

account evmos1l4djnmk86fkm2zsh4t0n8un5chtsr8jx59wpjm does not exist

From Genesis

{
    "@type": "/cosmos.staking.v1beta1.MsgCreateValidator",
    "description": {
        "moniker": "localtestnet",
        "identity": "",
        "website": "",
        "security_contact": "",
        "details": ""
    },
    "commission": {
        "rate": "0.100000000000000000",
        "max_rate": "0.200000000000000000",
        "max_change_rate": "0.010000000000000000"
    },
    "min_self_delegation": "1",
    "delegator_address": "evmos18z729jvxf5q6wr5j23krqmp8exf42nehc2022m",
    "validator_address": "evmosvaloper18z729jvxf5q6wr5j23krqmp8exf42neh4yq6tx",
    "pubkey": {
        "@type": "/cosmos.crypto.ed25519.PubKey",
        "key": "ljzShtSBut3HF4pVDDp8oCFCjXvn+XowqTvz0f5GXZo="
    },
    "value": {
        "denom": "aphoton",
        "amount": "1000000000000000000000"
    }
}

Naive guess is that it's checking for the existence of a Cosmos address mapping from the generated contract address?

Maybe this is a red herrring, doesn't seem to actually break anything

Also get

t=2022-02-12T01:36:20+0000 lvl=warn msg="Served eth_createAccessList"      conn=192.167.0.1:64172 reqid=4 t="15.125µs"               err="the method eth_createAccessList does not exist/is not available"

From ethermint/x/evm/types/query.pb.go

err := c.cc.Invoke(ctx, "/ethermint.evm.v1.Query/ValidatorAccount", in, out, opts...)

returns status.Error

Maybe

res, err := e.queryClient.ValidatorAccount(ctx, req)

Consensus Address is: evmosvalcons1x24ffaaskjq6j0y62xuexeqard95rq6kgwt7cf

Is here in ethermint/x/evm/types/query.pb.go

err := c.cc.Invoke(ctx, "/ethermint.evm.v1.Query/ValidatorAccount", in, out, opts...)

This goes to ethermint/x/evm/keeper/grpc_query.go

func (k Keeper) ValidatorAccount(c context.Context, req *types.QueryValidatorAccountRequest) (*types.QueryValidatorAccountResponse, error) {

From [email protected]/x/staking/keeper/validator.go

func (k Keeper) GetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) (validator types.Validator, found bool) {

We get a nil response at

opAddr := store.Get(types.GetValidatorByConsAddrKey(consAddr))

Complete Path

ethermint/rpc/ethereum/namespaces/eth/api.go

return e.backend.GetBlockByNumber(ethBlockNum, fullTx)

ethermint/rpc/ethereum/backend/feebackend.go

ethBlock, err := e.GetBlockByNumber(rpctypes.BlockNumber(blockID), true)

ethermint/rpc/ethereum/backend/backend.go

resBlock, err := e.GetTendermintBlockByNumber(blockNum)

ethermint/rpc/ethereum/backend/backend.go

resBlock, err := e.clientCtx.Client.Block(e.ctx, &height)

optimint/rpc/client/client.go

block, err := c.node.Store.LoadBlock(heightValue)

ethermint/rpc/ethereum/backend/backend.go

res, err := e.EthBlockFromTendermint(resBlock.Block, fullTx)

ethermint/rpc/ethereum/backend/backend.go

res, err := e.queryClient.ValidatorAccount(ctx, req)

ethermint/x/evm/types/query.pb.go

err := c.cc.Invoke(ctx, "/ethermint.evm.v1.Query/ValidatorAccount", in, out, opts...)

ethermint/x/evm/keeper/grpc_query.go

validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, consAddr)

[email protected]/x/staking/keeper/validator.go

opAddr := store.Get(types.GetValidatorByConsAddrKey(consAddr))

/Users/joshbowen/go/pkg/mod/github.com/tharsis/[email protected]/store/gaskv/store.go

value = gs.parent.Get(key)

[email protected]/store/cachekv/store.go

value = store.parent.Get(key)

[email protected]/store/iavl/store.go

_, value := st.tree.Get(key)

Notes:

  • The root of the failure is that the account isn't found. Where is the account address coming from?
  • The call to EthBlockFromTendermint has a block without a height or any Txs
  • The .evmosd/config/genesis.json contains no evmosvalcons values

Ref: https://evmos.dev/basics/accounts.html

Our initial key this run is evmosvalcons18z729jvxf5q6wr5j23krqmp8exf42nehphnx88 which can be retrieved with

evmosd keys show mykey --bech cons

The hash is the proposerAddress

The proposerAddress is populated in optimint/rpc/client/client.go

block, err := c.node.Store.LoadBlock(heightValue)
func ToABCIBlock(block *types.Block) (*tmtypes.Block, error) {

The ProposerAddress is the same in the BlockIndexing flow.

Digging into block production

optimint/block/manager.go

block := m.executor.CreateBlock(newHeight, lastCommit, lastHeaderHash, m.lastState)

evmos/optimint/state/executor.go

block := &types.Block{

optimint/block/manager.go

newState, _, err := m.executor.ApplyBlock(ctx, m.lastState, block)

The ProposerAddress is in the BlockExecutor

return &BlockExecutor{

Initial call is optimint/block/manager.go

proposerAddress, err := getAddress(proposerKey)

Had to restart it all

Hash = evmos1zkz9c5flza4yutgaargf0ey3j5nc2f8ts5au5k

ethermint/server/start.go

tmNode, err := optinode.NewNode(

/Users/joshbowen/Code/jbowen93/evmos/optimint/node/node.go

blockManager, err := block.NewManager(nodeKey, conf.BlockManagerConfig, genesis, s, mp, proxyApp.Consensus(), dalc, eventBus, logger.With("module", "BlockManager"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment