Skip to content

Commit

Permalink
Merge pull request #309 from m-Peter/eth-get-tx-by-hash-add-chain-id
Browse files Browse the repository at this point in the history
Add missing fields to the response of `eth_getTransactionByHash`
  • Loading branch information
m-Peter authored Jun 18, 2024
2 parents 2ecf54c + d85b44f commit d5292a2
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 18 deletions.
2 changes: 1 addition & 1 deletion api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ func (b *BlockChainAPI) GetTransactionByHash(
return handleError[*Transaction](b.logger, err)
}

return NewTransaction(tx, *rcp)
return NewTransaction(tx, *rcp, *b.config)
}

// GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
Expand Down
65 changes: 54 additions & 11 deletions api/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
errs "github.com/onflow/flow-evm-gateway/api/errors"
"github.com/onflow/flow-evm-gateway/config"
"github.com/onflow/flow-evm-gateway/models"

"github.com/onflow/go-ethereum/common"
Expand Down Expand Up @@ -91,7 +92,11 @@ type Transaction struct {
YParity *hexutil.Uint64 `json:"yParity,omitempty"`
}

func NewTransaction(tx models.Transaction, receipt types.Receipt) (*Transaction, error) {
func NewTransaction(
tx models.Transaction,
receipt types.Receipt,
config config.Config,
) (*Transaction, error) {
txHash, err := tx.Hash()
if err != nil {
return nil, err
Expand All @@ -112,23 +117,61 @@ func NewTransaction(tx models.Transaction, receipt types.Receipt) (*Transaction,
v, r, s := tx.RawSignatureValues()
index := uint64(receipt.TransactionIndex)

return &Transaction{
Hash: txHash,
BlockHash: &receipt.BlockHash,
BlockNumber: (*hexutil.Big)(receipt.BlockNumber),
result := &Transaction{
Type: hexutil.Uint64(tx.Type()),
From: from,
To: to,
Gas: hexutil.Uint64(receipt.GasUsed),
GasPrice: (*hexutil.Big)(receipt.EffectiveGasPrice),
Gas: hexutil.Uint64(tx.Gas()),
GasPrice: (*hexutil.Big)(tx.GasPrice()),
Hash: txHash,
Input: tx.Data(),
Nonce: hexutil.Uint64(tx.Nonce()),
TransactionIndex: (*hexutil.Uint64)(&index),
To: to,
Value: (*hexutil.Big)(tx.Value()),
Type: hexutil.Uint64(tx.Type()),
V: (*hexutil.Big)(v),
R: (*hexutil.Big)(r),
S: (*hexutil.Big)(s),
}, nil
BlockHash: &receipt.BlockHash,
BlockNumber: (*hexutil.Big)(receipt.BlockNumber),
TransactionIndex: (*hexutil.Uint64)(&index),
}
chainID := config.EVMNetworkID

switch tx.Type() {
case types.LegacyTxType:
result.ChainID = (*hexutil.Big)(chainID)
case types.AccessListTxType:
al := tx.AccessList()
yparity := hexutil.Uint64(v.Sign())
result.Accesses = &al
result.ChainID = (*hexutil.Big)(chainID)
result.YParity = &yparity
case types.DynamicFeeTxType:
al := tx.AccessList()
yparity := hexutil.Uint64(v.Sign())
result.Accesses = &al
result.ChainID = (*hexutil.Big)(chainID)
result.YParity = &yparity
result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap())
result.GasTipCap = (*hexutil.Big)(tx.GasTipCap())
// Since BaseFee is `0`, this is the effective gas price
// the sender is willing to pay.
result.GasPrice = (*hexutil.Big)(tx.GasFeeCap())
case types.BlobTxType:
al := tx.AccessList()
yparity := hexutil.Uint64(v.Sign())
result.Accesses = &al
result.ChainID = (*hexutil.Big)(chainID)
result.YParity = &yparity
result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap())
result.GasTipCap = (*hexutil.Big)(tx.GasTipCap())
// Since BaseFee is `0`, this is the effective gas price
// the sender is willing to pay.
result.GasPrice = (*hexutil.Big)(tx.GasFeeCap())
result.MaxFeePerBlobGas = (*hexutil.Big)(tx.BlobGasFeeCap())
result.BlobVersionedHashes = tx.BlobHashes()
}

return result, nil
}

// SignTransactionResult represents a RLP encoded signed transaction.
Expand Down
2 changes: 1 addition & 1 deletion api/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func (s *StreamAPI) NewPendingTransactions(ctx context.Context, fullTx *bool) (*
return nil, fmt.Errorf("failed to compute tx hash: %w", err)
}

t, err := NewTransaction(tx, *rcp)
t, err := NewTransaction(tx, *rcp, *s.config)
if err != nil {
return nil, err
}
Expand Down
25 changes: 25 additions & 0 deletions models/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ type Transaction interface {
Value() *big.Int
Type() uint8
Gas() uint64
GasFeeCap() *big.Int
GasTipCap() *big.Int
GasPrice() *big.Int
BlobGas() uint64
BlobGasFeeCap() *big.Int
BlobHashes() []common.Hash
Size() uint64
AccessList() gethTypes.AccessList
MarshalBinary() ([]byte, error)
}

Expand Down Expand Up @@ -79,6 +84,14 @@ func (dc DirectCall) Gas() uint64 {
return dc.DirectCall.GasLimit
}

func (dc DirectCall) GasFeeCap() *big.Int {
return big.NewInt(0)
}

func (dc DirectCall) GasTipCap() *big.Int {
return big.NewInt(0)
}

func (dc DirectCall) GasPrice() *big.Int {
return big.NewInt(0)
}
Expand All @@ -87,6 +100,14 @@ func (dc DirectCall) BlobGas() uint64 {
return 0
}

func (dc DirectCall) BlobGasFeeCap() *big.Int {
return big.NewInt(0)
}

func (dc DirectCall) BlobHashes() []common.Hash {
return []common.Hash{}
}

func (dc DirectCall) Size() uint64 {
encoded, err := dc.MarshalBinary()
if err != nil {
Expand All @@ -95,6 +116,10 @@ func (dc DirectCall) Size() uint64 {
return uint64(len(encoded))
}

func (dc DirectCall) AccessList() gethTypes.AccessList {
return gethTypes.AccessList{}
}

func (dc DirectCall) MarshalBinary() ([]byte, error) {
return dc.DirectCall.Encode()
}
Expand Down
8 changes: 6 additions & 2 deletions tests/e2e_web3js_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ func TestWeb3_E2E(t *testing.T) {
runWeb3Test(t, "eth_deploy_contract_and_interact_test")
})

t.Run("eth_getTransactionByHash", func(t *testing.T) {
runWeb3Test(t, "eth_get_transaction_by_hash_test")
})

t.Run("transfer Flow between EOA accounts", func(t *testing.T) {
runWeb3Test(t, "eth_transfer_between_eoa_accounts_test")
})
Expand All @@ -38,10 +42,10 @@ func TestWeb3_E2E(t *testing.T) {
runWeb3Test(t, "eth_get_filter_logs_test")
})

t.Run("rate-limit requests made by single client", func(t *testing.T) {
t.Run("rate-limit requests made by single client", func(t *testing.T) {
runWeb3Test(t, "eth_rate_limit_test")
})

t.Run("batch run transactions", func(t *testing.T) {
// create multiple value transfers and batch run them before the test
runWeb3TestWithSetup(t, "eth_batch_retrieval_test", func(emu emulator.Emulator) {
Expand Down
33 changes: 33 additions & 0 deletions tests/web3js/eth_get_transaction_by_hash_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const { assert } = require('chai')
const conf = require('./config')
const helpers = require('./helpers')
const web3 = conf.web3

it('returns proper response for eth_getTransactionByHash', async () => {
let deployed = await helpers.deployContract('storage')
let contractAddress = deployed.receipt.contractAddress

// make sure deploy results are correct
assert.equal(deployed.receipt.status, conf.successStatus)

let updateData = deployed.contract.methods.store(1337).encodeABI()
let result = await helpers.signAndSend({
from: conf.eoa.address,
to: contractAddress,
data: updateData,
gas: 25000,
value: 0,
maxFeePerGas: 3000000000,
maxPriorityFeePerGas: 800000000,
})
assert.equal(result.receipt.status, conf.successStatus)

let tx = await web3.eth.getTransactionFromBlock(result.receipt.blockNumber, 0)
assert.equal(tx.type, 2n)
assert.deepEqual(tx.accessList, [])
assert.equal(tx.chainId, 646n)
assert.equal(tx.gas, 25000n)
assert.equal(tx.maxFeePerGas, 3000000000n)
assert.equal(tx.maxPriorityFeePerGas, 800000000n)
assert.equal(tx.gasPrice, 3000000000n)
}).timeout(10 * 1000)
6 changes: 3 additions & 3 deletions tests/web3js/eth_non_interactive_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ it('get transaction', async () => {
assert.deepEqual(blockTx, tx)
assert.isString(tx.hash)
assert.equal(tx.blockNumber, conf.startBlockHeight)
assert.isAbove(parseInt(tx.gas), 1)
assert.equal(tx.gas, 300000n)
assert.isNotEmpty(tx.from)
assert.isNotEmpty(tx.r)
assert.isNotEmpty(tx.s)
Expand All @@ -109,10 +109,10 @@ it('get transaction', async () => {
assert.equal(rcp.blockNumber, conf.startBlockHeight)
assert.equal(rcp.from, tx.from)
assert.equal(rcp.to, tx.to)
assert.equal(rcp.cumulativeGasUsed, tx.gas) // todo check
assert.equal(rcp.cumulativeGasUsed, 21000n) // todo check
assert.equal(rcp.transactionHash, tx.hash)
assert.equal(rcp.status, conf.successStatus)
assert.equal(rcp.gasUsed, tx.gas)
assert.equal(rcp.gasUsed, 21000n)
})

it('get mining status', async () => {
Expand Down

0 comments on commit d5292a2

Please sign in to comment.