Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/3518 use generic eth client for l2 #3519

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
"github.com/0xPolygonHermez/zkevm-node/synchronizer"
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
"github.com/ethereum/go-ethereum/ethclient"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


"github.com/jackc/pgx/v4/pgxpool"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -280,6 +281,15 @@ func newEtherman(c config.Config) (*etherman.Client, error) {
return etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config)
}

func newL2EthClient(url string) (*ethclient.Client, error) {
ethClient, err := ethclient.Dial(url)
if err != nil {
log.Errorf("error connecting L1 to %s: %+v", url, err)
return nil, err
}
return ethClient, nil
}

func runSynchronizer(cfg config.Config, etherman *etherman.Client, ethTxManagerStorage *ethtxmanager.PostgresStorage, st *state.State, pool *pool.Pool, eventLog *event.EventLog) {
var trustedSequencerURL string
var err error
Expand All @@ -295,6 +305,17 @@ func runSynchronizer(cfg config.Config, etherman *etherman.Client, ethTxManagerS
}
log.Info("trustedSequencerURL ", trustedSequencerURL)
}
var ethClientForL2 *ethclient.Client
if trustedSequencerURL != "" {
log.Infof("Creating L2 ethereum client %s", trustedSequencerURL)
ethClientForL2, err = newL2EthClient(trustedSequencerURL)
if err != nil {
log.Fatalf("Can't create L2 ethereum client. Err:%w", err)
}
} else {
ethClientForL2 = nil
log.Infof("skipping creating L2 ethereum client because URL is empty")
}
zkEVMClient := client.NewClient(trustedSequencerURL)
etherManForL1 := []syncinterfaces.EthermanFullInterface{}
// If synchronizer are using sequential mode, we only need one etherman client
Expand All @@ -310,7 +331,7 @@ func runSynchronizer(cfg config.Config, etherman *etherman.Client, ethTxManagerS
etm := ethtxmanager.New(cfg.EthTxManager, etherman, ethTxManagerStorage, st)
sy, err := synchronizer.NewSynchronizer(
cfg.IsTrustedSequencer, etherman, etherManForL1, st, pool, etm,
zkEVMClient, eventLog, cfg.NetworkConfig.Genesis, cfg.Synchronizer, cfg.Log.Environment == "development",
zkEVMClient, ethClientForL2, eventLog, cfg.NetworkConfig.Genesis, cfg.Synchronizer, cfg.Log.Environment == "development",
)
if err != nil {
log.Fatal(err)
Expand Down
13 changes: 8 additions & 5 deletions synchronizer/actions/check_l2block.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"fmt"
"math/big"

"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/jackc/pgx/v4"
)

Expand Down Expand Up @@ -129,11 +129,14 @@ func (p *CheckL2BlockHash) iterationCheckL2Block(ctx context.Context, l2BlockNum
}

func compareL2Blocks(prefixLogs string, localL2Block *state.L2Block, trustedL2Block *types.Block) error {
if localL2Block == nil || trustedL2Block == nil || trustedL2Block.Hash == nil {
return fmt.Errorf("%s localL2Block or trustedL2Block or trustedHash are nil", prefixLogs)
if localL2Block == nil || trustedL2Block == nil {
return fmt.Errorf("%s localL2Block or trustedL2Block are nil", prefixLogs)
}
if localL2Block.Hash() != trustedL2Block.Hash() {
return fmt.Errorf("%s localL2Block.Hash %s and trustedL2Block.Hash %s are different", prefixLogs, localL2Block.Hash().String(), trustedL2Block.Hash().String())
}
if localL2Block.Hash() != *trustedL2Block.Hash {
return fmt.Errorf("%s localL2Block.Hash %s and trustedL2Block.Hash %s are different", prefixLogs, localL2Block.Hash().String(), (*trustedL2Block.Hash).String())
if localL2Block.ParentHash() != trustedL2Block.ParentHash() {
return fmt.Errorf("%s localL2Block.ParentHash %s and trustedL2Block.ParentHash %s are different", prefixLogs, localL2Block.ParentHash().String(), trustedL2Block.ParentHash().String())
}
return nil
}
37 changes: 21 additions & 16 deletions synchronizer/actions/check_l2block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"math/big"
"testing"

rpctypes "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • [ ]

"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/0xPolygonHermez/zkevm-node/synchronizer/actions"
mock_syncinterfaces "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces/mocks"
Expand All @@ -19,7 +18,7 @@ import (
type CheckL2BlocksTestData struct {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

sut *actions.CheckL2BlockHash
mockState *mock_syncinterfaces.StateFullInterface
zKEVMClient *mock_syncinterfaces.ZKEVMClientInterface
zKEVMClient *mock_syncinterfaces.ZKEVMClientEthereumCompatibleInterface
}

func TestCheckL2BlockHash_GetMinimumL2BlockToCheck(t *testing.T) {
Expand Down Expand Up @@ -57,7 +56,7 @@ func TestCheckL2BlockHashNotEnoughBlocksToCheck(t *testing.T) {
func newCheckL2BlocksTestData(t *testing.T, initialL2Block, modulus uint64) CheckL2BlocksTestData {
res := CheckL2BlocksTestData{
mockState: mock_syncinterfaces.NewStateFullInterface(t),
zKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
zKEVMClient: mock_syncinterfaces.NewZKEVMClientEthereumCompatibleInterface(t),
}
res.sut = actions.NewCheckL2BlockHash(res.mockState, res.zKEVMClient, initialL2Block, modulus)
return res
Expand Down Expand Up @@ -97,18 +96,23 @@ func TestCheckL2BlockHashMatch(t *testing.T) {

data.mockState.EXPECT().GetLastL2BlockNumber(mock.Anything, mock.Anything).Return(lastL2Block, nil)
data.mockState.EXPECT().GetL2BlockByNumber(mock.Anything, lastL2Block, mock.Anything).Return(stateBlock, nil)
l2blockHash := stateBlock.Hash()
rpcL2Block := rpctypes.Block{
Hash: &l2blockHash,
Number: rpctypes.ArgUint64(lastL2Block),
}
//l2blockHash := stateBlock.Hash()
// rpcL2Block := rpctypes.Block{
// Hash: &l2blockHash,
// Number: rpctypes.ArgUint64(lastL2Block),
// }
// create a types.Block object

rpcL2Block := types.NewBlock(&types.Header{
Number: big.NewInt(int64(lastL2Block)),
}, nil, nil, nil, nil)

data.zKEVMClient.EXPECT().BlockByNumber(mock.Anything, lastL2BlockBigInt).Return(&rpcL2Block, nil)
data.zKEVMClient.EXPECT().BlockByNumber(mock.Anything, lastL2BlockBigInt).Return(rpcL2Block, nil)
err := data.sut.CheckL2Block(context.Background(), nil)
require.NoError(t, err)
}

func TestCheckL2BlockHashMissmatch(t *testing.T) {
func TestCheckL2BlockHashMismatch(t *testing.T) {
data := newCheckL2BlocksTestData(t, 1, 10)
lastL2Block := uint64(14)
lastL2BlockBigInt := big.NewInt(int64(lastL2Block))
Expand All @@ -119,13 +123,14 @@ func TestCheckL2BlockHashMissmatch(t *testing.T) {

data.mockState.EXPECT().GetLastL2BlockNumber(mock.Anything, mock.Anything).Return(lastL2Block, nil)
data.mockState.EXPECT().GetL2BlockByNumber(mock.Anything, lastL2Block, mock.Anything).Return(stateBlock, nil)
l2blockHash := common.HexToHash("0x1234")
rpcL2Block := rpctypes.Block{
Hash: &l2blockHash,
Number: rpctypes.ArgUint64(lastL2Block),
}
//l2blockHash := common.HexToHash("0x1234")

rpcL2Block := types.NewBlock(&types.Header{
Number: big.NewInt(int64(lastL2Block)),
ParentHash: common.HexToHash("0x1234"),
}, nil, nil, nil, nil)

data.zKEVMClient.EXPECT().BlockByNumber(mock.Anything, lastL2BlockBigInt).Return(&rpcL2Block, nil)
data.zKEVMClient.EXPECT().BlockByNumber(mock.Anything, lastL2BlockBigInt).Return(rpcL2Block, nil)
err := data.sut.CheckL2Block(context.Background(), nil)
require.Error(t, err)
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package syncinterfaces

import (
"context"
"math/big"

"github.com/ethereum/go-ethereum/core/types"
)

// ZKEVMClientEthereumCompatibleInterface contains the methods required to interact with zkEVM-RPC as a ethereum-API compatible
//
// Reason behind: the zkEVMClient have some extensions to ethereum-API that are not compatible with all nodes. So if you need to maximize
// the compatibility the idea is to use a regular ethereum-API compatible client
type ZKEVMClientEthereumCompatibleInterface interface {
ZKEVMClientEthereumCompatibleL2BlockGetter
}

// ZKEVMClientEthereumCompatibleL2BlockGetter contains the methods required to interact with zkEVM-RPC as a ethereum-API compatible for obtain Block information
type ZKEVMClientEthereumCompatibleL2BlockGetter interface {
BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
}
61 changes: 32 additions & 29 deletions synchronizer/synchronizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,18 @@ type ClientSynchronizer struct {
etherMan syncinterfaces.EthermanFullInterface
latestFlushID uint64
// If true the lastFlushID is stored in DB and we don't need to check again
latestFlushIDIsFulfilled bool
etherManForL1 []syncinterfaces.EthermanFullInterface
state syncinterfaces.StateFullInterface
pool syncinterfaces.PoolInterface
ethTxManager syncinterfaces.EthTxManager
zkEVMClient syncinterfaces.ZKEVMClientInterface
eventLog syncinterfaces.EventLogInterface
ctx context.Context
cancelCtx context.CancelFunc
genesis state.Genesis
cfg Config
latestFlushIDIsFulfilled bool
etherManForL1 []syncinterfaces.EthermanFullInterface
state syncinterfaces.StateFullInterface
pool syncinterfaces.PoolInterface
ethTxManager syncinterfaces.EthTxManager
zkEVMClient syncinterfaces.ZKEVMClientInterface
zkEVMClientEthereumCompatible syncinterfaces.ZKEVMClientEthereumCompatibleInterface
eventLog syncinterfaces.EventLogInterface
ctx context.Context
cancelCtx context.CancelFunc
genesis state.Genesis
cfg Config
// Id of the 'process' of the executor. Each time that it starts this value changes
// This value is obtained from the call state.GetStoredFlushID
// It starts as an empty string and it is filled in the first call
Expand All @@ -85,30 +86,32 @@ func NewSynchronizer(
pool syncinterfaces.PoolInterface,
ethTxManager syncinterfaces.EthTxManager,
zkEVMClient syncinterfaces.ZKEVMClientInterface,
zkEVMClientEthereumCompatible syncinterfaces.ZKEVMClientEthereumCompatibleInterface,
eventLog syncinterfaces.EventLogInterface,
genesis state.Genesis,
cfg Config,
runInDevelopmentMode bool) (Synchronizer, error) {
ctx, cancel := context.WithCancel(context.Background())
metrics.Register()
res := &ClientSynchronizer{
isTrustedSequencer: isTrustedSequencer,
state: st,
etherMan: ethMan,
etherManForL1: etherManForL1,
pool: pool,
ctx: ctx,
cancelCtx: cancel,
ethTxManager: ethTxManager,
zkEVMClient: zkEVMClient,
eventLog: eventLog,
genesis: genesis,
cfg: cfg,
proverID: "",
previousExecutorFlushID: 0,
l1SyncOrchestration: nil,
l1EventProcessors: nil,
halter: syncCommon.NewCriticalErrorHalt(eventLog, 5*time.Second), //nolint:gomnd
isTrustedSequencer: isTrustedSequencer,
state: st,
etherMan: ethMan,
etherManForL1: etherManForL1,
pool: pool,
ctx: ctx,
cancelCtx: cancel,
ethTxManager: ethTxManager,
zkEVMClient: zkEVMClient,
zkEVMClientEthereumCompatible: zkEVMClientEthereumCompatible,
eventLog: eventLog,
genesis: genesis,
cfg: cfg,
proverID: "",
previousExecutorFlushID: 0,
l1SyncOrchestration: nil,
l1EventProcessors: nil,
halter: syncCommon.NewCriticalErrorHalt(eventLog, 5*time.Second), //nolint:gomnd
}

if !isTrustedSequencer {
Expand Down Expand Up @@ -143,7 +146,7 @@ func NewSynchronizer(
log.Errorf("error getting last L2Block number from state. Error: %v", err)
return nil, err
}
l1checkerL2Blocks = actions.NewCheckL2BlockHash(res.state, res.zkEVMClient, initialL2Block, cfg.L1SyncCheckL2BlockNumberhModulus)
l1checkerL2Blocks = actions.NewCheckL2BlockHash(res.state, res.zkEVMClientEthereumCompatible, initialL2Block, cfg.L1SyncCheckL2BlockNumberhModulus)
} else {
log.Infof("Trusted Node can't check L2Block hash, ignoring parameter")
}
Expand Down
Loading
Loading