Skip to content

Commit

Permalink
reviews l2 block exit roots and exposes endpoint to get them by ger (0…
Browse files Browse the repository at this point in the history
  • Loading branch information
tclemos authored Dec 20, 2023
1 parent 57d5b47 commit 14aefd9
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 22 deletions.
1 change: 1 addition & 0 deletions docs/json-rpc-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,4 @@ If the endpoint is not in the list below, it means this specific endpoint is not
- `zkevm_isBlockVirtualized`
- `zkevm_verifiedBatchNumber`
- `zkevm_virtualBatchNumber`
- `zkevm_getExitRootsByGER`
21 changes: 21 additions & 0 deletions jsonrpc/client/zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/0xPolygonHermez/zkevm-node/hex"
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
"github.com/ethereum/go-ethereum/common"
)

// BatchNumber returns the latest batch number
Expand Down Expand Up @@ -56,3 +57,23 @@ func (c *Client) BatchByNumber(ctx context.Context, number *big.Int) (*types.Bat

return result, nil
}

// ExitRootsByGER returns the exit roots accordingly to the provided Global Exit Root
func (c *Client) ExitRootsByGER(ctx context.Context, globalExitRoot common.Hash) (*types.ExitRoots, error) {
response, err := JSONRPCCall(c.url, "zkevm_getExitRootsByGER", globalExitRoot.String())
if err != nil {
return nil, err
}

if response.Error != nil {
return nil, response.Error.RPCError()
}

var result *types.ExitRoots
err = json.Unmarshal(response.Result, &result)
if err != nil {
return nil, err
}

return result, nil
}
5 changes: 1 addition & 4 deletions jsonrpc/endpoints_eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1182,8 +1182,7 @@ func TestGetL2BlockByNumber(t *testing.T) {

l2Header := state.NewL2Header(header)
l2Header.GlobalExitRoot = common.HexToHash("0x16")
l2Header.LocalExitRoot = common.HexToHash("0x17")
l2Header.BlockInfoRoot = common.HexToHash("0x18")
l2Header.BlockInfoRoot = common.HexToHash("0x17")
l2Block := state.NewL2Block(l2Header, signedTransactions, uncles, receipts, &trie.StackTrie{})

for _, receipt := range receipts {
Expand Down Expand Up @@ -1258,7 +1257,6 @@ func TestGetL2BlockByNumber(t *testing.T) {
Nonce: rpcBlockNonce,
Hash: state.HashPtr(l2Block.Hash()),
GlobalExitRoot: l2Block.GlobalExitRoot(),
LocalExitRoot: l2Block.LocalExitRoot(),
BlockInfoRoot: l2Block.BlockInfoRoot(),
Uncles: rpcUncles,
Transactions: rpcTransactions,
Expand Down Expand Up @@ -1496,7 +1494,6 @@ func TestGetL2BlockByNumber(t *testing.T) {
assert.Nil(t, result.Hash)
}
assert.Equal(t, tc.ExpectedResult.GlobalExitRoot, result.GlobalExitRoot)
assert.Equal(t, tc.ExpectedResult.LocalExitRoot, result.LocalExitRoot)
assert.Equal(t, tc.ExpectedResult.BlockInfoRoot, result.BlockInfoRoot)

assert.Equal(t, len(tc.ExpectedResult.Transactions), len(result.Transactions))
Expand Down
18 changes: 18 additions & 0 deletions jsonrpc/endpoints_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/jackc/pgx/v4"
)
Expand Down Expand Up @@ -300,3 +301,20 @@ func (z *ZKEVMEndpoints) GetNativeBlockHashesInRange(filter NativeBlockHashBlock
return nativeBlockHashes, nil
})
}

// GetExitRootsByGER returns the exit roots accordingly to the provided Global Exit Root
func (z *ZKEVMEndpoints) GetExitRootsByGER(globalExitRoot common.Hash) (interface{}, types.Error) {
return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
exitRoots, err := z.state.GetExitRootByGlobalExitRoot(ctx, globalExitRoot, dbTx)
if errors.Is(err, state.ErrNotFound) {
return nil, nil
} else if err != nil {
return RPCErrorResponse(types.DefaultErrorCode, "failed to get exit roots by global exit root from state", err, true)
}

return types.ExitRoots{
MainnetExitRoot: exitRoots.MainnetExitRoot,
RollupExitRoot: exitRoots.RollupExitRoot,
}, nil
})
}
42 changes: 42 additions & 0 deletions jsonrpc/endpoints_zkevm.openrpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,35 @@
"$ref": "#/components/schemas/NativeBlockHashes"
}
}
},
{
"name": "zkevm_getExitRootsByGER",
"summary": "Gets the exit roots accordingly to the provided Global Exit Root",
"params": [
{
"$ref": "#/components/schemas/Keccak"
}
],
"result": {
"$ref": "#/components/schemas/ExitRoots"
},
"examples": [
{
"params": [
{
"name": "global exit root",
"value": "0x0000000000000000000000000000000000000000000000000000000000000001"
}
],
"result": {
"name": "Exit Roots",
"value": {
"mainnetExitRoot": "0x0000000000000000000000000000000000000000000000000000000000000002",
"rollupExitRoot": "0x0000000000000000000000000000000000000000000000000000000000000003"
}
}
}
]
}
],
"components": {
Expand Down Expand Up @@ -1153,6 +1182,19 @@
"$ref": "#/components/schemas/BlockNumber"
}
}
},
"ExitRoots": {
"title": "ExitRoots",
"type": "object",
"readOnly": true,
"properties": {
"mainnetExitRoot": {
"$ref": "#/components/schemas/Keccak"
},
"rollupExitRoot": {
"$ref": "#/components/schemas/Keccak"
}
}
}
}
}
Expand Down
117 changes: 113 additions & 4 deletions jsonrpc/endpoints_zkevm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"math/big"
"strings"
"testing"
"time"

