Skip to content

Commit

Permalink
remove l2 hash from eth_getTransactionReceipt (0xPolygonHermez#3089)
Browse files Browse the repository at this point in the history
  • Loading branch information
tclemos authored Jan 18, 2024
1 parent cfe5048 commit 8972932
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 59 deletions.
2 changes: 1 addition & 1 deletion jsonrpc/endpoints_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ func (e *EthEndpoints) GetTransactionReceipt(hash types.ArgHash) (interface{}, t
return RPCErrorResponse(types.DefaultErrorCode, "failed to get tx receipt from state", err, true)
}

receipt, err := types.NewReceipt(*tx, r)
receipt, err := types.NewReceipt(*tx, r, state.Ptr(false))
if err != nil {
return RPCErrorResponse(types.DefaultErrorCode, "failed to build the receipt response", err, true)
}
Expand Down
155 changes: 106 additions & 49 deletions jsonrpc/endpoints_eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"math/big"
"strings"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -3239,22 +3238,79 @@ func TestGetTransactionCount(t *testing.T) {
}

func TestGetTransactionReceipt(t *testing.T) {
s, m, c := newSequencerMockedServer(t)
s, m, _ := newSequencerMockedServer(t)
defer s.Stop()

type testCase struct {
Name string
Hash common.Hash
ExpectedResult *ethTypes.Receipt
ExpectedError interface{}
ExpectedResult *types.Receipt
ExpectedError *types.RPCError
SetupMocks func(m *mocksWrapper, tc testCase)
}

chainID := big.NewInt(1)

privateKey, err := crypto.GenerateKey()
require.NoError(t, err)
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID)
require.NoError(t, err)

tx := ethTypes.NewTransaction(1, common.HexToAddress("0x111"), big.NewInt(2), 3, big.NewInt(4), []byte{5, 6, 7, 8})
signedTx, err := auth.Signer(auth.From, tx)
require.NoError(t, err)

l2Hash, err := state.GetL2Hash(*signedTx)
require.NoError(t, err)

log := &ethTypes.Log{Topics: []common.Hash{common.HexToHash("0x1")}, Data: []byte{}}
logs := []*ethTypes.Log{log}

stateRoot := common.HexToHash("0x112233")

receipt := &ethTypes.Receipt{
Type: signedTx.Type(),
PostState: stateRoot.Bytes(),
CumulativeGasUsed: 1,
BlockNumber: big.NewInt(2),
GasUsed: 3,
TxHash: signedTx.Hash(),
TransactionIndex: 4,
ContractAddress: common.HexToAddress("0x223344"),
Logs: logs,
Status: ethTypes.ReceiptStatusSuccessful,
EffectiveGasPrice: big.NewInt(5),
BlobGasUsed: 6,
BlobGasPrice: big.NewInt(7),
BlockHash: common.HexToHash("0x1"),
}

receipt.Bloom = ethTypes.CreateBloom(ethTypes.Receipts{receipt})

rpcReceipt := types.Receipt{
Root: stateRoot,
CumulativeGasUsed: types.ArgUint64(receipt.CumulativeGasUsed),
LogsBloom: receipt.Bloom,
Logs: receipt.Logs,
Status: types.ArgUint64(receipt.Status),
TxHash: receipt.TxHash,
TxL2Hash: &l2Hash,
TxIndex: types.ArgUint64(receipt.TransactionIndex),
BlockHash: receipt.BlockHash,
BlockNumber: types.ArgUint64(receipt.BlockNumber.Uint64()),
GasUsed: types.ArgUint64(receipt.GasUsed),
FromAddr: auth.From,
ToAddr: signedTx.To(),
ContractAddress: state.Ptr(receipt.ContractAddress),
Type: types.ArgUint64(receipt.Type),
EffectiveGasPrice: state.Ptr(types.ArgBig(*receipt.EffectiveGasPrice)),
}

testCases := []testCase{
{
Name: "Get TX receipt Successfully",
Hash: common.HexToHash("0x123"),
ExpectedResult: ethTypes.NewReceipt([]byte{}, false, 0),
ExpectedResult: &rpcReceipt,
ExpectedError: nil,
SetupMocks: func(m *mocksWrapper, tc testCase) {
m.DbTx.
Expand All @@ -3267,31 +3323,22 @@ func TestGetTransactionReceipt(t *testing.T) {
Return(m.DbTx, nil).
Once()

tx := ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{})
privateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x"))
require.NoError(t, err)
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1))
require.NoError(t, err)

signedTx, err := auth.Signer(auth.From, tx)
require.NoError(t, err)

m.State.
On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx).
Return(signedTx, nil).
Once()

m.State.
On("GetTransactionReceipt", context.Background(), tc.Hash, m.DbTx).
Return(tc.ExpectedResult, nil).
Return(receipt, nil).
Once()
},
},
{
Name: "Get TX receipt but tx not found",
Hash: common.HexToHash("0x123"),
ExpectedResult: nil,
ExpectedError: ethereum.NotFound,
ExpectedError: nil,
SetupMocks: func(m *mocksWrapper, tc testCase) {
m.DbTx.
On("Commit", context.Background()).
Expand Down Expand Up @@ -3335,7 +3382,7 @@ func TestGetTransactionReceipt(t *testing.T) {
Name: "TX receipt Not Found",
Hash: common.HexToHash("0x123"),
ExpectedResult: nil,
ExpectedError: ethereum.NotFound,
ExpectedError: nil,
SetupMocks: func(m *mocksWrapper, tc testCase) {
m.DbTx.
On("Commit", context.Background()).
Expand All @@ -3347,15 +3394,6 @@ func TestGetTransactionReceipt(t *testing.T) {
Return(m.DbTx, nil).
Once()

tx := ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{})
privateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x"))
require.NoError(t, err)
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1))
require.NoError(t, err)

signedTx, err := auth.Signer(auth.From, tx)
require.NoError(t, err)

m.State.
On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx).
Return(signedTx, nil).
Expand Down Expand Up @@ -3383,15 +3421,6 @@ func TestGetTransactionReceipt(t *testing.T) {
Return(m.DbTx, nil).
Once()

tx := ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{})
privateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x"))
require.NoError(t, err)
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1))
require.NoError(t, err)

