Skip to content

Commit

Permalink
Merge pull request #57 from initia-labs/feat/evm-tx
Browse files Browse the repository at this point in the history
add evm-tx submodules and minor improvement for plain tx
  • Loading branch information
Vritra4 authored Aug 19, 2024
2 parents 8829ef9 + 5568a69 commit 1f7d215
Show file tree
Hide file tree
Showing 13 changed files with 4,298 additions and 5 deletions.
4 changes: 4 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ github.com/cosmos/ibc-apps/modules/async-icq/v8 v8.0.1-0.20240124225747-f055ce5b
github.com/cosmos/ibc-apps/modules/async-icq/v8 v8.0.1-0.20240124225747-f055ce5b405c/go.mod h1:D3Q380FpWRFtmUQWLosPxachi6w24Og2t5u/Tww5wtY=
github.com/cosmos/ibc-go/v8 v8.1.0/go.mod h1:o1ipS95xpdjqNcB8Drq0eI3Sn4FRLigjll42ec1ECuU=
github.com/cosmos/interchain-security/v5 v5.0.0-alpha1/go.mod h1:c4oYjNwdfPKAhxzkwzTkkWROXKeUNPvc4VJHyNWrRU8=
github.com/cosmos/interchain-security/v5 v5.0.0-rc0 h1:Sh5CDqLDS32q2WsO9k5j3NyBzmW+mm66c+kgRniCthA=
github.com/cosmos/interchain-security/v5 v5.0.0-rc0/go.mod h1:h/RkwOppo5AJj+1pkQyfjqU1MPdpohD/S6oEeAXpGZY=
github.com/cosmos/relayer/v2 v2.5.2/go.mod h1:h4Ng2QsVpxExIq5S+WvLr8slDb9MSBh82gQS4DeMwDo=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
Expand Down Expand Up @@ -857,6 +858,7 @@ github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99
github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e h1:CYRpN206UTHUinz3VJoLaBdy1gEGeJNsqT0mvswDcMw=
github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
Expand Down Expand Up @@ -1174,6 +1176,7 @@ github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7e
github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ=
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
github.com/noble-assets/forwarding v0.0.0-20240416085758-ed8e9efaf69a/go.mod h1:nMEL3w1pf7+2LAQ3jqX+XaK0GWcdnwXjwlBnX7QO9ho=
github.com/noble-assets/forwarding/v2 v2.0.0-20240514101621-172acc02aac6 h1:YQ6I+9F24PD9U/Q83/t/DCPwye8IeHXOrQWorPx2aSE=
github.com/noble-assets/forwarding/v2 v2.0.0-20240514101621-172acc02aac6/go.mod h1:fkfElMT7VJZXXqywx+OE6qsEXddT/fwKX5XNdIl747U=
github.com/nunnatsa/ginkgolinter v0.9.0/go.mod h1:FHaMLURXP7qImeH6bvxWJUpyH+2tuqe5j4rW1gxJRmI=
github.com/nunnatsa/ginkgolinter v0.14.1/go.mod h1:nY0pafUSst7v7F637e7fymaMlQqI9c0Wka2fGsDkzWg=
Expand Down Expand Up @@ -1341,6 +1344,7 @@ github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvR
github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg=
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/skip-mev/block-sdk/v2 v2.1.1/go.mod h1:AOjFICNrPpq/Cq1f97CcC7ljWhxCzmfmyz4/Ir8/xFM=
github.com/skip-mev/block-sdk/v2 v2.1.2 h1:fNKbrb+PVVzuU0JiSuWgBV4Afj5zZ1VeHQJp88wSl1g=
github.com/skip-mev/block-sdk/v2 v2.1.2/go.mod h1:kIq7SMva0/eHKTCiG/oI5XGxD4HNVK0t71TrUZqHcvA=
github.com/skip-mev/chaintestutil v0.0.0-20231221145345-f208ee3b1383/go.mod h1:FvYgT9wJSLvtBkwWp4mHo+A5/r9OkvHXJJh9u8RhGWk=
github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4=
Expand Down
200 changes: 200 additions & 0 deletions submodules/evm-tx/collect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package tx

import (
"context"
"encoding/json"
"fmt"
"time"

"cosmossdk.io/collections"
cosmoserr "cosmossdk.io/errors"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx"

abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/crypto/tmhash"
coretypes "github.com/cometbft/cometbft/rpc/core/types"

evmtypes "github.com/initia-labs/minievm/x/evm/types"

"github.com/initia-labs/kvindexer/submodules/tx/types"
)

func (sm EvmTxSubmodule) finalizeBlock(ctx context.Context, req abci.RequestFinalizeBlock, res abci.ResponseFinalizeBlock) error {
sm.Logger(ctx).Debug("finalizeBlock", "submodule", types.SubmoduleName, "txs", len(req.Txs), "height", req.Height)

if err := sm.processTxs(ctx, req, res); err != nil {
return err
}

return nil
}