"github.com/0xPolygonHermez/zkevm-node/hex"
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/client"
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/0xPolygonHermez/zkevm-node/test/operations"
Expand Down Expand Up @@ -1386,8 +1388,7 @@ func TestGetL2FullBlockByNumber(t *testing.T) {

l2Header := state.NewL2Header(header)
l2Header.GlobalExitRoot = common.HexToHash("0x16")
l2Header.LocalExitRoot = common.HexToHash("0x17")
l2Header.BlockInfoRoot = common.HexToHash("0x18")
l2Header.BlockInfoRoot = common.HexToHash("0x17")
l2Block := state.NewL2Block(l2Header, signedTransactions, uncles, receipts, &trie.StackTrie{})

for _, receipt := range receipts {
Expand Down Expand Up @@ -1462,7 +1463,6 @@ func TestGetL2FullBlockByNumber(t *testing.T) {
Nonce: rpcBlockNonce,
Hash: state.HashPtr(l2Block.Hash()),
GlobalExitRoot: l2Block.GlobalExitRoot(),
LocalExitRoot: l2Block.LocalExitRoot(),
BlockInfoRoot: l2Block.BlockInfoRoot(),
Uncles: rpcUncles,
Transactions: rpcTransactions,
Expand Down Expand Up @@ -1708,7 +1708,6 @@ func TestGetL2FullBlockByNumber(t *testing.T) {
assert.Nil(t, result.Hash)
}
assert.Equal(t, tc.ExpectedResult.GlobalExitRoot, result.GlobalExitRoot)
assert.Equal(t, tc.ExpectedResult.LocalExitRoot, result.LocalExitRoot)
assert.Equal(t, tc.ExpectedResult.BlockInfoRoot, result.BlockInfoRoot)

assert.Equal(t, len(tc.ExpectedResult.Transactions), len(result.Transactions))
Expand Down Expand Up @@ -1876,6 +1875,116 @@ func TestGetNativeBlockHashesInRange(t *testing.T) {
}
}

func TestGetExitRootsByGER(t *testing.T) {
type testCase struct {
Name string
GER common.Hash
ExpectedResult *types.ExitRoots
ExpectedError types.Error
SetupMocks func(*mockedServer, *mocksWrapper, *testCase)
}

testCases := []testCase{
{
Name: "GER not found",
GER: common.HexToHash("0x123"),
ExpectedResult: nil,
ExpectedError: nil,
SetupMocks: func(s *mockedServer, m *mocksWrapper, tc *testCase) {
m.DbTx.
On("Commit", context.Background()).
Return(nil).
Once()

m.State.
On("BeginStateTransaction", context.Background()).
Return(m.DbTx, nil).
Once()

m.State.
On("GetExitRootByGlobalExitRoot", context.Background(), tc.GER, m.DbTx).
Return(nil, state.ErrNotFound)
},
},
{
Name: "get exit roots fails to load exit roots from state",
GER: common.HexToHash("0x123"),
ExpectedResult: nil,
ExpectedError: nil,
SetupMocks: func(s *mockedServer, m *mocksWrapper, tc *testCase) {
m.DbTx.
On("Commit", context.Background()).
Return(nil).
Once()

m.State.
On("BeginStateTransaction", context.Background()).
Return(m.DbTx, nil).
Once()

m.State.
On("GetExitRootByGlobalExitRoot", context.Background(), tc.GER, m.DbTx).
Return(nil, fmt.Errorf("failed to load exit roots from state"))
},
},
{
Name: "get exit roots successfully",
GER: common.HexToHash("0x345"),
ExpectedResult: &types.ExitRoots{
MainnetExitRoot: common.HexToHash("0x1"),
RollupExitRoot: common.HexToHash("0x2"),
},
ExpectedError: nil,
SetupMocks: func(s *mockedServer, m *mocksWrapper, tc *testCase) {
m.DbTx.
On("Commit", context.Background()).
Return(nil).
Once()

m.State.
On("BeginStateTransaction", context.Background()).
Return(m.DbTx, nil).
Once()

er := &state.GlobalExitRoot{
MainnetExitRoot: tc.ExpectedResult.MainnetExitRoot,
RollupExitRoot: tc.ExpectedResult.RollupExitRoot,
}

m.State.
On("GetExitRootByGlobalExitRoot", context.Background(), tc.GER, m.DbTx).
Return(er, nil)
},
},
}

s, m, _ := newSequencerMockedServer(t)
defer s.Stop()

c := client.NewClient(s.ServerURL)

for _, testCase := range testCases {
t.Run(testCase.Name, func(t *testing.T) {
tc := testCase
testCase.SetupMocks(s, m, &tc)

exitRoots, err := c.ExitRootsByGER(context.Background(), tc.GER)
require.NoError(t, err)

if exitRoots != nil || tc.ExpectedResult != nil {
assert.Equal(t, tc.ExpectedResult.MainnetExitRoot.String(), exitRoots.MainnetExitRoot.String())
assert.Equal(t, tc.ExpectedResult.RollupExitRoot.String(), exitRoots.RollupExitRoot.String())
}

if err != nil || tc.ExpectedError != nil {
rpcErr := err.(types.RPCError)
assert.Equal(t, tc.ExpectedError.ErrorCode(), rpcErr.ErrorCode())
assert.Equal(t, tc.ExpectedError.Error(), rpcErr.Error())
}
})
}
}

func ptrUint64(n uint64) *uint64 {
return &n
}
Expand Down
8 changes: 6 additions & 2 deletions jsonrpc/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ type Block struct {
Transactions []TransactionOrHash `json:"transactions"`
Uncles []common.Hash `json:"uncles"`
GlobalExitRoot common.Hash `json:"globalExitRoot"`
LocalExitRoot common.Hash `json:"localExitRoot"`
BlockInfoRoot common.Hash `json:"blockInfoRoot"`
}

Expand Down Expand Up @@ -310,7 +309,6 @@ func NewBlock(hash *common.Hash, b *state.L2Block, receipts []types.Receipt, ful
Hash: hash,
Transactions: []TransactionOrHash{},
Uncles: []common.Hash{},
LocalExitRoot: h.LocalExitRoot,
GlobalExitRoot: h.GlobalExitRoot,
BlockInfoRoot: h.BlockInfoRoot,
}
Expand Down Expand Up @@ -685,3 +683,9 @@ func NewLog(l types.Log) Log {
Removed: l.Removed,
}
}

// ExitRoots structure
type ExitRoots struct {
MainnetExitRoot common.Hash `json:"mainnetExitRoot"`
RollupExitRoot common.Hash `json:"rollupExitRoot"`
}
11 changes: 0 additions & 11 deletions state/l2block.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ type gethBlock struct {
// L2Header represents a block header in the L2.
type L2Header struct {
*gethHeader
LocalExitRoot common.Hash `json:"localExitRoot"`
GlobalExitRoot common.Hash `json:"globalExitRoot"`
BlockInfoRoot common.Hash `json:"blockInfoRoot"`
}
Expand Down Expand Up @@ -56,7 +55,6 @@ func (h *L2Header) MarshalJSON() ([]byte, error) {
}
}

m["localExitRoot"] = h.LocalExitRoot.String()
m["globalExitRoot"] = h.GlobalExitRoot.String()
m["blockInfoRoot"] = h.BlockInfoRoot.String()

Expand Down Expand Up @@ -88,9 +86,6 @@ func (h *L2Header) UnmarshalJSON(input []byte) error {
}

h.gethHeader = &gethHeader{header}
if localExitRoot, found := m["localExitRoot"]; found {
h.LocalExitRoot = common.HexToHash(localExitRoot.(string))
}
if globalExitRoot, found := m["globalExitRoot"]; found {
h.GlobalExitRoot = common.HexToHash(globalExitRoot.(string))
}
Expand All @@ -113,11 +108,6 @@ type L2Block struct {
ReceivedFrom interface{}
}

// LocalExitRoot returns the header LocalExitRoot
func (b *L2Block) LocalExitRoot() common.Hash {
return b.Header().LocalExitRoot
}

// GlobalExitRoot returns the header GlobalExitRoot
func (b *L2Block) GlobalExitRoot() common.Hash {
return b.Header().GlobalExitRoot
Expand Down Expand Up @@ -212,7 +202,6 @@ func CopyHeader(h *L2Header) *L2Header {
}
cpy := *h
cpy.gethHeader = &gethHeader{types.CopyHeader(h.gethHeader.Header)}
cpy.LocalExitRoot = h.LocalExitRoot
cpy.GlobalExitRoot = h.GlobalExitRoot
cpy.BlockInfoRoot = h.BlockInfoRoot
return &cpy
Expand Down
1 change: 0 additions & 1 deletion state/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,6 @@ func (s *State) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *P

l2Header.GlobalExitRoot = l2Block.GlobalExitRoot
l2Header.BlockInfoRoot = l2Block.BlockInfoRoot
//TODO: l2header.LocalExitRoot??

transactions := []*types.Transaction{}
storeTxsEGPData := []StoreTxEGPData{}
Expand Down

0 comments on commit 14aefd9

Please sign in to comment.