Skip to content

Commit

Permalink
Merge pull request #6190 from ethereum-optimism/aj/get-synch-status
Browse files Browse the repository at this point in the history
op-node: Add `admin_sequencerActive` RPC method
  • Loading branch information
OptimismBot authored Jun 29, 2023
2 parents ff6d298 + bff6bab commit 0399485
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 4 deletions.
4 changes: 4 additions & 0 deletions op-e2e/actions/l2_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func (s *l2VerifierBackend) StopSequencer(ctx context.Context) (common.Hash, err
return common.Hash{}, errors.New("stopping the L2Verifier sequencer is not supported")
}

func (s *l2VerifierBackend) SequencerActive(ctx context.Context) (bool, error) {
return false, nil
}

func (s *L2Verifier) L2Finalized() eth.L2BlockRef {
return s.derivation.Finalized()
}
Expand Down
26 changes: 22 additions & 4 deletions op-e2e/system_adminrpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,46 @@ func TestStopStartSequencer(t *testing.T) {

nodeRPC, err := rpc.DialContext(context.Background(), rollupNode.HTTPEndpoint())
require.Nil(t, err, "Error dialing node")
rollupClient := sources.NewRollupClient(client.NewBaseRPCClient(nodeRPC))

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
active, err := rollupClient.SequencerActive(ctx)
require.NoError(t, err)
require.True(t, active, "sequencer should be active")

blockBefore := latestBlock(t, l2Seq)
time.Sleep(time.Duration(cfg.DeployConfig.L2BlockTime+1) * time.Second)
blockAfter := latestBlock(t, l2Seq)
require.Greaterf(t, blockAfter, blockBefore, "Chain did not advance")

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
blockHash := common.Hash{}
err = nodeRPC.CallContext(ctx, &blockHash, "admin_stopSequencer")
blockHash, err := rollupClient.StopSequencer(ctx)
require.Nil(t, err, "Error stopping sequencer")

ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
active, err = rollupClient.SequencerActive(ctx)
require.NoError(t, err)
require.False(t, active, "sequencer should be inactive")

blockBefore = latestBlock(t, l2Seq)
time.Sleep(time.Duration(cfg.DeployConfig.L2BlockTime+1) * time.Second)
blockAfter = latestBlock(t, l2Seq)
require.Equal(t, blockAfter, blockBefore, "Chain advanced after stopping sequencer")

ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err = nodeRPC.CallContext(ctx, nil, "admin_startSequencer", blockHash)
err = rollupClient.StartSequencer(ctx, blockHash)
require.Nil(t, err, "Error starting sequencer")

ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
active, err = rollupClient.SequencerActive(ctx)
require.NoError(t, err)
require.True(t, active, "sequencer should be active again")

blockBefore = latestBlock(t, l2Seq)
time.Sleep(time.Duration(cfg.DeployConfig.L2BlockTime+1) * time.Second)
blockAfter = latestBlock(t, l2Seq)
Expand Down
7 changes: 7 additions & 0 deletions op-node/node/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type driverClient interface {
ResetDerivationPipeline(context.Context) error
StartSequencer(ctx context.Context, blockHash common.Hash) error
StopSequencer(context.Context) (common.Hash, error)
SequencerActive(context.Context) (bool, error)
}

type rpcMetrics interface {
Expand Down Expand Up @@ -65,6 +66,12 @@ func (n *adminAPI) StopSequencer(ctx context.Context) (common.Hash, error) {
return n.dr.StopSequencer(ctx)
}

func (n *adminAPI) SequencerActive(ctx context.Context) (bool, error) {
recordDur := n.m.RecordRPCServerRequest("admin_sequencerActive")
defer recordDur()
return n.dr.SequencerActive(ctx)
}

type nodeAPI struct {
config *rollup.Config
client l2EthClient
Expand Down
4 changes: 4 additions & 0 deletions op-node/node/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,7 @@ func (c *mockDriverClient) StartSequencer(ctx context.Context, blockHash common.
func (c *mockDriverClient) StopSequencer(ctx context.Context) (common.Hash, error) {
return c.Mock.MethodCalled("StopSequencer").Get(0).(common.Hash), nil
}

func (c *mockDriverClient) SequencerActive(ctx context.Context) (bool, error) {
return c.Mock.MethodCalled("SequencerActive").Get(0).(bool), nil
}
1 change: 1 addition & 0 deletions op-node/rollup/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func NewDriver(driverCfg *Config, cfg *rollup.Config, l2 L2Chain, l1 L1Chain, al
forceReset: make(chan chan struct{}, 10),
startSequencer: make(chan hashAndErrorChannel, 10),
stopSequencer: make(chan chan hashAndError, 10),
sequencerActive: make(chan chan bool, 10),
sequencerNotifs: sequencerStateListener,
config: cfg,
driverConfig: driverCfg,
Expand Down
25 changes: 25 additions & 0 deletions op-node/rollup/driver/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ type Driver struct {
// It tells the caller that the sequencer stopped by returning the latest sequenced L2 block hash.
stopSequencer chan chan hashAndError

// Upon receiving a channel in this channel, the current sequencer status is queried.
// It tells the caller the status by outputting a boolean to the provided channel:
// true when the sequencer is active, false when it is not.
sequencerActive chan chan bool

// sequencerNotifs is notified when the sequencer is started or stopped
sequencerNotifs SequencerStateListener

Expand Down Expand Up @@ -373,6 +378,8 @@ func (s *Driver) eventLoop() {
s.driverConfig.SequencerStopped = true
respCh <- hashAndError{hash: s.derivation.UnsafeL2Head().Hash}
}
case respCh := <-s.sequencerActive:
respCh <- !s.driverConfig.SequencerStopped
case <-s.done:
return
}
Expand Down Expand Up @@ -436,6 +443,24 @@ func (s *Driver) StopSequencer(ctx context.Context) (common.Hash, error) {
}
}

func (s *Driver) SequencerActive(ctx context.Context) (bool, error) {
if !s.driverConfig.SequencerEnabled {
return false, nil
}
respCh := make(chan bool, 1)
select {
case <-ctx.Done():
return false, ctx.Err()
case s.sequencerActive <- respCh:
select {
case <-ctx.Done():
return false, ctx.Err()
case active := <-respCh:
return active, nil
}
}
}

// syncStatus returns the current sync status, and should only be called synchronously with
// the driver event loop to avoid retrieval of an inconsistent status.
func (s *Driver) syncStatus() *eth.SyncStatus {
Expand Down
6 changes: 6 additions & 0 deletions op-node/sources/rollupclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,9 @@ func (r *RollupClient) StopSequencer(ctx context.Context) (common.Hash, error) {
err := r.rpc.CallContext(ctx, &result, "admin_stopSequencer")
return result, err
}

func (r *RollupClient) SequencerActive(ctx context.Context) (bool, error) {
var result bool
err := r.rpc.CallContext(ctx, &result, "admin_sequencerActive")
return result, err
}

0 comments on commit 0399485

Please sign in to comment.