func (sm EvmTxSubmodule) processTxs(ctx context.Context, req abci.RequestFinalizeBlock, res abci.ResponseFinalizeBlock) error {
// key: address, value: txs slice
accTxMap := map[string][]string{}

txHashes := []string{}
for idx, txBytes := range req.Txs {
tx, err := parseTx(sm.cdc, txBytes)
if err != nil {
sm.Logger(ctx).Info("failed to parse tx", "error", err, "index", idx)
continue
}

any, err := codectypes.NewAnyWithValue(tx)
if err != nil {
sm.Logger(ctx).Info("failed to unpack any", "error", err, "index", idx)
continue
}

txHash := tmhash.Sum(txBytes)
txHashStr := fmt.Sprintf("%x", txHash)
resultTx := coretypes.ResultTx{
Hash: txHash,
Height: req.Height,
TxResult: *res.TxResults[idx],
// No Index, Tx and Proof here. sdk.NewResponseTxResult() don't use them
}

txr := sdk.NewResponseResultTx(&resultTx, any, req.Time.UTC().Format(time.RFC3339))

if err := sm.txMap.Set(ctx, txHashStr, *txr); err != nil {
sm.Logger(ctx).Info("failed to store tx", "error", err, "index", idx)
continue
}

// get addresses from the tx
addrs, err := grepAddressesFromTx(txr)
if err != nil {
sm.Logger(ctx).Info("failed to grep addresses from tx", "error", err, "index", idx)
continue
}

for _, addr := range addrs {
accTxMap[addr] = uniqueAppend(accTxMap[addr], txHashStr)
}
txHashes = append(txHashes, txHashStr)
}

// store tx/account pair into txAccMap
for addr, txHashes := range accTxMap {
err := sm.storeAccTxs(ctx, addr, txHashes)
if err != nil {
sm.Logger(ctx).Info("failed to store tx/account pair", "error", err, "address", addr)
}
}
return sm.storeIndices(ctx, req.Height, txHashes)
}

func uniqueAppend(slice []string, elem string) []string {
for _, e := range slice {
if e == elem {
return slice
}
}
return append(slice, elem)
}

func parseTx(cdc codec.Codec, txBytes []byte) (*tx.Tx, error) {
tx := tx.Tx{}
err := cdc.Unmarshal(txBytes, &tx)
if err != nil {
return nil, err
}
return &tx, nil
}

func grepAddressesFromTx(txr *sdk.TxResponse) ([]string, error) {
grepped := []string{}
for _, event := range txr.Events {
for _, attr := range event.Attributes {
var addrs []string

if event.Type == evmtypes.EventTypeEVM && attr.Key == evmtypes.AttributeKeyLog {
contractAddr, err := extractAddressesFromEVMLog(attr.Value)
if err != nil {
continue
}
addrs = append(addrs, contractAddr)
} else {
addrs = findAllBech32Address(attr.Value)
addrs = append(addrs, findAllHexAddress(attr.Value)...)
}

for _, addr := range addrs {
accAddr, err := accAddressFromString(addr)
if err != nil {
continue
}
grepped = append(grepped, accAddr.String())
}
}
}

return grepped, nil
}

func extractAddressesFromEVMLog(attrVal string) (string, error) {
log := evmtypes.Log{}
if err := json.Unmarshal([]byte(attrVal), &log); err != nil {
return "", err
}
return convertContractAddressToBech32(log.Address)
}

func (sm EvmTxSubmodule) storeAccTxs(ctx context.Context, addr string, txHashes []string) error {
if len(txHashes) == 0 {
return nil
}
acc, err := sdk.AccAddressFromBech32(addr)
if err != nil {
sm.Logger(ctx).Info("failed to convert address", "error", err, "address", addr)
return err
}

seq, err := sm.accountSequenceMap.Get(ctx, acc)
if err != nil && !cosmoserr.IsOf(err, collections.ErrNotFound) {
return err
}

for i, txHash := range txHashes {
err = sm.txhashesByAccountMap.Set(ctx, collections.Join(acc, seq+uint64(i)), txHash)
if err != nil {
sm.Logger(ctx).Info("failed to store tx/account pair", "error", err, "address", addr, "txhash", txHash)
continue
}

}
delta := seq + uint64(len(txHashes)+1)
if err = sm.accountSequenceMap.Set(ctx, acc, delta); err != nil {
sm.Logger(ctx).Info("failed to store account sequence", "error", err, "address", addr, "delta", delta)
return err
}

return err
}

func (sm EvmTxSubmodule) storeIndices(ctx context.Context, height int64, txHashes []string) error {
for i, txHash := range txHashes {
err := sm.txhashesByHeightMap.Set(ctx, collections.Join(height, uint64(i)), txHash)
if err != nil {
sm.Logger(ctx).Info("failed to store tx/height pair", "error", err, "height", height, "txhash", txHash)
continue
}

seq, err := sm.sequence.Next(ctx)
if err != nil {
return err
}

err = sm.txhashesBySequenceMap.Set(ctx, seq, txHash)
if err != nil {
return err
}
}

return nil
}
Loading

0 comments on commit 1f7d215

Please sign in to comment.