Skip to content

Commit

Permalink
Merge tag 'v6.0.2' into feature/firehose-tracer-at-latest-release-tag
Browse files Browse the repository at this point in the history
  • Loading branch information
maoueh committed Jan 13, 2025
2 parents ef82a26 + f17ec67 commit 8a46488
Show file tree
Hide file tree
Showing 54 changed files with 1,544 additions and 469 deletions.
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@ Ref: https://keepachangelog.com/en/1.0.0/
-->

# Changelog
## v6.0.2
sei-chain
* [#2018](https://github.com/sei-protocol/sei-chain/pull/2018) Remove TxHashes from EVM module
* [#2006](https://github.com/sei-protocol/sei-chain/pull/2006) Fix volatile eth_gasPrice
* [#2005](https://github.com/sei-protocol/sei-chain/pull/2005) Exclude block receipts whose block number do not match
* [#2004](https://github.com/sei-protocol/sei-chain/pull/2004) Integrate with MinTxsInBlock
* [#1983](https://github.com/sei-protocol/sei-chain/pull/1983) Handle oracle overflow and rounding to zero
* [#2002](https://github.com/sei-protocol/sei-chain/pull/2002) Update IBC version to use utc on error msg
* [#2000](https://github.com/sei-protocol/sei-chain/pull/2000) Catch panic in trace transaction / trace call
* [#1995](https://github.com/sei-protocol/sei-chain/pull/1995) RPC endpoints for excluding tracing failures
* [#1993](https://github.com/sei-protocol/sei-chain/pull/1993) Avoid panic in getLogs
* [#1991](https://github.com/sei-protocol/sei-chain/pull/1991) Add defer recovery for failed txs when tracing and estimating gas
* [#1988](https://github.com/sei-protocol/sei-chain/pull/1988) getLogs endpoint should check whether or not to include cosmos txs based on namespace
* [#1984](https://github.com/sei-protocol/sei-chain/pull/1984) Client state pagniation by using filtered pagination
* [#1982](https://github.com/sei-protocol/sei-chain/pull/1982) Fix method handler crash due to nil min fee per gas
* [#1974](https://github.com/sei-protocol/sei-chain/pull/1974) Optimize getLogs with parallelization
* [#1971](https://github.com/sei-protocol/sei-chain/pull/1971) Remove tokenfactory config
* [#1970](https://github.com/sei-protocol/sei-chain/pull/1970) Add unbonding delegation query

sei-cosmos
* [#559](https://github.com/sei-protocol/sei-cosmos/pull/559) Fix state sync halt issue
* [#558](https://github.com/sei-protocol/sei-cosmos/pull/558) Integrate with MinTxsInBlock
* [#557](https://github.com/sei-protocol/sei-cosmos/pull/557) Fix seid rollback state mismatch error
* [#555](https://github.com/sei-protocol/sei-cosmos/pull/555) Set earliest version update
* [#552](https://github.com/sei-protocol/sei-cosmos/pull/552) Add confidential transfer constants

sei-tendermint
* [#252](https://github.com/sei-protocol/sei-tendermint/pull/252) Add new MinTxsInBlock consensus param

## v6.0.1
sei-chain
* [#1956](https://github.com/sei-protocol/sei-chain/pull/1956) Assign owner correctly when there are multiple transfers
Expand Down
24 changes: 13 additions & 11 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,19 +541,13 @@ func New(
).SetHooks(epochmoduletypes.NewMultiEpochHooks(
app.MintKeeper.Hooks()))

tokenFactoryConfig, err := tokenfactorykeeper.ReadConfig(appOpts)
if err != nil {
panic(fmt.Sprintf("error reading token factory config due to %s", err))
}

app.TokenFactoryKeeper = tokenfactorykeeper.NewKeeper(
appCodec,
app.keys[tokenfactorytypes.StoreKey],
app.GetSubspace(tokenfactorytypes.ModuleName),
app.AccountKeeper,
app.BankKeeper.(bankkeeper.BaseKeeper).WithMintCoinsRestriction(tokenfactorytypes.NewTokenFactoryDenomMintCoinsRestriction()),
app.DistrKeeper,
tokenFactoryConfig,
)

// The last arguments can contain custom message handlers, and custom query handlers,
Expand Down Expand Up @@ -1745,8 +1739,9 @@ func (app *App) getFinalizeBlockResponse(appHash []byte, events []abci.Event, tx
}),
ConsensusParamUpdates: &tmproto.ConsensusParams{
Block: &tmproto.BlockParams{
MaxBytes: endBlockResp.ConsensusParamUpdates.Block.MaxBytes,
MaxGas: endBlockResp.ConsensusParamUpdates.Block.MaxGas,
MaxBytes: endBlockResp.ConsensusParamUpdates.Block.MaxBytes,
MaxGas: endBlockResp.ConsensusParamUpdates.Block.MaxGas,
MinTxsInBlock: endBlockResp.ConsensusParamUpdates.Block.MinTxsInBlock,
},
Evidence: &tmproto.EvidenceParams{
MaxAgeNumBlocks: endBlockResp.ConsensusParamUpdates.Evidence.MaxAgeNumBlocks,
Expand Down Expand Up @@ -1873,7 +1868,7 @@ func (app *App) RegisterTendermintService(clientCtx client.Context) {
return ctx.WithIsEVM(true)
}
if app.evmRPCConfig.HTTPEnabled {
evmHTTPServer, err := evmrpc.NewEVMHTTPServer(app.Logger(), app.evmRPCConfig, clientCtx.Client, &app.EvmKeeper, ctxProvider, app.encodingConfig.TxConfig, DefaultNodeHome)
evmHTTPServer, err := evmrpc.NewEVMHTTPServer(app.Logger(), app.evmRPCConfig, clientCtx.Client, &app.EvmKeeper, ctxProvider, app.encodingConfig.TxConfig, DefaultNodeHome, nil)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -1906,6 +1901,7 @@ func RegisterSwaggerAPI(rtr *mux.Router) {

func (app *App) checkTotalBlockGasWanted(ctx sdk.Context, txs [][]byte) bool {
totalGasWanted := uint64(0)
nonzeroTxsCnt := 0
for _, tx := range txs {
decodedTx, err := app.txDecoder(tx)
if err != nil {
Expand Down Expand Up @@ -1950,10 +1946,16 @@ func (app *App) checkTotalBlockGasWanted(ctx sdk.Context, txs [][]byte) bool {
return false
}

if gasWanted > 0 {
nonzeroTxsCnt++
}

totalGasWanted += gasWanted
if totalGasWanted > uint64(ctx.ConsensusParams().Block.MaxGas) {
// early return
return false
if nonzeroTxsCnt > int(ctx.ConsensusParams().Block.MinTxsInBlock) {
// early return
return false
}
}
}
return true
Expand Down
4 changes: 0 additions & 4 deletions app/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking/teststaking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
tokenfactorykeeper "github.com/sei-protocol/sei-chain/x/tokenfactory/keeper"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/config"
Expand Down Expand Up @@ -56,9 +55,6 @@ func (t TestAppOpts) Get(s string) interface{} {
if s == FlagSCEnable {
return t.useSc
}
if s == tokenfactorykeeper.FlagDenomAllowListMaxSize {
return 3
}
return nil
}

Expand Down
13 changes: 13 additions & 0 deletions app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ var upgradesList = []string{
"v5.9.0",
"v6.0.0",
"v6.0.1",
"v6.0.2",
}

// if there is an override list, use that instead, for integration tests
Expand Down Expand Up @@ -149,6 +150,18 @@ func (app App) RegisterUpgradeHandlers() {
return newVM, err
}

if upgradeName == "v6.0.2" {
newVM, err := app.mm.RunMigrations(ctx, app.configurator, fromVM)
if err != nil {
return newVM, err
}

cp := app.GetConsensusParams(ctx)
cp.Block.MinTxsInBlock = 10
app.StoreConsensusParams(ctx, cp)
return newVM, err
}

return app.mm.RunMigrations(ctx, app.configurator, fromVM)
})
}
Expand Down
5 changes: 2 additions & 3 deletions contracts/test/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,14 @@ async function instantiateWasm(codeId, adminAddr, label, args = {}, from=adminKe
return getEventAttribute(response, "instantiate", "_contract_address");
}

async function proposeCW20toERC20Upgrade(erc20Address, cw20Address, title="erc20-pointer", version=99, description="erc20 pointer",fees="20000usei", from=adminKeyName) {
async function proposeCW20toERC20Upgrade(erc20Address, cw20Address, title="erc20-pointer", version=99, description="erc20 pointer",fees="200000usei", from=adminKeyName) {
const command = `seid tx evm add-cw-erc20-pointer "${title}" "${description}" ${erc20Address} ${version} 200000000usei ${cw20Address} --from ${from} --fees ${fees} -y -o json --broadcast-mode=block`
const output = await execute(command);
const proposalId = getEventAttribute(JSON.parse(output), "submit_proposal", "proposal_id")
return await passProposal(proposalId)
}

async function passProposal(proposalId, desposit="200000000usei", fees="20000usei", from=adminKeyName) {
async function passProposal(proposalId, desposit="200000000usei", fees="200000usei", from=adminKeyName) {
if(await isDocker()) {
await executeOnAllNodes(`seid tx gov vote ${proposalId} yes --from node_admin -b block -y --fees ${fees}`)
} else {
Expand Down Expand Up @@ -331,7 +331,6 @@ async function registerPointerForERC721(erc721Address, fees="20000usei", from=ad
return getEventAttribute(response, "pointer_registered", "pointer_address")
}


async function getSeiAddress(evmAddress) {
const command = `seid q evm sei-addr ${evmAddress} -o json`
const output = await execute(command);
Expand Down
24 changes: 24 additions & 0 deletions evmrpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Sei's EVM RPC

Sei supports the standard [Ethereum JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) endpoints. On top of that, Sei supports some additional custom endpoints.

## Sei_ endpoints

### Endpoints for Synthetic txs
The motivation for these endpoints is to expose CW20 and CW721 events on the EVM side through synthetic receipts and logs. This is useful for indexing pointer contracts.
- `sei_getFilterLogs`
- same as `eth_getFilterLogs` but includes synthetic logs
- `sei_getLogs`
- same as `eth_getLogs` but includes synthetic logs
- `sei_getBlockByNumber` and `sei_getBlockByHash`
- same as `eth_getBlockByNumber` and `eth_getBlockByHash` but includes synthetic txs
- NOTE: for synthetic txs, `eth_getTransactionReceipt` can be used to get the receipt data for a synthetic tx hash.

### Endpoints for excluding tracing failures
The motivation for these endpoints is to exclude tracing failures from the EVM side. Due to how our mempool works and our lack of tx simulation, we cannot rely on txs to pass all pre-state checks. Therefore, in the eth_ endpoints, we may see txs that fail tracing with errors like "nonce too low", "nonce too high", "insufficient funds", or other types of panic failures. These transactions are not executed, yet are still included in the block. These endpoints are useful for filtering out these txs.
- `sei_traceBlockByNumberExcludeTraceFail`
- same as `debug_traceBlockByNumber` but excludes panic txs
- `sei_getTransactionReceiptExcludeTraceFail`
- same as `eth_getTransactionReceipt` but excludes panic txs
- `sei_getBlockByNumberExcludeTraceFail` and `sei_getBlockByHashExcludeTraceFail`
- same as `eth_getBlockByNumber` and `eth_getBlockByHash` but excludes panic txs
106 changes: 88 additions & 18 deletions evmrpc/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,48 @@ type BlockAPI struct {
includeShellReceipts bool
}

func NewBlockAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func(int64) sdk.Context, txConfig client.TxConfig, connectionType ConnectionType, namespace string) *BlockAPI {
return &BlockAPI{tmClient: tmClient, keeper: k, ctxProvider: ctxProvider, txConfig: txConfig, connectionType: connectionType, includeShellReceipts: shouldIncludeSynthetic(namespace)}
type SeiBlockAPI struct {
*BlockAPI
isPanicTx func(ctx context.Context, hash common.Hash) (bool, error)
}

func NewBlockAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func(int64) sdk.Context, txConfig client.TxConfig, connectionType ConnectionType) *BlockAPI {
return &BlockAPI{
tmClient: tmClient,
keeper: k,
ctxProvider: ctxProvider,
txConfig: txConfig,
connectionType: connectionType,
includeShellReceipts: false,
namespace: "eth",
}
}

func NewSeiBlockAPI(
tmClient rpcclient.Client,
k *keeper.Keeper,
ctxProvider func(int64) sdk.Context,
txConfig client.TxConfig,
connectionType ConnectionType,
isPanicTx func(ctx context.Context, hash common.Hash) (bool, error),
) *SeiBlockAPI {
blockAPI := &BlockAPI{
tmClient: tmClient,
keeper: k,
ctxProvider: ctxProvider,
txConfig: txConfig,
connectionType: connectionType,
includeShellReceipts: true,
namespace: "sei",
}
return &SeiBlockAPI{
BlockAPI: blockAPI,
isPanicTx: isPanicTx,
}
}

func (a *SeiBlockAPI) GetBlockByNumberExcludeTraceFail(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) {
return a.getBlockByNumber(ctx, number, fullTx, a.isPanicTx)
}

func (a *BlockAPI) GetBlockTransactionCountByNumber(ctx context.Context, number rpc.BlockNumber) (result *hexutil.Uint, returnErr error) {
Expand Down Expand Up @@ -68,12 +108,20 @@ func (a *BlockAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash
}

func (a *BlockAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (result map[string]interface{}, returnErr error) {
startTime := time.Now()
defer recordMetrics(fmt.Sprintf("%s_getBlockByHash", a.namespace), a.connectionType, startTime, returnErr == nil)
return a.getBlockByHash(ctx, blockHash, fullTx)
return a.getBlockByHash(ctx, blockHash, fullTx, nil)
}

func (a *SeiBlockAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (result map[string]interface{}, returnErr error) {
return a.getBlockByHash(ctx, blockHash, fullTx, nil)
}

func (a *BlockAPI) getBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (result map[string]interface{}, returnErr error) {
func (a *SeiBlockAPI) GetBlockByHashExcludeTraceFail(ctx context.Context, blockHash common.Hash, fullTx bool) (result map[string]interface{}, returnErr error) {
return a.getBlockByHash(ctx, blockHash, fullTx, a.isPanicTx)
}

func (a *BlockAPI) getBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool, isPanicTx func(ctx context.Context, hash common.Hash) (bool, error)) (result map[string]interface{}, returnErr error) {
startTime := time.Now()
defer recordMetrics(fmt.Sprintf("%s_getBlockByHash", a.namespace), a.connectionType, startTime, returnErr == nil)
block, err := blockByHashWithRetry(ctx, a.tmClient, blockHash[:], 1)
if err != nil {
return nil, err
Expand All @@ -83,7 +131,7 @@ func (a *BlockAPI) getBlockByHash(ctx context.Context, blockHash common.Hash, fu
return nil, err
}
blockBloom := a.keeper.GetBlockBloom(a.ctxProvider(block.Block.Height))
return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeShellReceipts)
return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeShellReceipts, isPanicTx)
}

func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) {
Expand All @@ -93,7 +141,7 @@ func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber,
// for compatibility with the graph, always return genesis block
return map[string]interface{}{
"number": (*hexutil.Big)(big.NewInt(0)),
"hash": common.HexToHash("F9D3845DF25B43B1C6926F3CEDA6845C17F5624E12212FD8847D0BA01DA1AB9E"),
"hash": "0xF9D3845DF25B43B1C6926F3CEDA6845C17F5624E12212FD8847D0BA01DA1AB9E",
"parentHash": common.Hash{},
"nonce": ethtypes.BlockNonce{}, // inapplicable to Sei
"mixHash": common.Hash{}, // inapplicable to Sei
Expand All @@ -114,10 +162,17 @@ func (a *BlockAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber,
"baseFeePerGas": (*hexutil.Big)(big.NewInt(0)),
}, nil
}
return a.getBlockByNumber(ctx, number, fullTx)
return a.getBlockByNumber(ctx, number, fullTx, nil)
}

func (a *BlockAPI) getBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (result map[string]interface{}, returnErr error) {
func (a *BlockAPI) getBlockByNumber(
ctx context.Context,
number rpc.BlockNumber,
fullTx bool,
isPanicTx func(ctx context.Context, hash common.Hash) (bool, error),
) (result map[string]interface{}, returnErr error) {
startTime := time.Now()
defer recordMetrics(fmt.Sprintf("%s_getBlockByNumber", a.namespace), a.connectionType, startTime, returnErr == nil)
numberPtr, err := getBlockNumber(ctx, a.tmClient, number)
if err != nil {
return nil, err
Expand All @@ -131,7 +186,7 @@ func (a *BlockAPI) getBlockByNumber(ctx context.Context, number rpc.BlockNumber,
return nil, err
}
blockBloom := a.keeper.GetBlockBloom(a.ctxProvider(block.Block.Height))
return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeShellReceipts)
return EncodeTmBlock(a.ctxProvider(block.Block.Height), block, blockRes, blockBloom, a.keeper, a.txConfig.TxDecoder(), fullTx, a.includeShellReceipts, isPanicTx)
}

func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (result []map[string]interface{}, returnErr error) {
Expand All @@ -150,7 +205,7 @@ func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.Block

// Get all tx hashes for the block
height := block.Block.Header.Height
txHashes := getEvmTxHashesFromBlock(block, a.txConfig)
txHashes := getTxHashesFromBlock(block, a.txConfig, shouldIncludeSynthetic(a.namespace))
// Get tx receipts for all hashes in parallel
wg := sync.WaitGroup{}
mtx := sync.Mutex{}
Expand All @@ -172,6 +227,11 @@ func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.Block
if !a.includeShellReceipts && receipt.TxType == ShellEVMTxType {
return
}
// tx hash is included in a future block (because it failed in the current block due to
// checks before the account's nonce is updated)
if receipt.BlockNumber != uint64(height) {
return
}
encodedReceipt, err := encodeReceipt(receipt, a.txConfig.TxDecoder(), block, func(h common.Hash) bool {
_, err := a.keeper.GetReceipt(a.ctxProvider(height), h)
return err == nil
Expand Down Expand Up @@ -207,6 +267,7 @@ func EncodeTmBlock(
txDecoder sdk.TxDecoder,
fullTx bool,
includeSyntheticTxs bool,
isPanicTx func(ctx context.Context, hash common.Hash) (bool, error),
) (map[string]interface{}, error) {
number := big.NewInt(block.Block.Height)
blockhash := common.HexToHash(block.BlockID.Hash.String())
Expand Down Expand Up @@ -235,16 +296,25 @@ func EncodeTmBlock(
}
ethtx, _ := m.AsTransaction()
hash := ethtx.Hash()
if !fullTx {
transactions = append(transactions, hash)
} else {
receipt, err := k.GetReceipt(ctx, hash)
if isPanicTx != nil {
isPanic, err := isPanicTx(ctx.Context(), hash)
if err != nil {
continue
return nil, fmt.Errorf("failed to check if tx is panic tx: %w", err)
}
if !includeSyntheticTxs && receipt.TxType == ShellEVMTxType {
if isPanic {
continue
}
}
receipt, err := k.GetReceipt(ctx, hash)
if err != nil {
continue
}
if !includeSyntheticTxs && receipt.TxType == ShellEVMTxType {
continue
}
if !fullTx {
transactions = append(transactions, hash)
} else {
newTx := ethapi.NewRPCTransaction(ethtx, blockhash, number.Uint64(), uint64(blockTime.Second()), uint64(receipt.TransactionIndex), baseFeePerGas, chainConfig)
transactions = append(transactions, newTx)
}
Expand Down
Loading

0 comments on commit 8a46488

Please sign in to comment.