diff --git a/contracts/test/EVMPrecompileTest.js b/contracts/test/EVMPrecompileTest.js index c094334f8f..60ac531776 100644 --- a/contracts/test/EVMPrecompileTest.js +++ b/contracts/test/EVMPrecompileTest.js @@ -109,35 +109,35 @@ describe("EVM Test", function () { }); }); - // TODO: Update when we add gov query precompiles - describe("EVM Gov Precompile Tester", function () { - let govProposal; - // TODO: Import this - const GovPrecompileContract = '0x0000000000000000000000000000000000001006'; - before(async function() { - govProposal = readDeploymentOutput('gov_proposal_output.txt'); - await sleep(1000); - - // Create a proposal - const [signer, _] = await ethers.getSigners(); - owner = await signer.getAddress(); - - const contractABIPath = path.join(__dirname, '../../precompiles/gov/abi.json'); - const contractABI = require(contractABIPath); - // Get a contract instance - gov = new ethers.Contract(GovPrecompileContract, contractABI, signer); - }); - - it("Gov deposit", async function () { - const depositAmount = ethers.parseEther('0.01'); - const deposit = await gov.deposit(govProposal, { - value: depositAmount, - }) - const receipt = await deposit.wait(); - expect(receipt.status).to.equal(1); - // TODO: Add gov query precompile here - }); - }); + // // TODO: Update when we add gov query precompiles + // describe("EVM Gov Precompile Tester", function () { + // let govProposal; + // // TODO: Import this + // const GovPrecompileContract = '0x0000000000000000000000000000000000001006'; + // before(async function() { + // govProposal = readDeploymentOutput('gov_proposal_output.txt'); + // await sleep(1000); + + // // Create a proposal + // const [signer, _] = await ethers.getSigners(); + // owner = await signer.getAddress(); + + // const contractABIPath = path.join(__dirname, '../../precompiles/gov/abi.json'); + // const contractABI = require(contractABIPath); + // // Get a contract instance + // gov = new ethers.Contract(GovPrecompileContract, contractABI, signer); + // }); + + // it("Gov deposit", async function () { + // const depositAmount = ethers.parseEther('0.01'); + // const deposit = await gov.deposit(govProposal, { + // value: depositAmount, + // }) + // const receipt = await deposit.wait(); + // expect(receipt.status).to.equal(1); + // // TODO: Add gov query precompile here + // }); + // }); // TODO: Update when we add distribution query precompiles describe("EVM Distribution Precompile Tester", function () { diff --git a/evmrpc/block.go b/evmrpc/block.go index 81f8345942..2b756d91fd 100644 --- a/evmrpc/block.go +++ b/evmrpc/block.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/lib/ethapi" "github.com/ethereum/go-ethereum/rpc" "github.com/sei-protocol/sei-chain/x/evm/keeper" "github.com/sei-protocol/sei-chain/x/evm/types" @@ -152,12 +153,15 @@ func EncodeTmBlock( ) (map[string]interface{}, error) { number := big.NewInt(block.Block.Height) blockhash := common.HexToHash(block.BlockID.Hash.String()) + blockTime := block.Block.Time lastHash := common.HexToHash(block.Block.LastBlockID.Hash.String()) appHash := common.HexToHash(block.Block.AppHash.String()) txHash := common.HexToHash(block.Block.DataHash.String()) resultHash := common.HexToHash(block.Block.LastResultsHash.String()) miner := common.HexToAddress(block.Block.ProposerAddress.String()) + baseFeePerGas := k.GetBaseFeePerGas(ctx).TruncateInt().BigInt() gasLimit, gasWanted := int64(0), int64(0) + chainConfig := types.DefaultChainConfig().EthereumConfig(k.ChainID(ctx)) transactions := []interface{}{} for i, txRes := range blockRes.TxsResults { gasLimit += txRes.GasWanted @@ -181,7 +185,8 @@ func EncodeTmBlock( if err != nil { continue } - transactions = append(transactions, hydrateTransaction(ethtx, number, blockhash, receipt)) + newTx := ethapi.NewRPCTransaction(ethtx, blockhash, number.Uint64(), uint64(blockTime.Second()), uint64(receipt.TransactionIndex), baseFeePerGas, chainConfig) + transactions = append(transactions, newTx) } } } @@ -209,7 +214,7 @@ func EncodeTmBlock( "size": hexutil.Uint64(block.Block.Size()), "uncles": []common.Hash{}, // inapplicable to Sei "transactions": transactions, - "baseFeePerGas": (*hexutil.Big)(k.GetBaseFeePerGas(ctx).TruncateInt().BigInt()), + "baseFeePerGas": (*hexutil.Big)(baseFeePerGas), } if fullTx { result["totalDifficulty"] = (*hexutil.Big)(big.NewInt(0)) // inapplicable to Sei diff --git a/evmrpc/block_test.go b/evmrpc/block_test.go index 331158bdb2..29aa42912f 100644 --- a/evmrpc/block_test.go +++ b/evmrpc/block_test.go @@ -90,9 +90,9 @@ func verifyBlockResult(t *testing.T, resObj map[string]interface{}) { require.Equal(t, "0x65254651", resObj["timestamp"]) tx := resObj["transactions"].([]interface{})[0].(map[string]interface{}) require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000001", tx["blockHash"]) - require.Equal(t, "0x1234567890123456789012345678901234567890", tx["from"]) + require.Equal(t, "0x5b4eba929f3811980f5ae0c5d04fa200f837df4e", tx["from"]) require.Equal(t, "0x3e8", tx["gas"]) - require.Equal(t, "0xa", tx["gasPrice"]) + require.Equal(t, "0x0", tx["gasPrice"]) require.Equal(t, "0xa", tx["maxFeePerGas"]) require.Equal(t, "0x0", tx["maxPriorityFeePerGas"]) require.Equal(t, "0xf02362077ac075a397344172496b28e913ce5294879d811bb0269b3be20a872e", tx["hash"]) diff --git a/evmrpc/tx.go b/evmrpc/tx.go index 16164cfa7d..805d670fb7 100644 --- a/evmrpc/tx.go +++ b/evmrpc/tx.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/lib/ethapi" "github.com/ethereum/go-ethereum/rpc" "github.com/sei-protocol/sei-chain/x/evm/keeper" "github.com/sei-protocol/sei-chain/x/evm/types" @@ -68,7 +69,7 @@ func (t *TransactionAPI) GetVMError(hash common.Hash) (result string, returnErr return receipt.VmError, nil } -func (t *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (result *RPCTransaction, returnErr error) { +func (t *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (result *ethapi.RPCTransaction, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getTransactionByBlockNumberAndIndex", t.connectionType, startTime, returnErr == nil) blockNumber, err := getBlockNumber(ctx, t.tmClient, blockNr) @@ -82,7 +83,7 @@ func (t *TransactionAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context return t.getTransactionWithBlock(block, index) } -func (t *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (result *RPCTransaction, returnErr error) { +func (t *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (result *ethapi.RPCTransaction, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getTransactionByBlockHashAndIndex", t.connectionType, startTime, returnErr == nil) block, err := blockByHash(ctx, t.tmClient, blockHash[:]) @@ -92,7 +93,7 @@ func (t *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, return t.getTransactionWithBlock(block, index) } -func (t *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (result *RPCTransaction, returnErr error) { +func (t *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (result *ethapi.RPCTransaction, returnErr error) { startTime := time.Now() defer recordMetrics("eth_getTransactionByHash", t.connectionType, startTime, returnErr == nil) sdkCtx := t.ctxProvider(LatestCtxHeight) @@ -112,7 +113,7 @@ func (t *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.H ) from, _ := ethtypes.Sender(signer, etx) v, r, s := etx.RawSignatureValues() - res := RPCTransaction{ + res := ethapi.RPCTransaction{ Type: hexutil.Uint64(etx.Type()), From: from, Gas: hexutil.Uint64(etx.Gas()), @@ -181,7 +182,7 @@ func (t *TransactionAPI) GetTransactionCount(ctx context.Context, address common return (*hexutil.Uint64)(&nonce), nil } -func (t *TransactionAPI) getTransactionWithBlock(block *coretypes.ResultBlock, index hexutil.Uint) (*RPCTransaction, error) { +func (t *TransactionAPI) getTransactionWithBlock(block *coretypes.ResultBlock, index hexutil.Uint) (*ethapi.RPCTransaction, error) { if int(index) >= len(block.Block.Txs) { return nil, nil } @@ -193,8 +194,14 @@ func (t *TransactionAPI) getTransactionWithBlock(block *coretypes.ResultBlock, i if err != nil { return nil, err } - res := hydrateTransaction(ethtx, big.NewInt(block.Block.Height), common.HexToHash(block.BlockID.Hash.String()), receipt) - return &res, nil + height := int64(receipt.BlockNumber) + baseFeePerGas := t.keeper.GetBaseFee(t.ctxProvider(height)) + chainConfig := types.DefaultChainConfig().EthereumConfig(t.keeper.ChainID(t.ctxProvider(height))) + blockHash := common.HexToHash(block.BlockID.Hash.String()) + blockNumber := uint64(block.Block.Height) + blockTime := block.Block.Time + res := ethapi.NewRPCTransaction(ethtx, blockHash, blockNumber, uint64(blockTime.Second()), uint64(receipt.TransactionIndex), baseFeePerGas, chainConfig) + return res, nil } func (t *TransactionAPI) Sign(addr common.Address, data hexutil.Bytes) (result hexutil.Bytes, returnErr error) { diff --git a/evmrpc/tx_test.go b/evmrpc/tx_test.go index 26d464a75e..002c31f87b 100644 --- a/evmrpc/tx_test.go +++ b/evmrpc/tx_test.go @@ -117,7 +117,7 @@ func TestGetTransaction(t *testing.T) { resObj = resObj["result"].(map[string]interface{}) require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000001", resObj["blockHash"].(string)) require.Equal(t, "0x8", resObj["blockNumber"].(string)) - require.Equal(t, "0x1234567890123456789012345678901234567890", resObj["from"].(string)) + require.Equal(t, "0x5b4eba929f3811980f5ae0c5d04fa200f837df4e", resObj["from"].(string)) require.Equal(t, "0x3e8", resObj["gas"].(string)) require.Equal(t, "0xa", resObj["gasPrice"].(string)) require.Equal(t, "0xa", resObj["maxFeePerGas"].(string)) diff --git a/evmrpc/txpool.go b/evmrpc/txpool.go index 8f77d996ad..95d90bd1e4 100644 --- a/evmrpc/txpool.go +++ b/evmrpc/txpool.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/lib/ethapi" "github.com/sei-protocol/sei-chain/x/evm/keeper" "github.com/sei-protocol/sei-chain/x/evm/types" rpcclient "github.com/tendermint/tendermint/rpc/client" @@ -31,12 +32,12 @@ func NewTxPoolAPI(tmClient rpcclient.Client, k *keeper.Keeper, ctxProvider func( } // For now, we put all unconfirmed txs in pending and none in queued -func (t *TxPoolAPI) Content(ctx context.Context) (result map[string]map[string]map[string]*RPCTransaction, returnErr error) { +func (t *TxPoolAPI) Content(ctx context.Context) (result map[string]map[string]map[string]*ethapi.RPCTransaction, returnErr error) { startTime := time.Now() defer recordMetrics("sei_content", t.connectionType, startTime, returnErr == nil) - content := map[string]map[string]map[string]*RPCTransaction{ - "pending": make(map[string]map[string]*RPCTransaction), - "queued": make(map[string]map[string]*RPCTransaction), + content := map[string]map[string]map[string]*ethapi.RPCTransaction{ + "pending": make(map[string]map[string]*ethapi.RPCTransaction), + "queued": make(map[string]map[string]*ethapi.RPCTransaction), } total := t.txPoolConfig.maxNumTxs @@ -63,14 +64,15 @@ func (t *TxPoolAPI) Content(ctx context.Context) (result map[string]map[string]m } nonce := ethTx.Nonce() - res := hydratePendingTransaction(ethTx) + chainConfig := types.DefaultChainConfig().EthereumConfig(t.keeper.ChainID(sdkCtx)) + res := ethapi.NewRPCPendingTransaction(ethTx, nil, chainConfig) nonceStr := strconv.FormatUint(nonce, 10) if content["pending"][fromAddr.String()] == nil { - content["pending"][fromAddr.String()] = map[string]*RPCTransaction{ - nonceStr: &res, + content["pending"][fromAddr.String()] = map[string]*ethapi.RPCTransaction{ + nonceStr: res, } } else { - content["pending"][fromAddr.String()][nonceStr] = &res + content["pending"][fromAddr.String()][nonceStr] = res } } return content, nil diff --git a/evmrpc/utils.go b/evmrpc/utils.go index 7b4c84aae7..4e8a8e311e 100644 --- a/evmrpc/utils.go +++ b/evmrpc/utils.go @@ -15,15 +15,10 @@ import ( "github.com/cosmos/cosmos-sdk/codec/legacy" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rpc" "github.com/sei-protocol/sei-chain/utils/metrics" - "github.com/sei-protocol/sei-chain/x/evm/ante" "github.com/sei-protocol/sei-chain/x/evm/keeper" - "github.com/sei-protocol/sei-chain/x/evm/types" "github.com/tendermint/tendermint/libs/bytes" rpcclient "github.com/tendermint/tendermint/rpc/client" "github.com/tendermint/tendermint/rpc/coretypes" @@ -36,110 +31,6 @@ const LatestCtxHeight int64 = -1 // the block is exactly half-utilized. const GasUsedRatio float64 = 0.5 -type RPCTransaction struct { - BlockHash *common.Hash `json:"blockHash"` - BlockNumber *hexutil.Big `json:"blockNumber"` - From common.Address `json:"from"` - Gas hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` - GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` - MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` - Hash common.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` - Nonce hexutil.Uint64 `json:"nonce"` - To *common.Address `json:"to"` - TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` - Value *hexutil.Big `json:"value"` - Type hexutil.Uint64 `json:"type"` - Accesses *ethtypes.AccessList `json:"accessList,omitempty"` - ChainID *hexutil.Big `json:"chainId,omitempty"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - YParity *hexutil.Uint64 `json:"yParity,omitempty"` -} - -func hydrateTransaction( - tx *ethtypes.Transaction, - blocknumber *big.Int, - blockhash common.Hash, - receipt *types.Receipt, -) RPCTransaction { - idx := hexutil.Uint64(receipt.TransactionIndex) - al := tx.AccessList() - v, r, s := tx.RawSignatureValues() - var yparity *hexutil.Uint64 - if tx.Type() != ethtypes.LegacyTxType { - yp := hexutil.Uint64(v.Sign()) - yparity = &yp - } - return RPCTransaction{ - BlockHash: &blockhash, - BlockNumber: (*hexutil.Big)(blocknumber), - From: common.HexToAddress(receipt.From), - Gas: hexutil.Uint64(tx.Gas()), - GasPrice: (*hexutil.Big)(tx.GasPrice()), - GasFeeCap: (*hexutil.Big)(tx.GasFeeCap()), - GasTipCap: (*hexutil.Big)(tx.GasTipCap()), - MaxFeePerBlobGas: (*hexutil.Big)(tx.BlobGasFeeCap()), - Hash: tx.Hash(), - Input: tx.Data(), - Nonce: hexutil.Uint64(tx.Nonce()), - To: tx.To(), - Type: hexutil.Uint64(tx.Type()), - TransactionIndex: &idx, - Value: (*hexutil.Big)(tx.Value()), - Accesses: &al, - ChainID: (*hexutil.Big)(tx.ChainId()), - BlobVersionedHashes: tx.BlobHashes(), - V: (*hexutil.Big)(v), - S: (*hexutil.Big)(s), - R: (*hexutil.Big)(r), - YParity: yparity, - } -} - -func hydratePendingTransaction( - tx *ethtypes.Transaction, -) RPCTransaction { - v, r, s := tx.RawSignatureValues() - v = ante.AdjustV(v, tx.Type(), tx.ChainId()) - var yparity *hexutil.Uint64 - if tx.Type() != ethtypes.LegacyTxType { - yp := hexutil.Uint64(v.Sign()) - yparity = &yp - } - al := tx.AccessList() - signer := ethtypes.NewCancunSigner(tx.ChainId()) - fromAddr, err := signer.Sender(tx) - if err != nil { - return RPCTransaction{} - } - return RPCTransaction{ - From: fromAddr, - Gas: hexutil.Uint64(tx.Gas()), - GasPrice: (*hexutil.Big)(tx.GasPrice()), - GasFeeCap: (*hexutil.Big)(tx.GasFeeCap()), - GasTipCap: (*hexutil.Big)(tx.GasTipCap()), - MaxFeePerBlobGas: (*hexutil.Big)(tx.BlobGasFeeCap()), - Hash: tx.Hash(), - Input: tx.Data(), - Nonce: hexutil.Uint64(tx.Nonce()), - To: tx.To(), - Value: (*hexutil.Big)(tx.Value()), - Type: hexutil.Uint64(tx.Type()), - Accesses: &al, - ChainID: (*hexutil.Big)(tx.ChainId()), - BlobVersionedHashes: tx.BlobHashes(), - V: (*hexutil.Big)(v), - S: (*hexutil.Big)(s), - R: (*hexutil.Big)(r), - YParity: yparity, - } -} - func GetBlockNumberByNrOrHash(ctx context.Context, tmClient rpcclient.Client, blockNrOrHash rpc.BlockNumberOrHash) (*int64, error) { if blockNrOrHash.BlockHash != nil { res, err := blockByHash(ctx, tmClient, blockNrOrHash.BlockHash[:]) diff --git a/go.mod b/go.mod index 2c4da3eae7..71851bea42 100644 --- a/go.mod +++ b/go.mod @@ -349,7 +349,7 @@ replace ( github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.3.11 github.com/cosmos/iavl => github.com/sei-protocol/sei-iavl v0.1.9 github.com/cosmos/ibc-go/v3 => github.com/sei-protocol/sei-ibc-go/v3 v3.3.0 - github.com/ethereum/go-ethereum => github.com/sei-protocol/go-ethereum v1.13.5-sei-16 + github.com/ethereum/go-ethereum => github.com/sei-protocol/go-ethereum v1.13.5-sei-17 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/sei-protocol/sei-db => github.com/sei-protocol/sei-db v0.0.36 // Latest goleveldb is broken, we have to stick to this version diff --git a/go.sum b/go.sum index 728acaf632..4e485c9754 100644 --- a/go.sum +++ b/go.sum @@ -1343,8 +1343,8 @@ github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod github.com/securego/gosec/v2 v2.11.0 h1:+PDkpzR41OI2jrw1q6AdXZCbsNGNGT7pQjal0H0cArI= github.com/securego/gosec/v2 v2.11.0/go.mod h1:SX8bptShuG8reGC0XS09+a4H2BoWSJi+fscA+Pulbpo= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/sei-protocol/go-ethereum v1.13.5-sei-16 h1:bPQw44//5XHDZWfwO98g2Hie5HguxYZY+AiRsYMBdVg= -github.com/sei-protocol/go-ethereum v1.13.5-sei-16/go.mod h1:kcRZmuzRn1lVejiFNTz4l4W7imnpq1bDAnuKS/RyhbQ= +github.com/sei-protocol/go-ethereum v1.13.5-sei-17 h1:NQcNuL/nmLCzVJFj6Za4ZrNj1ODTmNKDH6ELrJIEpkY= +github.com/sei-protocol/go-ethereum v1.13.5-sei-17/go.mod h1:kcRZmuzRn1lVejiFNTz4l4W7imnpq1bDAnuKS/RyhbQ= github.com/sei-protocol/goutils v0.0.2 h1:Bfa7Sv+4CVLNM20QcpvGb81B8C5HkQC/kW1CQpIbXDA= github.com/sei-protocol/goutils v0.0.2/go.mod h1:iYE2DuJfEnM+APPehr2gOUXfuLuPsVxorcDO+Tzq9q8= github.com/sei-protocol/sei-cosmos v0.3.11 h1:mHhscQlvF6temJ8AsVBBAD6ZY44q5tUSgxhsMXrduRg=