Skip to content

Commit

Permalink
Merge tag 'v4.1.6-evm-devnet' into firehose/evm-devnet
Browse files Browse the repository at this point in the history
# Conflicts:
#	app/app.go
#	x/evm/keeper/msg_server.go
#	x/evm/module.go
#	x/evm/state/balance.go
#	x/evm/state/code.go
#	x/evm/state/nonce.go
#	x/evm/state/state.go
  • Loading branch information
maoueh committed Mar 25, 2024
2 parents d0335dd + 9fc938a commit a59e684
Show file tree
Hide file tree
Showing 65 changed files with 21,790 additions and 10,633 deletions.
68 changes: 48 additions & 20 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import (
ethcommon "github.com/ethereum/go-ethereum/common"
ethhexutil "github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"

"github.com/ethereum/go-ethereum/ethclient"
ethrpc "github.com/ethereum/go-ethereum/rpc"
"github.com/sei-protocol/sei-chain/app/antedecorators"
"github.com/sei-protocol/sei-chain/evmrpc"
"github.com/sei-protocol/sei-chain/precompiles"
Expand Down Expand Up @@ -125,6 +126,7 @@ import (
"github.com/sei-protocol/sei-chain/x/evm"
evmante "github.com/sei-protocol/sei-chain/x/evm/ante"
evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper"
"github.com/sei-protocol/sei-chain/x/evm/replay"
evmtracers "github.com/sei-protocol/sei-chain/x/evm/tracers"
"github.com/sei-protocol/sei-chain/x/evm/tracing"
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
Expand Down Expand Up @@ -595,6 +597,18 @@ func New(
if err != nil {
panic(fmt.Sprintf("error reading EVM config due to %s", err))
}
ethReplayConfig, err := replay.ReadConfig(appOpts)
if err != nil {
panic(fmt.Sprintf("error reading eth replay config due to %s", err))
}
app.EvmKeeper.EthReplayConfig = ethReplayConfig
if ethReplayConfig.Enabled {
rpcclient, err := ethrpc.Dial(ethReplayConfig.EthRPC)
if err != nil {
panic(fmt.Sprintf("error dialing %s due to %s", ethReplayConfig.EthRPC, err))
}
app.EvmKeeper.EthClient = ethclient.NewClient(rpcclient)
}

if app.evmRPCConfig.LiveEVMTracer != "" {
// PR_REVIEW_NOTE: So I moved this code from `ProcessBlock` and there, I had access to `ctx` so the code was actually looking
Expand Down Expand Up @@ -1499,7 +1513,7 @@ func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequ
events = append(events, beginBlockResp.Events...)

txResults = make([]*abci.ExecTxResult, len(txs))
typedTxs := []sdk.Tx{}
typedTxs := app.DecodeTransactionsConcurrently(ctx, txs)

if app.evmTracer != nil {
header := ctx.BlockHeader()
Expand All @@ -1509,24 +1523,6 @@ func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequ
}()
}

for i, tx := range txs {
typedTx, err := app.txDecoder(tx)
// get txkey from tx
if err != nil {
ctx.Logger().Error(fmt.Sprintf("error decoding transaction at index %d due to %s", i, err))
typedTxs = append(typedTxs, nil)
} else {
if isEVM, _ := evmante.IsEVMMessage(typedTx); isEVM {
msg := evmtypes.MustGetEVMTransactionMessage(typedTx)
if err := evmante.Preprocess(ctx, msg); err != nil {
ctx.Logger().Error(fmt.Sprintf("error preprocessing EVM tx due to %s", err))
typedTxs = append(typedTxs, nil)
continue
}
}
typedTxs = append(typedTxs, typedTx)
}
}
prioritizedTxs, otherTxs, prioritizedTypedTxs, otherTypedTxs, prioritizedIndices, otherIndices := app.PartitionPrioritizedTxs(ctx, txs, typedTxs)

// run the prioritized txs
Expand Down Expand Up @@ -1560,6 +1556,35 @@ func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequ
return events, txResults, endBlockResp, nil
}

func (app *App) DecodeTransactionsConcurrently(ctx sdk.Context, txs [][]byte) []sdk.Tx {
typedTxs := make([]sdk.Tx, len(txs))
wg := sync.WaitGroup{}
for i, tx := range txs {
wg.Add(1)
go func(idx int, encodedTx []byte) {
defer wg.Done()
typedTx, err := app.txDecoder(encodedTx)
// get txkey from tx
if err != nil {
ctx.Logger().Error(fmt.Sprintf("error decoding transaction at index %d due to %s", idx, err))
typedTxs[idx] = nil
} else {
if isEVM, _ := evmante.IsEVMMessage(typedTx); isEVM {
msg := evmtypes.MustGetEVMTransactionMessage(typedTx)
if err := evmante.Preprocess(ctx, msg); err != nil {
ctx.Logger().Error(fmt.Sprintf("error preprocessing EVM tx due to %s", err))
typedTxs[idx] = nil
return
}
}
typedTxs[idx] = typedTx
}
}(i, tx)
}
wg.Wait()
return typedTxs
}

func (app *App) addBadWasmDependenciesToContext(ctx sdk.Context, txResults []*abci.ExecTxResult) sdk.Context {
wasmContractsWithIncorrectDependencies := []sdk.AccAddress{}
for _, txResult := range txResults {
Expand All @@ -1583,6 +1608,9 @@ func (app *App) addBadWasmDependenciesToContext(ctx sdk.Context, txResults []*ab
}

func (app *App) getFinalizeBlockResponse(appHash []byte, events []abci.Event, txResults []*abci.ExecTxResult, endBlockResp abci.ResponseEndBlock) abci.ResponseFinalizeBlock {
if app.EvmKeeper.EthReplayConfig.Enabled {
return abci.ResponseFinalizeBlock{}
}
return abci.ResponseFinalizeBlock{
Events: events,
TxResults: txResults,
Expand Down
60 changes: 60 additions & 0 deletions app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package app_test

import (
"context"
"encoding/hex"
"fmt"
"math/big"
"testing"
"time"

Expand All @@ -12,9 +14,15 @@ import (
acltypes "github.com/cosmos/cosmos-sdk/x/accesscontrol/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/k0kubun/pp/v3"
"github.com/sei-protocol/sei-chain/app"
testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper"
dextypes "github.com/sei-protocol/sei-chain/x/dex/types"
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
"github.com/sei-protocol/sei-chain/x/evm/types/ethtx"
oracletypes "github.com/sei-protocol/sei-chain/x/oracle/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
Expand Down Expand Up @@ -344,3 +352,55 @@ func TestInvalidProposalWithExcessiveGasWanted(t *testing.T) {
require.Nil(t, err)
require.Equal(t, abci.ResponseProcessProposal_REJECT, res.Status)
}

func TestDecodeTransactionsConcurrently(t *testing.T) {
tm := time.Now().UTC()
valPub := secp256k1.GenPrivKey().PubKey()

testWrapper := app.NewTestWrapper(t, tm, valPub, false)
privKey := testkeeper.MockPrivateKey()
testPrivHex := hex.EncodeToString(privKey.Bytes())
key, _ := crypto.HexToECDSA(testPrivHex)
to := new(common.Address)
copy(to[:], []byte("0x1234567890abcdef1234567890abcdef12345678"))
txData := ethtypes.LegacyTx{
Nonce: 1,
GasPrice: big.NewInt(10),
Gas: 1000,
To: to,
Value: big.NewInt(1000),
Data: []byte("abc"),
}
chainCfg := evmtypes.DefaultChainConfig()
ethCfg := chainCfg.EthereumConfig(big.NewInt(713715))
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(1), uint64(123))
tx, err := ethtypes.SignTx(ethtypes.NewTx(&txData), signer, key)
ethtxdata, _ := ethtx.NewTxDataFromTx(tx)
if err != nil {
return
}
msg, _ := evmtypes.NewMsgEVMTransaction(ethtxdata)
txBuilder := testWrapper.App.GetTxConfig().NewTxBuilder()
txBuilder.SetMsgs(msg)
evmtxbz, _ := testWrapper.App.GetTxConfig().TxEncoder()(txBuilder.GetTx())

bankMsg := &banktypes.MsgSend{
FromAddress: "",
ToAddress: "",
Amount: sdk.NewCoins(sdk.NewInt64Coin("usei", 2)),
}

bankTxBuilder := testWrapper.App.GetTxConfig().NewTxBuilder()
bankTxBuilder.SetMsgs(bankMsg)
bankTxBuilder.SetGasLimit(200000)
bankTxBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewInt64Coin("usei", 20000)))
banktxbz, _ := testWrapper.App.GetTxConfig().TxEncoder()(bankTxBuilder.GetTx())

invalidbz := []byte("abc")

typedTxs := testWrapper.App.DecodeTransactionsConcurrently(testWrapper.Ctx, [][]byte{evmtxbz, invalidbz, banktxbz})
require.NotNil(t, typedTxs[0])
require.NotNil(t, typedTxs[0].GetMsgs()[0].(*evmtypes.MsgEVMTransaction).Derived)
require.Nil(t, typedTxs[1])
require.NotNil(t, typedTxs[2])
}
129 changes: 129 additions & 0 deletions app/eth_replay.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package app

import (
"context"
"encoding/binary"
"fmt"
"math/big"
"path/filepath"
"time"

"github.com/cosmos/cosmos-sdk/client"
"github.com/ethereum/go-ethereum/core/tracing"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"github.com/sei-protocol/sei-chain/utils"
"github.com/sei-protocol/sei-chain/x/evm/state"
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
"github.com/sei-protocol/sei-chain/x/evm/types/ethtx"
abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
)

func Replay(a *App) {
h := a.EvmKeeper.GetReplayedHeight(a.GetCheckCtx()) + 1
initHeight := a.EvmKeeper.GetReplayInitialHeight(a.GetCheckCtx())
if h == 1 {
gendoc, err := tmtypes.GenesisDocFromFile(filepath.Join(DefaultNodeHome, "config/genesis.json"))
if err != nil {
panic(err)
}
_, err = a.InitChain(context.Background(), &abci.RequestInitChain{
Time: time.Now(),
ChainId: gendoc.ChainID,
AppStateBytes: gendoc.AppState,
})
if err != nil {
panic(err)
}
initHeight = a.EvmKeeper.GetReplayInitialHeight(a.GetContextForDeliverTx([]byte{}))
} else {
a.EvmKeeper.OpenEthDatabase()
}
for {
latestBlock, err := a.EvmKeeper.EthClient.BlockNumber(context.Background())
if err != nil {
panic(err)
}
if latestBlock < uint64(h+initHeight) {
a.Logger().Info(fmt.Sprintf("Latest block is %d. Sleeping for a minute", latestBlock))
time.Sleep(1 * time.Minute)
continue
}
a.Logger().Info(fmt.Sprintf("Replaying block height %d", h+initHeight))
if h+initHeight >= 19426587 && evmtypes.DefaultChainConfig().CancunTime < 0 {
a.Logger().Error("Reaching Cancun upgrade height. Turn on Cancun by setting CancunTime in x/evm/types/config.go:DefaultChainConfig() to 0")
break
} else if h+initHeight < 19426587 && evmtypes.DefaultChainConfig().CancunTime >= 0 {
a.Logger().Error("Haven't reached Cancun upgrade height. Turn off Cancun by setting CancunTime in x/evm/types/config.go:DefaultChainConfig() to -1")
break
}
b, err := a.EvmKeeper.EthClient.BlockByNumber(context.Background(), big.NewInt(h+initHeight))
if err != nil {
panic(err)
}
hash := make([]byte, 8)
binary.BigEndian.PutUint64(hash, uint64(h))
_, err = a.FinalizeBlock(context.Background(), &abci.RequestFinalizeBlock{
Txs: utils.Map(b.Txs, func(tx *ethtypes.Transaction) []byte { return encodeTx(tx, a.GetTxConfig()) }),
DecidedLastCommit: abci.CommitInfo{Votes: []abci.VoteInfo{}},
Height: h,
Hash: hash,
Time: time.Now(),
})
if err != nil {
panic(err)
}
ctx := a.GetContextForDeliverTx([]byte{})
s := state.NewDBImpl(ctx, &a.EvmKeeper, false)
for _, w := range b.Withdrawals() {
amount := new(big.Int).SetUint64(w.Amount)
amount = amount.Mul(amount, big.NewInt(params.GWei))
s.AddBalance(w.Address, amount, tracing.BalanceIncreaseWithdrawal)
}
_, _ = s.Finalize()
for _, tx := range b.Txs {
a.Logger().Info(fmt.Sprintf("Verifying tx %s", tx.Hash().Hex()))
if tx.To() != nil {
a.EvmKeeper.VerifyBalance(ctx, *tx.To())
}
a.EvmKeeper.VerifyTxResult(ctx, tx.Hash())
}
_, err = a.Commit(context.Background())
if err != nil {
panic(err)
}
h++
}
}

func encodeTx(tx *ethtypes.Transaction, txConfig client.TxConfig) []byte {
var txData ethtx.TxData
var err error
switch tx.Type() {
case ethtypes.LegacyTxType:
txData, err = ethtx.NewLegacyTx(tx)
case ethtypes.DynamicFeeTxType:
txData, err = ethtx.NewDynamicFeeTx(tx)
case ethtypes.AccessListTxType:
txData, err = ethtx.NewAccessListTx(tx)
case ethtypes.BlobTxType:
txData, err = ethtx.NewBlobTx(tx)
}
if err != nil {
panic(err)
}
msg, err := evmtypes.NewMsgEVMTransaction(txData)
if err != nil {
panic(err)
}
txBuilder := txConfig.NewTxBuilder()
if err = txBuilder.SetMsgs(msg); err != nil {
panic(err)
}
txbz, encodeErr := txConfig.TxEncoder()(txBuilder.GetTx())
if encodeErr != nil {
panic(encodeErr)
}
return txbz
}
1 change: 1 addition & 0 deletions app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ var upgradesList = []string{
"v4.1.3-evm-devnet",
"v4.1.4-evm-devnet",
"v4.1.5-evm-devnet",
"v4.1.6-evm-devnet",
}

// if there is an override list, use that instead, for integration tests
Expand Down
Loading

0 comments on commit a59e684

Please sign in to comment.