signedTx, err := auth.Signer(auth.From, tx)
require.NoError(t, err)

m.State.
On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx).
Return(signedTx, nil).
Expand Down Expand Up @@ -3419,16 +3448,14 @@ func TestGetTransactionReceipt(t *testing.T) {
Return(m.DbTx, nil).
Once()

tx := ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{})

m.State.
On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx).
Return(tx, nil).
Once()

m.State.
On("GetTransactionReceipt", context.Background(), tc.Hash, m.DbTx).
Return(ethTypes.NewReceipt([]byte{}, false, 0), nil).
Return(receipt, nil).
Once()
},
},
Expand All @@ -3439,20 +3466,50 @@ func TestGetTransactionReceipt(t *testing.T) {
tc := testCase
tc.SetupMocks(m, tc)

result, err := c.TransactionReceipt(context.Background(), testCase.Hash)
res, err := s.JSONRPCCall("eth_getTransactionReceipt", tc.Hash.String())
require.NoError(t, err)

if result != nil || testCase.ExpectedResult != nil {
assert.Equal(t, testCase.ExpectedResult.TxHash, result.TxHash)
}
if testCase.ExpectedResult != nil {
require.NotNil(t, res.Result)
require.Nil(t, res.Error)

if err != nil || testCase.ExpectedError != nil {
if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok {
rpcErr := err.(rpc.Error)
assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode())
assert.Equal(t, expectedErr.Error(), rpcErr.Error())
} else {
assert.Equal(t, testCase.ExpectedError, err)
var result types.Receipt
err = json.Unmarshal(res.Result, &result)
require.NoError(t, err)

assert.Equal(t, rpcReceipt.Root.String(), result.Root.String())
assert.Equal(t, rpcReceipt.CumulativeGasUsed, result.CumulativeGasUsed)
assert.Equal(t, rpcReceipt.LogsBloom, result.LogsBloom)
assert.Equal(t, len(rpcReceipt.Logs), len(result.Logs))
for i := 0; i < len(rpcReceipt.Logs); i++ {
assert.Equal(t, rpcReceipt.Logs[i].Address, result.Logs[i].Address)
assert.Equal(t, rpcReceipt.Logs[i].Topics, result.Logs[i].Topics)
assert.Equal(t, rpcReceipt.Logs[i].Data, result.Logs[i].Data)
assert.Equal(t, rpcReceipt.Logs[i].BlockNumber, result.Logs[i].BlockNumber)
assert.Equal(t, rpcReceipt.Logs[i].TxHash, result.Logs[i].TxHash)
assert.Equal(t, rpcReceipt.Logs[i].TxIndex, result.Logs[i].TxIndex)
assert.Equal(t, rpcReceipt.Logs[i].BlockHash, result.Logs[i].BlockHash)
assert.Equal(t, rpcReceipt.Logs[i].Index, result.Logs[i].Index)
assert.Equal(t, rpcReceipt.Logs[i].Removed, result.Logs[i].Removed)
}
assert.Equal(t, rpcReceipt.Status, result.Status)
assert.Equal(t, rpcReceipt.TxHash, result.TxHash)
assert.Nil(t, result.TxL2Hash)
assert.Equal(t, rpcReceipt.TxIndex, result.TxIndex)
assert.Equal(t, rpcReceipt.BlockHash, result.BlockHash)
assert.Equal(t, rpcReceipt.BlockNumber, result.BlockNumber)
assert.Equal(t, rpcReceipt.GasUsed, result.GasUsed)
assert.Equal(t, rpcReceipt.FromAddr, result.FromAddr)
assert.Equal(t, rpcReceipt.ToAddr, result.ToAddr)
assert.Equal(t, rpcReceipt.ContractAddress, result.ContractAddress)
assert.Equal(t, rpcReceipt.Type, result.Type)
assert.Equal(t, rpcReceipt.EffectiveGasPrice, result.EffectiveGasPrice)
}

if res.Error != nil || tc.ExpectedError != nil {
rpcErr := res.Error.RPCError()
assert.Equal(t, tc.ExpectedError.ErrorCode(), rpcErr.ErrorCode())
assert.Equal(t, tc.ExpectedError.Error(), rpcErr.Error())
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion jsonrpc/endpoints_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ func (z *ZKEVMEndpoints) GetTransactionReceiptByL2Hash(hash types.ArgHash) (inte
return RPCErrorResponse(types.DefaultErrorCode, "failed to get tx receipt from state", err, true)
}

receipt, err := types.NewReceipt(*tx, r)
receipt, err := types.NewReceipt(*tx, r, state.Ptr(true))
if err != nil {
return RPCErrorResponse(types.DefaultErrorCode, "failed to build the receipt response", err, true)
}
Expand Down
36 changes: 32 additions & 4 deletions jsonrpc/endpoints_zkevm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ func TestGetBatchByNumber(t *testing.T) {
from, _ := state.GetSender(*tx)
V, R, S := tx.RawSignatureValues()

rpcReceipt, err := types.NewReceipt(*tx, receipt)
rpcReceipt, err := types.NewReceipt(*tx, receipt, state.Ptr(true))
require.NoError(t, err)

tc.ExpectedResult.Transactions = append(tc.ExpectedResult.Transactions,
Expand Down Expand Up @@ -2204,7 +2204,7 @@ func TestGetTransactionReceiptByL2Hash(t *testing.T) {
l2Hash, err := state.GetL2Hash(*signedTx)
require.NoError(t, err)

log := &ethTypes.Log{}
log := &ethTypes.Log{Topics: []common.Hash{common.HexToHash("0x1")}, Data: []byte{}}
logs := []*ethTypes.Log{log}

stateRoot := common.HexToHash("0x112233")
Expand Down Expand Up @@ -2235,7 +2235,7 @@ func TestGetTransactionReceiptByL2Hash(t *testing.T) {
Logs: receipt.Logs,
Status: types.ArgUint64(receipt.Status),
TxHash: receipt.TxHash,
TxL2Hash: l2Hash,
TxL2Hash: &l2Hash,
TxIndex: types.ArgUint64(receipt.TransactionIndex),
BlockHash: receipt.BlockHash,
BlockNumber: types.ArgUint64(receipt.BlockNumber.Uint64()),
Expand Down Expand Up @@ -2414,9 +2414,37 @@ func TestGetTransactionReceiptByL2Hash(t *testing.T) {
require.NotNil(t, res.Result)
require.Nil(t, res.Error)

var result types.Transaction
var result types.Receipt
err = json.Unmarshal(res.Result, &result)
require.NoError(t, err)

assert.Equal(t, rpcReceipt.Root.String(), result.Root.String())
assert.Equal(t, rpcReceipt.CumulativeGasUsed, result.CumulativeGasUsed)
assert.Equal(t, rpcReceipt.LogsBloom, result.LogsBloom)
assert.Equal(t, len(rpcReceipt.Logs), len(result.Logs))
for i := 0; i < len(rpcReceipt.Logs); i++ {
assert.Equal(t, rpcReceipt.Logs[i].Address, result.Logs[i].Address)
assert.Equal(t, rpcReceipt.Logs[i].Topics, result.Logs[i].Topics)
assert.Equal(t, rpcReceipt.Logs[i].Data, result.Logs[i].Data)
assert.Equal(t, rpcReceipt.Logs[i].BlockNumber, result.Logs[i].BlockNumber)
assert.Equal(t, rpcReceipt.Logs[i].TxHash, result.Logs[i].TxHash)
assert.Equal(t, rpcReceipt.Logs[i].TxIndex, result.Logs[i].TxIndex)
assert.Equal(t, rpcReceipt.Logs[i].BlockHash, result.Logs[i].BlockHash)
assert.Equal(t, rpcReceipt.Logs[i].Index, result.Logs[i].Index)
assert.Equal(t, rpcReceipt.Logs[i].Removed, result.Logs[i].Removed)
}
assert.Equal(t, rpcReceipt.Status, result.Status)
assert.Equal(t, rpcReceipt.TxHash, result.TxHash)
assert.Equal(t, rpcReceipt.TxL2Hash, result.TxL2Hash)
assert.Equal(t, rpcReceipt.TxIndex, result.TxIndex)
assert.Equal(t, rpcReceipt.BlockHash, result.BlockHash)
assert.Equal(t, rpcReceipt.BlockNumber, result.BlockNumber)
assert.Equal(t, rpcReceipt.GasUsed, result.GasUsed)
assert.Equal(t, rpcReceipt.FromAddr, result.FromAddr)
assert.Equal(t, rpcReceipt.ToAddr, result.ToAddr)
assert.Equal(t, rpcReceipt.ContractAddress, result.ContractAddress)
assert.Equal(t, rpcReceipt.Type, result.Type)
assert.Equal(t, rpcReceipt.EffectiveGasPrice, result.EffectiveGasPrice)
}

if res.Error != nil || tc.ExpectedError != nil {
Expand Down
12 changes: 8 additions & 4 deletions jsonrpc/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ func NewTransaction(
res.BlockHash = &receipt.BlockHash
ti := ArgUint64(receipt.TransactionIndex)
res.TxIndex = &ti
rpcReceipt, err := NewReceipt(tx, receipt)
rpcReceipt, err := NewReceipt(tx, receipt, includeExtraInfo)
if err != nil {
return nil, err
}
Expand All @@ -602,7 +602,6 @@ type Receipt struct {
Logs []*types.Log `json:"logs"`
Status ArgUint64 `json:"status"`
TxHash common.Hash `json:"transactionHash"`
TxL2Hash common.Hash `json:"transactionL2Hash"`
TxIndex ArgUint64 `json:"transactionIndex"`
BlockHash common.Hash `json:"blockHash"`
BlockNumber ArgUint64 `json:"blockNumber"`
Expand All @@ -612,10 +611,11 @@ type Receipt struct {
ContractAddress *common.Address `json:"contractAddress"`
Type ArgUint64 `json:"type"`
EffectiveGasPrice *ArgBig `json:"effectiveGasPrice,omitempty"`
TxL2Hash *common.Hash `json:"transactionL2Hash,omitempty"`
}

// NewReceipt creates a new Receipt instance
func NewReceipt(tx types.Transaction, r *types.Receipt) (Receipt, error) {
func NewReceipt(tx types.Transaction, r *types.Receipt, includeExtraInfo *bool) (Receipt, error) {
to := tx.To()
logs := r.Logs
if logs == nil {
Expand Down Expand Up @@ -656,12 +656,16 @@ func NewReceipt(tx types.Transaction, r *types.Receipt) (Receipt, error) {
FromAddr: from,
ToAddr: to,
Type: ArgUint64(r.Type),
TxL2Hash: l2Hash,
}
if r.EffectiveGasPrice != nil {
egp := ArgBig(*r.EffectiveGasPrice)
receipt.EffectiveGasPrice = &egp
}

if includeExtraInfo != nil && *includeExtraInfo {
receipt.TxL2Hash = &l2Hash
}

return receipt, nil
}

Expand Down

0 comments on commit 8972932

Please sign in to comment.