Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e852d4a
add helper method for sig recovery
stevenlanders Sep 30, 2025
e903eab
fix rpc sender calculation
stevenlanders Sep 30, 2025
ba78b6b
handle conflicts
stevenlanders Sep 30, 2025
33f442d
go fmt
stevenlanders Sep 30, 2025
12d02dc
handle conflict
stevenlanders Sep 30, 2025
95f836e
use unix time instead of Second
stevenlanders Oct 1, 2025
d679e30
handle conflicts
stevenlanders Oct 1, 2025
ecca0e1
handle conflicts
stevenlanders Oct 1, 2025
b043107
add log for regression test
stevenlanders Oct 1, 2025
ff2741c
remove log line
stevenlanders Oct 1, 2025
af3458f
add prague to recovery
stevenlanders Oct 1, 2025
2233203
Merge branch 'main' into steven/fix-from-discrepancy-main
stevenlanders Oct 2, 2025
1d01677
refactor to avoid inadvertant usage for non-evmrpc use
stevenlanders Oct 2, 2025
95d4212
Merge branch 'main' into steven/fix-from-discrepancy-main
stevenlanders Oct 2, 2025
985cb28
fix lint
stevenlanders Oct 2, 2025
22ae277
fix rest of lint
stevenlanders Oct 2, 2025
37e5bc7
gosec adjustment
stevenlanders Oct 2, 2025
117a608
add test coverage for tx.go
stevenlanders Oct 2, 2025
9656a82
go fmt
stevenlanders Oct 2, 2025
bd95f15
increase some test coverage
stevenlanders Oct 2, 2025
4092be1
Merge branch 'main' into steven/fix-from-discrepancy-main
stevenlanders Oct 3, 2025
a941b69
try to raise codecov
stevenlanders Oct 3, 2025
83a9aed
go fmt
stevenlanders Oct 3, 2025
245cebc
Merge branch 'main' into steven/fix-from-discrepancy-main
stevenlanders Oct 3, 2025
314f73c
Merge branch 'main' into steven/fix-from-discrepancy-main
stevenlanders Oct 3, 2025
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
24 changes: 8 additions & 16 deletions evmrpc/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,8 @@ func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.Block
}

