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

Add occ test for multiple EVM transactions in a block #1903

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,7 @@ func New(
)

app.mm.SetOrderEndBlockers(
evmtypes.ModuleName,
crisistypes.ModuleName,
govtypes.ModuleName,
stakingtypes.ModuleName,
Expand All @@ -808,7 +809,6 @@ func New(
ibctransfertypes.ModuleName,
oracletypes.ModuleName,
epochmoduletypes.ModuleName,
evmtypes.ModuleName,
wasm.ModuleName,
tokenfactorytypes.ModuleName,
acltypes.ModuleName,
Expand Down
1 change: 1 addition & 0 deletions example/contracts/mintburn/MintBurn.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
1 change: 1 addition & 0 deletions example/contracts/mintburn/MintBurn.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
608060405234801561000f575f80fd5b5061042e8061001d5f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c80631249c58b1461004357806344df8e701461006157806370a082311461007f575b5f80fd5b61004b6100af565b604051610058919061021a565b60405180910390f35b61006961010d565b604051610076919061021a565b60405180910390f35b61009960048036038101906100949190610291565b6101ec565b6040516100a691906102d4565b60405180910390f35b5f633b9aca005f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546100ff919061031a565b925050819055506001905090565b5f629896805f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015610190576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610187906103a7565b60405180910390fd5b629896805f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546101de91906103c5565b925050819055506001905090565b5f602052805f5260405f205f915090505481565b5f8115159050919050565b61021481610200565b82525050565b5f60208201905061022d5f83018461020b565b92915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61026082610237565b9050919050565b61027081610256565b811461027a575f80fd5b50565b5f8135905061028b81610267565b92915050565b5f602082840312156102a6576102a5610233565b5b5f6102b38482850161027d565b91505092915050565b5f819050919050565b6102ce816102bc565b82525050565b5f6020820190506102e75f8301846102c5565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610324826102bc565b915061032f836102bc565b9250828201905080821115610347576103466102ed565b5b92915050565b5f82825260208201905092915050565b7f6e6f7420656e6f75676820746f206275726e00000000000000000000000000005f82015250565b5f61039160128361034d565b915061039c8261035d565b602082019050919050565b5f6020820190508181035f8301526103be81610385565b9050919050565b5f6103cf826102bc565b91506103da836102bc565b92508282039050818111156103f2576103f16102ed565b5b9291505056fea264697066735822122097bb6b200c883aafe856a02eaa5776af13824f11e4701de41eeae065e31e0b0964736f6c63430008140033
19 changes: 19 additions & 0 deletions example/contracts/mintburn/MintBurn.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

// NOTE: NOT A REAL IMPLEMENTATION -- DO NOT USE IN PROD
contract MintBurn {
mapping(address => uint256) public balanceOf;

function mint() external returns (bool) {
balanceOf[msg.sender] += 1000000000;
return true;
}

function burn() external returns (bool) {
require(balanceOf[msg.sender] >= 10000000, "not enough to burn");
balanceOf[msg.sender] -= 10000000;
return true;
}
}
1 change: 1 addition & 0 deletions example/contracts/mintburn/deployed_bytes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
608060405234801561000f575f80fd5b506004361061003f575f3560e01c80631249c58b1461004357806344df8e701461006157806370a082311461007f575b5f80fd5b61004b6100af565b604051610058919061021a565b60405180910390f35b61006961010d565b604051610076919061021a565b60405180910390f35b61009960048036038101906100949190610291565b6101ec565b6040516100a691906102d4565b60405180910390f35b5f633b9aca005f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546100ff919061031a565b925050819055506001905090565b5f629896805f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20541015610190576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610187906103a7565b60405180910390fd5b629896805f803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546101de91906103c5565b925050819055506001905090565b5f602052805f5260405f205f915090505481565b5f8115159050919050565b61021481610200565b82525050565b5f60208201905061022d5f83018461020b565b92915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61026082610237565b9050919050565b61027081610256565b811461027a575f80fd5b50565b5f8135905061028b81610267565b92915050565b5f602082840312156102a6576102a5610233565b5b5f6102b38482850161027d565b91505092915050565b5f819050919050565b6102ce816102bc565b82525050565b5f6020820190506102e75f8301846102c5565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610324826102bc565b915061032f836102bc565b9250828201905080821115610347576103466102ed565b5b92915050565b5f82825260208201905092915050565b7f6e6f7420656e6f75676820746f206275726e00000000000000000000000000005f82015250565b5f61039160128361034d565b915061039c8261035d565b602082019050919050565b5f6020820190508181035f8301526103be81610385565b9050919050565b5f6103cf826102bc565b91506103da836102bc565b92508282039050818111156103f2576103f16102ed565b5b9291505056fea264697066735822122096efa896bee5c78076838624bd673f04b81ba995c74eed07d06e9e71571627da64736f6c634300081a0033
152 changes: 152 additions & 0 deletions occ_tests/evm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package occ

import (
"encoding/hex"
"fmt"
"math/big"
"math/rand"
"os"
"testing"
"time"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/sei-protocol/sei-chain/app"
"github.com/sei-protocol/sei-chain/occ_tests/utils"
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
"github.com/sei-protocol/sei-chain/x/evm/types/ethtx"
minttypes "github.com/sei-protocol/sei-chain/x/mint/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
)

var MintPayload = []byte{18, 73, 197, 139}
var BurnPayload = []byte{68, 223, 142, 112}

func TestMintBurn(t *testing.T) {
blocksToTest := 100
numAccounts := 10
maxTxsPerBlock := 10
burnToMintRatio := 1
now := time.Now()
val := utils.NewSigner()
occWrapper := app.NewTestWrapper(t, now, val.PublicKey, false, func(ba *baseapp.BaseApp) {
ba.SetOccEnabled(true)
ba.SetConcurrencyWorkers(5)
})
occTestApp := occWrapper.App
occCtx := occWrapper.Ctx
seqWrapper := app.NewTestWrapper(t, now, val.PublicKey, false, func(ba *baseapp.BaseApp) {
ba.SetOccEnabled(false)
ba.SetConcurrencyWorkers(5)
})
seqTestApp := seqWrapper.App
seqCtx := seqWrapper.Ctx
accts := make([]utils.TestAcct, numAccounts)
nonces := make([]uint64, numAccounts)
funds := utils.Funds(100000000000000000)
for i := 0; i < numAccounts; i++ {
accts[i] = utils.NewSigner()
panicIfErr(occTestApp.BankKeeper.MintCoins(occCtx, minttypes.ModuleName, funds))
panicIfErr(seqTestApp.BankKeeper.MintCoins(seqCtx, minttypes.ModuleName, funds))
panicIfErr(occTestApp.BankKeeper.SendCoinsFromModuleToAccount(occCtx, minttypes.ModuleName, accts[i].AccountAddress, funds))
panicIfErr(seqTestApp.BankKeeper.SendCoinsFromModuleToAccount(seqCtx, minttypes.ModuleName, accts[i].AccountAddress, funds))
}
codeAddr := utils.NewSigner().EvmAddress
code := readDeployedCode()
occTestApp.EvmKeeper.SetCode(occCtx, codeAddr, code)
seqTestApp.EvmKeeper.SetCode(seqCtx, codeAddr, code)
chainID := occTestApp.EvmKeeper.ChainID(occCtx)
require.Equal(t, chainID, seqTestApp.EvmKeeper.ChainID(seqCtx))
chainCfg := evmtypes.DefaultChainConfig()
ethCfg := chainCfg.EthereumConfig(chainID)
for i := 0; i < blocksToTest; i++ {
numTx := rand.Intn(maxTxsPerBlock) + 1
fmt.Printf("number of transactions for block %d: %d\n", i, numTx)
txsOcc := make([][]byte, numTx)
txsSeq := make([][]byte, numTx)
for j := 0; j < numTx; j++ {
payload := BurnPayload
if rand.Intn(burnToMintRatio) == 0 {
payload = MintPayload
}
whichAcct := rand.Intn(numAccounts)
acct := accts[whichAcct]
txData := ethtypes.DynamicFeeTx{
Nonce: nonces[whichAcct],
GasFeeCap: big.NewInt(10000000000),
Gas: 50000,
To: &codeAddr,
Value: big.NewInt(0),
Data: payload,
ChainID: chainID,
}
nonces[whichAcct]++
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(0), uint64(now.Unix()))
tx, err := ethtypes.SignTx(ethtypes.NewTx(&txData), signer, acct.EvmPrivateKey)
panicIfErr(err)
typedTx, err := ethtx.NewDynamicFeeTx(tx)
panicIfErr(err)
msg, err := evmtypes.NewMsgEVMTransaction(typedTx)
panicIfErr(err)
occTxBuilder := occTestApp.GetTxConfig().NewTxBuilder()
occTxBuilder.SetMsgs(msg)
txsOcc[j], err = occTestApp.GetTxConfig().TxEncoder()(occTxBuilder.GetTx())
panicIfErr(err)
seqTxBuilder := seqTestApp.GetTxConfig().NewTxBuilder()
seqTxBuilder.SetMsgs(msg)
txsSeq[j], err = seqTestApp.GetTxConfig().TxEncoder()(seqTxBuilder.GetTx())
panicIfErr(err)
}
reqOcc := &abci.RequestFinalizeBlock{
Txs: txsOcc,
Height: int64(i) + 1,
}
reqSeq := &abci.RequestFinalizeBlock{
Txs: txsSeq,
Height: int64(i) + 1,
}
occCtx = occCtx.WithBlockHeight(reqOcc.Height)
seqCtx = seqCtx.WithBlockHeight(reqSeq.Height)
_, _, _, err := seqTestApp.ProcessBlock(seqCtx, txsSeq, reqSeq, reqSeq.DecidedLastCommit)
panicIfErr(err)
_, _, _, err = occTestApp.ProcessBlock(occCtx, txsOcc, reqOcc, reqOcc.DecidedLastCommit)
panicIfErr(err)
// verify account info
for _, acct := range accts {
require.Equal(t, occTestApp.BankKeeper.GetBalance(occCtx, acct.AccountAddress, "usei").Amount, seqTestApp.BankKeeper.GetBalance(seqCtx, acct.AccountAddress, "usei").Amount)
require.Equal(t, occTestApp.EvmKeeper.GetNonce(occCtx, acct.EvmAddress), seqTestApp.EvmKeeper.GetNonce(seqCtx, acct.EvmAddress))
}
// verify contract state
occTestApp.EvmKeeper.IterateState(occCtx, func(addr common.Address, key, val common.Hash) bool {
seqState := seqTestApp.EvmKeeper.GetState(seqCtx, addr, key)
require.Equal(t, seqState, val)
return false
})
seqTestApp.SetDeliverStateToCommit()
occTestApp.SetDeliverStateToCommit()
seqTestApp.WriteState()
seqTestApp.GetWorkingHash()
seqTestApp.CommitMultiStore().Commit(true)
occTestApp.WriteState()
occTestApp.GetWorkingHash()
occTestApp.CommitMultiStore().Commit(true)
seqCtx = seqCtx.WithMultiStore(seqTestApp.CommitMultiStore().CacheMultiStore())
occCtx = occCtx.WithMultiStore(occTestApp.CommitMultiStore().CacheMultiStore())
}
}

func readDeployedCode() []byte {
dat, err := os.ReadFile("../example/contracts/mintburn/deployed_bytes")
panicIfErr(err)
bz, err := hex.DecodeString(string(dat))
panicIfErr(err)
return bz
}

func panicIfErr(err error) {
if err != nil {
panic(err)
}
}
Loading