Skip to content

Commit

Permalink
Merge pull request #107 from Inphi/inphi/ecotone
Browse files Browse the repository at this point in the history
Support the Ecotone upgrade
  • Loading branch information
Inphi authored Feb 22, 2024
2 parents 54b996d + bac17d0 commit 599a398
Show file tree
Hide file tree
Showing 9 changed files with 449 additions and 22 deletions.
4 changes: 2 additions & 2 deletions optimism/client_bedrock.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ type TxExtraInfo struct {

// parseBedrockBlock returns a [EthTypes.Header] and [rpcBedrockBlock] for a given block or a respective error.
func (c *Client) parseBedrockBlock(raw *json.RawMessage) (
*EthTypes.Header,
*rpcHeader,
*rpcBedrockBlock,
error,
) {
// Decode bedrock header and transactions
var head EthTypes.Header
var head rpcHeader
var body rpcBedrockBlock
if err := json.Unmarshal(*raw, &head); err != nil {
return nil, nil, err
Expand Down
38 changes: 21 additions & 17 deletions optimism/client_bedrock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
RosettaTypes "github.com/coinbase/rosetta-sdk-go/types"
"github.com/ethereum-optimism/optimism/l2geth/params"
"github.com/ethereum-optimism/optimism/l2geth/rpc"
"github.com/ethereum/go-ethereum/common"
EthCommon "github.com/ethereum/go-ethereum/common"
EthHexutil "github.com/ethereum/go-ethereum/common/hexutil"
EthTypes "github.com/ethereum/go-ethereum/core/types"
Expand Down Expand Up @@ -131,23 +132,26 @@ func (testSuite *ClientBedrockTestSuite) TestParseBedrockBlock() {
testSuite.NoError(json.Unmarshal(file, &correctHeader))
// var correctBlock *rpcBedrockBlock
// testSuite.NoError(json.Unmarshal(file, &correctBlock))
expectedHeader := &EthTypes.Header{
ParentHash: EthCommon.HexToHash("0x70a4f8a536e03c2bb46ceafeafabe4070c3ecf56039c70bc0b4a5584684f664a"),
UncleHash: EthCommon.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"),
Coinbase: EthCommon.HexToAddress("0x4200000000000000000000000000000000000011"),
Root: EthCommon.HexToHash("0x64fc9af5be01af062cfd137cf1f2cfd78dd28dac15b499b227fb0e7183da4769"),
TxHash: EthCommon.HexToHash("0xada45aa72d8206747ec7a2dcbaed701b921389ca9b8275a516e6fac044f23357"),
ReceiptHash: EthCommon.HexToHash("0x7be5f73e807a2564853738e784008e499fd8498ce803d8c0b3a814c996840105"),
Bloom: EthTypes.BytesToBloom(EthCommon.FromHex("0x000000000000000000000003001000000001100000002000000002000000001002108040000000000000020000000000000000000204000400000000002000080040210000000000000080084000000000000040000100000008000000000000100020000000002000000000200009000000000000000000000000100000002000204000080000000000000008000008000100000000a2000800020000000000020000000000000000000000000000000400000000000000408000000000000004000002000000000000000000024800000000000000004010010001000000000010200000005000008000040000000000000000000000000000000800800000")),
Difficulty: correctHeader.Difficulty,
Number: convertBigInt("0x4c5836"),
GasLimit: convertBigInt("0x17d7840").Uint64(),
GasUsed: convertBigInt("0x4a853").Uint64(),
Time: convertBigInt("0x63dd1ad0").Uint64(),
Extra: []byte{},
MixDigest: EthCommon.HexToHash("0x11bca9946ac51ed6451e9182f41b3513d27839aad5e102aead7b1f7f5f55bbdf"),
Nonce: EthTypes.BlockNonce{},
BaseFee: big.NewInt(49),
expectedHeader := &rpcHeader{
Header: EthTypes.Header{
ParentHash: EthCommon.HexToHash("0x70a4f8a536e03c2bb46ceafeafabe4070c3ecf56039c70bc0b4a5584684f664a"),
UncleHash: EthCommon.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"),
Coinbase: EthCommon.HexToAddress("0x4200000000000000000000000000000000000011"),
Root: EthCommon.HexToHash("0x64fc9af5be01af062cfd137cf1f2cfd78dd28dac15b499b227fb0e7183da4769"),
TxHash: EthCommon.HexToHash("0xada45aa72d8206747ec7a2dcbaed701b921389ca9b8275a516e6fac044f23357"),
ReceiptHash: EthCommon.HexToHash("0x7be5f73e807a2564853738e784008e499fd8498ce803d8c0b3a814c996840105"),
Bloom: EthTypes.BytesToBloom(EthCommon.FromHex("0x000000000000000000000003001000000001100000002000000002000000001002108040000000000000020000000000000000000204000400000000002000080040210000000000000080084000000000000040000100000008000000000000100020000000002000000000200009000000000000000000000000100000002000204000080000000000000008000008000100000000a2000800020000000000020000000000000000000000000000000400000000000000408000000000000004000002000000000000000000024800000000000000004010010001000000000010200000005000008000040000000000000000000000000000000800800000")),
Difficulty: correctHeader.Difficulty,
Number: convertBigInt("0x4c5836"),
GasLimit: convertBigInt("0x17d7840").Uint64(),
GasUsed: convertBigInt("0x4a853").Uint64(),
Time: convertBigInt("0x63dd1ad0").Uint64(),
Extra: []byte{},
MixDigest: EthCommon.HexToHash("0x11bca9946ac51ed6451e9182f41b3513d27839aad5e102aead7b1f7f5f55bbdf"),
Nonce: EthTypes.BlockNonce{},
BaseFee: big.NewInt(49),
},
Hash: common.HexToHash("0x4503cbd671b3ca292e9f54998b2d566b705a32a178fc467f311c79b43e8e1774"),
}
expectedBlockHash := EthCommon.HexToHash("0x4503cbd671b3ca292e9f54998b2d566b705a32a178fc467f311c79b43e8e1774")

Expand Down
6 changes: 3 additions & 3 deletions optimism/client_blocks_bedrock_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
"math/big"

RosettaTypes "github.com/coinbase/rosetta-sdk-go/types"
"github.com/ethereum-optimism/optimism/l2geth/common/hexutil"
EthCommon "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"
)
Expand Down Expand Up @@ -131,7 +131,7 @@ func (ec *Client) getParsedBedrockBlock(
return &RosettaTypes.Block{
BlockIdentifier: &RosettaTypes.BlockIdentifier{
Index: head.Number.Int64(),
Hash: head.Hash().String(),
Hash: head.Hash.String(),
},
ParentBlockIdentifier: &RosettaTypes.BlockIdentifier{
Hash: head.ParentHash.Hex(),
Expand All @@ -146,7 +146,7 @@ func (ec *Client) getParsedBedrockBlock(
// populateBedrockTransaction populates a Rosetta transaction from a bedrock transaction.
func (ec *Client) populateBedrockTransaction(
ctx context.Context,
head *EthTypes.Header,
head *rpcHeader,
tx *bedrockTransaction,
) (*RosettaTypes.Transaction, error) {
ops, err := ec.ParseOps(tx)
Expand Down
146 changes: 146 additions & 0 deletions optimism/client_ecotone_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// Copyright 2023 Coinbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package optimism

import (
"context"
"encoding/json"
"math/big"
"os"
"testing"

RosettaTypes "github.com/coinbase/rosetta-sdk-go/types"
"github.com/ethereum-optimism/optimism/l2geth/params"
"github.com/ethereum-optimism/optimism/l2geth/rpc"
EthCommon "github.com/ethereum/go-ethereum/common"
mocks "github.com/inphi/optimism-rosetta/mocks/optimism"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
"golang.org/x/sync/semaphore"
)

type ClientEcotoneTestSuite struct {
suite.Suite

mockJSONRPC *mocks.JSONRPC
mockGraphQL *mocks.GraphQL
mockCurrencyFetcher *mocks.CurrencyFetcher
}

func (t *ClientEcotoneTestSuite) MockJSONRPC() *mocks.JSONRPC {
return t.mockJSONRPC
}

func TestClientEcotone(t *testing.T) {
suite.Run(t, new(ClientEcotoneTestSuite))
}

func (testSuite *ClientEcotoneTestSuite) SetupTest() {
testSuite.mockJSONRPC = &mocks.JSONRPC{}
testSuite.mockGraphQL = &mocks.GraphQL{}
testSuite.mockCurrencyFetcher = &mocks.CurrencyFetcher{}
}

func (testSuite *ClientEcotoneTestSuite) TestEcotoneBlock() {
c := &Client{
c: testSuite.mockJSONRPC,
g: testSuite.mockGraphQL,
currencyFetcher: testSuite.mockCurrencyFetcher,
tc: testBedrockTraceConfig,
p: params.TestnetChainConfig,
traceSemaphore: semaphore.NewWeighted(100),
filterTokens: false,
bedrockBlock: big.NewInt(0),
}

ctx := context.Background()
testSuite.mockJSONRPC.On(
"CallContext",
ctx,
mock.Anything,
"eth_getBlockByNumber",
"latest",
true,
).Return(
nil,
).Run(
func(args mock.Arguments) {
r := args.Get(1).(*json.RawMessage)
file, err := os.ReadFile("testdata/sepolia_ecotone_block_4089330.json")
testSuite.NoError(err)
*r = json.RawMessage(file)
},
).Once()
testSuite.mockJSONRPC.On(
"CallContext",
ctx,
mock.Anything,
"eth_getBlockByNumber",
[]interface{}{"latest", true},
).Return(
nil,
).Run(
func(args mock.Arguments) {
r := args.Get(1).(*json.RawMessage)
file, err := os.ReadFile("testdata/sepolia_ecotone_block_4089330.json")
testSuite.NoError(err)
*r = json.RawMessage(file)
},
).Once()

tx1 := EthCommon.HexToHash("0xd62fb327dc8df4e8f6a1ad70c9ff03099d2f85c75b9d943d5d6885e62be31069")

// Execute the transaction trace
mockTraceTransaction(ctx, testSuite, "testdata/sepolia_ecotone_tx_trace_5003318_1.json")
mockGetEcotoneTransactionReceipt(ctx, testSuite, []EthCommon.Hash{tx1}, []string{"testdata/sepolia_ecotone_tx_receipt_4089330_1.json"})

correctRaw, err := os.ReadFile("testdata/sepolia_ecotone_block_response_4089330.json")
testSuite.NoError(err)
var correct *RosettaTypes.BlockResponse
testSuite.NoError(json.Unmarshal(correctRaw, &correct))

// Fetch the latest block and validate
resp, err := c.Block(ctx, nil)
testSuite.NoError(err)
testSuite.Equal(correct.Block, resp)
}

func mockGetEcotoneTransactionReceipt(ctx context.Context, testSuite *ClientEcotoneTestSuite, txhashes []EthCommon.Hash, txFileData []string) {
testSuite.Equal(len(txhashes), len(txFileData))
numReceipts := len(txhashes)
testSuite.mockJSONRPC.On(
"BatchCallContext",
ctx,
mock.MatchedBy(func(rpcs []rpc.BatchElem) bool {
return len(rpcs) == numReceipts && rpcs[0].Method == "eth_getTransactionReceipt"
}),
).Return(
nil,
).Run(
func(args mock.Arguments) {
r := args.Get(1).([]rpc.BatchElem)
testSuite.Len(r, numReceipts)
for i := range txhashes {
testSuite.Equal(
txhashes[i].Hex(),
r[i].Args[0],
)
file, err := os.ReadFile(txFileData[i])
testSuite.NoError(err)
*(r[i].Result.(*json.RawMessage)) = json.RawMessage(file)
}
},
).Once()
}
48 changes: 48 additions & 0 deletions optimism/testdata/sepolia_ecotone_block_4089330.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"hash": "0xf1e1eb6735860e60bfbb19fb9c3a3ade2a1e2fc51bc5549e47939aac30bc8092",
"parentHash": "0x2ea5dc85c900443e6ee9615876a413ef3f7f800792886e646f03cae258e30dc4",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"miner": "0x4200000000000000000000000000000000000011",
"stateRoot": "0x07697115aeffa8bcf76bc90edf9c8c6998b5bb87d8049f631c90db75a8dbe6d9",
"transactionsRoot": "0xfc7fc33824e66da578de2aafbafc1d175301b8c36b56ff8ad0817b4d3a77f039",
"receiptsRoot": "0xad690e8a5ce0df6f1d9554901d531a5945ed233d6408420decaff8950fefdb0d",
"number": "0x3e65f2",
"gasUsed": "0xb705",
"gasLimit": "0x1c9c380",
"extraData": "0x",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x6553a790",
"difficulty": "0x0",
"totalDifficulty": "0x0",
"sealFields": [],
"uncles": [],
"transactions": [
{
"hash": "0xd62fb327dc8df4e8f6a1ad70c9ff03099d2f85c75b9d943d5d6885e62be31069",
"nonce": "0x3e65f1",
"blockHash": "0xf1e1eb6735860e60bfbb19fb9c3a3ade2a1e2fc51bc5549e47939aac30bc8092",
"blockNumber": "0x3e65f2",
"transactionIndex": "0x0",
"from": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001",
"to": "0x4200000000000000000000000000000000000015",
"value": "0x0",
"gasPrice": "0x0",
"gas": "0xf4240",
"input": "0x015d8eb90000000000000000000000000000000000000000000000000000000000479ddd000000000000000000000000000000000000000000000000000000006553a73c000000000000000000000000000000000000000000000000000000000000000e68ac0d50607ac5d009c560fafb10d165a445811924a4a1cdaa93cd85ab5fff0300000000000000000000000000000000000000000000000000000000000000030000000000000000000000008f23bb38f531600e5d8fddaaec41f13fab46e98c00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000a6fe0",
"v": "0x0",
"r": "0x0",
"s": "0x0",
"sourceHash": "0xb11d5cce1ac3d8ec545e49a73cc9111cf05c00f07cddffeedb777a0825bb26c6",
"mint": "0x0",
"isSystemTx": false,
"type": "0x7e",
"depositReceiptVersion": "0x1"
}
],
"size": "0x387",
"mixHash": "0x56c69fea1a23e350c8014171a2819ff4cc84a27272bae1a866d58b4ced467024",
"nonce": "0x0000000000000000",
"baseFeePerGas": "0x32",
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"withdrawals": []
}
68 changes: 68 additions & 0 deletions optimism/testdata/sepolia_ecotone_block_response_4089330.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"block": {
"block_identifier": {
"index": 4089330,
"hash": "0xf1e1eb6735860e60bfbb19fb9c3a3ade2a1e2fc51bc5549e47939aac30bc8092"
},
"parent_block_identifier": {
"index": 4089329,
"hash": "0x2ea5dc85c900443e6ee9615876a413ef3f7f800792886e646f03cae258e30dc4"
},
"timestamp": 1699981200000,
"transactions": [
{
"transaction_identifier": {
"hash": "0xd62fb327dc8df4e8f6a1ad70c9ff03099d2f85c75b9d943d5d6885e62be31069"
},
"operations": [
{
"operation_identifier": {
"index": 0
},
"type": "CALL",
"status": "SUCCESS",
"account": {
"address": "0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001"
},
"amount": {
"value": "0",
"currency": {
"symbol": "ETH",
"decimals": 18
}
}
}
],
"metadata": {
"gas_limit": "0xf4240",
"gas_price": "0x0",
"receipt": {
"GasPrice": 0,
"GasUsed": 46853,
"Logs": [],
"RawMessage": {
"blockHash": "0xf1e1eb6735860e60bfbb19fb9c3a3ade2a1e2fc51bc5549e47939aac30bc8092",
"blockNumber": "0x3e65f2",
"contractAddress": null,
"cumulativeGasUsed": "0xb705",
"depositNonce": "0x3e65f1",
"depositReceiptVersion": "0x1",
"effectiveGasPrice": "0x0",
"from": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001",
"gasUsed": "0xb705",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": "0x1",
"to": "0x4200000000000000000000000000000000000015",
"transactionHash": "0xd62fb327dc8df4e8f6a1ad70c9ff03099d2f85c75b9d943d5d6885e62be31069",
"transactionIndex": "0x0",
"type": "0x7e"
},
"TransactionFee": 0,
"type": 126
}
}
}
]
}
}
18 changes: 18 additions & 0 deletions optimism/testdata/sepolia_ecotone_tx_receipt_4089330_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"transactionHash": "0xd62fb327dc8df4e8f6a1ad70c9ff03099d2f85c75b9d943d5d6885e62be31069",
"transactionIndex": "0x0",
"blockHash": "0xf1e1eb6735860e60bfbb19fb9c3a3ade2a1e2fc51bc5549e47939aac30bc8092",
"blockNumber": "0x3e65f2",
"from": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001",
"to": "0x4200000000000000000000000000000000000015",
"cumulativeGasUsed": "0xb705",
"gasUsed": "0xb705",
"contractAddress": null,
"logs": [],
"status": "0x1",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"type": "0x7e",
"effectiveGasPrice": "0x0",
"depositNonce": "0x3e65f1",
"depositReceiptVersion": "0x1"
}
20 changes: 20 additions & 0 deletions optimism/testdata/sepolia_ecotone_tx_trace_5003318_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"from": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001",
"gas": "0xf4240",
"gasUsed": "0xb705",
"to": "0x4200000000000000000000000000000000000015",
"input": "0x015d8eb90000000000000000000000000000000000000000000000000000000000479ddd000000000000000000000000000000000000000000000000000000006553a73c000000000000000000000000000000000000000000000000000000000000000e68ac0d50607ac5d009c560fafb10d165a445811924a4a1cdaa93cd85ab5fff0300000000000000000000000000000000000000000000000000000000000000030000000000000000000000008f23bb38f531600e5d8fddaaec41f13fab46e98c00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000a6fe0",
"calls": [
{
"from": "0x4200000000000000000000000000000000000015",
"gas": "0xe9a30",
"gasUsed": "0x4a28",
"to": "0xc0d3c0d3c0d3c0d3c0d3c0d3c0d3c0d3c0d30015",
"input": "0x015d8eb90000000000000000000000000000000000000000000000000000000000479ddd000000000000000000000000000000000000000000000000000000006553a73c000000000000000000000000000000000000000000000000000000000000000e68ac0d50607ac5d009c560fafb10d165a445811924a4a1cdaa93cd85ab5fff0300000000000000000000000000000000000000000000000000000000000000030000000000000000000000008f23bb38f531600e5d8fddaaec41f13fab46e98c00000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000a6fe0",
"value": "0x0",
"type": "DELEGATECALL"
}
],
"value": "0x0",
"type": "CALL"
}
Loading

0 comments on commit 599a398

Please sign in to comment.