// Get all tx hashes for the block
sdkCtx := a.ctxProvider(LatestCtxHeight)
height := block.Block.Height
signer := ethtypes.MakeSigner(
types.DefaultChainConfig().EthereumConfig(a.keeper.ChainID(sdkCtx)),
big.NewInt(sdkCtx.BlockHeight()),
uint64(sdkCtx.BlockTime().Unix()), //nolint:gosec
)
txHashes := getTxHashesFromBlock(a.ctxProvider, a.txConfigProvider, a.keeper, block, signer, shouldIncludeSynthetic(a.namespace))
txHashes := getTxHashesFromBlock(a.ctxProvider, a.txConfigProvider, a.keeper, block, shouldIncludeSynthetic(a.namespace))
// Get tx receipts for all hashes in parallel
wg := sync.WaitGroup{}
mtx := sync.Mutex{}
Expand All @@ -264,7 +258,7 @@ func (a *BlockAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.Block
mtx.Unlock()
}
} else {
encodedReceipt, err := encodeReceipt(a.ctxProvider, a.txConfigProvider, receipt, a.keeper, block, a.includeShellReceipts, signer)
encodedReceipt, err := encodeReceipt(a.ctxProvider, a.txConfigProvider, receipt, a.keeper, block, a.includeShellReceipts)
if err != nil {
mtx.Lock()
returnErr = err
Expand Down Expand Up @@ -320,26 +314,24 @@ func EncodeTmBlock(
chainConfig := types.DefaultChainConfig().EthereumConfig(k.ChainID(ctx))
transactions := []interface{}{}
latestCtx := ctxProvider(LatestCtxHeight)
signer := ethtypes.MakeSigner(
types.DefaultChainConfig().EthereumConfig(k.ChainID(latestCtx)),
big.NewInt(latestCtx.BlockHeight()),
uint64(latestCtx.BlockTime().Unix()), //nolint:gosec
)
msgs := filterTransactions(k, ctxProvider, txConfigProvider, block, signer, includeSyntheticTxs, includeBankTransfers)

msgs := filterTransactions(k, ctxProvider, txConfigProvider, block, includeSyntheticTxs, includeBankTransfers)

blockBloom := make([]byte, ethtypes.BloomByteLength)
for _, msg := range msgs {
switch m := msg.msg.(type) {
case *types.MsgEVMTransaction:
ethtx, _ := m.AsTransaction()
hash := ethtx.Hash()
receipt, _ := k.GetReceipt(latestCtx, hash)
if !fullTx {
transactions = append(transactions, hash.Hex())
} else {
newTx := export.NewRPCTransaction(ethtx, blockhash, number.Uint64(), uint64(blockTime.Second()), uint64(len(transactions)), baseFeePerGas, chainConfig) //nolint:gosec
blockUnix := toUint64(blockTime.Unix())
newTx := export.NewRPCTransaction(ethtx, blockhash, number.Uint64(), blockUnix, uint64(len(transactions)), baseFeePerGas, chainConfig)
replaceFrom(newTx, receipt)
transactions = append(transactions, newTx)
}
receipt, _ := k.GetReceipt(latestCtx, hash)
or := make([]byte, ethtypes.BloomByteLength)
bloom := ethtypes.Bloom{}
bloom.SetBytes(receipt.LogsBloom)
Expand Down
8 changes: 1 addition & 7 deletions evmrpc/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"encoding/json"
"errors"
"fmt"
"math/big"
"sort"
"sync"
"time"
Expand Down Expand Up @@ -828,13 +827,8 @@ func (f *LogFetcher) collectLogs(block *coretypes.ResultBlock, crit filters.Filt
ctx := f.ctxProvider(block.Block.Height)
totalLogs := uint(0)
evmTxIndex := 0
signer := ethtypes.MakeSigner(
evmtypes.DefaultChainConfig().EthereumConfig(f.k.ChainID(ctx)),
big.NewInt(ctx.BlockHeight()),
uint64(ctx.BlockTime().Unix()), //nolint:gosec
)

for _, hash := range getTxHashesFromBlock(f.ctxProvider, f.txConfigProvider, f.k, block, signer, f.includeSyntheticReceipts) {
for _, hash := range getTxHashesFromBlock(f.ctxProvider, f.txConfigProvider, f.k, block, f.includeSyntheticReceipts) {
receipt, found := getCachedReceipt(f.globalBlockCache, block.Block.Height, hash.hash)
if !found {
var err error
Expand Down
98 changes: 98 additions & 0 deletions evmrpc/rpcutils/sig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package rpcutils

import (
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
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/utils/helpers"
"github.com/sei-protocol/sei-chain/x/evm/derived"
evmtypes "github.com/sei-protocol/sei-chain/x/evm/types"
)

var signerMap = map[derived.SignerVersion]func(*big.Int) ethtypes.Signer{
derived.London: ethtypes.NewLondonSigner,
derived.Cancun: ethtypes.NewCancunSigner,
derived.Prague: ethtypes.NewPragueSigner,
}

// RecoverEVMSender recovers the sender address from an Ethereum transaction
// using the same logic as the preprocess ante handler.
// This ensures consistency between transaction preprocessing and RPC queries.
func RecoverEVMSender(ethTx *ethtypes.Transaction, blockHeight int64, blockTime int64) (common.Address, error) {
// Get the chain ID from the transaction
chainID := ethTx.ChainId()

// Get the chain config and determine the signer version
chainCfg := evmtypes.DefaultChainConfig()
ethCfg := chainCfg.EthereumConfig(chainID)

// Create the signer with the transaction's chain ID
var signer ethtypes.Signer
if chainID.Int64() == 0 {
signer = ethtypes.NewEIP155Signer(chainID)
} else {
var uintBlockTime uint64
if blockTime > 0 {
uintBlockTime = uint64(blockTime)
}
version := getSignerVersion(blockHeight, uintBlockTime, ethCfg)
signer = signerMap[version](chainID)
}

// Get raw signature values
V, R, S := ethTx.RawSignatureValues()

// Compute the transaction hash based on whether it's protected
var txHash common.Hash
if ethTx.Protected() {
// For protected transactions, adjust V and use signer hash
V = adjustV(V, ethTx.Type(), ethCfg.ChainID)
txHash = signer.Hash(ethTx)
} else {
// For unprotected transactions, use Frontier signer
txHash = ethtypes.FrontierSigner{}.Hash(ethTx)
}

// Recover the sender address
evmAddr, _, _, err := helpers.GetAddresses(V, R, S, txHash)
if err != nil {
return common.Address{}, err
}

return evmAddr, nil
}

// adjustV adjusts the V value for signature recovery based on transaction type and chain ID
func adjustV(V *big.Int, txType uint8, chainID *big.Int) *big.Int {
// Non-legacy TX always needs to be bumped by 27
if txType != ethtypes.LegacyTxType {
return new(big.Int).Add(V, utils.Big27)
}

// Legacy TX needs to be adjusted based on chainID
// Formula: V = V - (chainID * 2) - 8
V = new(big.Int).Sub(V, new(big.Int).Mul(chainID, utils.Big2))
return V.Sub(V, utils.Big8)
}

// getSignerVersion determines which signer version to use based on block height and time
func getSignerVersion(blockHeight int64, blockTime uint64, ethCfg *params.ChainConfig) derived.SignerVersion {
blockNum := big.NewInt(blockHeight)
switch {
case ethCfg.IsPrague(blockNum, blockTime):
return derived.Prague
case ethCfg.IsCancun(blockNum, blockTime):
return derived.Cancun
default:
return derived.London
}
}

// RecoverEVMSenderWithContext is a convenience wrapper that extracts block info from context
func RecoverEVMSenderWithContext(ctx sdk.Context, ethTx *ethtypes.Transaction) (common.Address, error) {
return RecoverEVMSender(ethTx, ctx.BlockHeight(), ctx.BlockTime().Unix())
}
Loading
Loading