Commit 0094f515 authored by vicotor's avatar vicotor

update for sequencer generate block

parent 17494c8a
#!/bin/bash
rootdir=$(pwd)
configdir=$(pwd)/deployer
deploymentdir=$rootdir/packages/contracts-bedrock/deployments
cp $configdir/config.json $deploymentdir/
source $rootdir/.envrc
cd packages/contracts-bedrock && \
DEPLOYMENT_OUTFILE=$deploymentdir/artifact.json \
DEPLOY_CONFIG_PATH=$deploymentdir/config.json \
forge script scripts/deploy/Deploy.s.sol:Deploy \
--broadcast --private-key $PRIVATE_KEY \
--rpc-url $L1_RPC_URL
cp $deploymentdir/artifact.json $configdir/
cd $rootdir
...@@ -8,13 +8,16 @@ import ( ...@@ -8,13 +8,16 @@ import (
"github.com/exchain/go-exchain/exchain" "github.com/exchain/go-exchain/exchain"
"github.com/exchain/go-exchain/exchain/chaindb" "github.com/exchain/go-exchain/exchain/chaindb"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1" nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/exchain/wrapper"
"github.com/exchain/go-exchain/op-node/p2p" "github.com/exchain/go-exchain/op-node/p2p"
"github.com/exchain/go-exchain/op-node/rollup" "github.com/exchain/go-exchain/op-node/rollup"
"github.com/exchain/go-exchain/op-node/rollup/derive" "github.com/exchain/go-exchain/op-node/rollup/derive"
"github.com/exchain/go-exchain/op-node/rollup/driver" "github.com/exchain/go-exchain/op-node/rollup/driver"
"github.com/exchain/go-exchain/op-node/rollup/sync" "github.com/exchain/go-exchain/op-node/rollup/sync"
"github.com/exchain/go-exchain/op-service/eth" "github.com/exchain/go-exchain/op-service/eth"
lru "github.com/hashicorp/golang-lru"
"github.com/holiman/uint256" "github.com/holiman/uint256"
log "github.com/sirupsen/logrus"
"math/big" "math/big"
) )
...@@ -22,6 +25,7 @@ type ExChainAPI struct { ...@@ -22,6 +25,7 @@ type ExChainAPI struct {
rollup *rollup.Config rollup *rollup.Config
chain chaindb.ChainDB chain chaindb.ChainDB
engine exchain.Engine engine exchain.Engine
cached *lru.Cache
} }
func (e *ExChainAPI) BlockRefByNumber(ctx context.Context, num uint64) (eth.BlockRef, error) { func (e *ExChainAPI) BlockRefByNumber(ctx context.Context, num uint64) (eth.BlockRef, error) {
...@@ -39,6 +43,13 @@ func (e *ExChainAPI) OutputV0AtBlock(ctx context.Context, blockHash common.Hash) ...@@ -39,6 +43,13 @@ func (e *ExChainAPI) OutputV0AtBlock(ctx context.Context, blockHash common.Hash)
panic("implement me") panic("implement me")
} }
func (e *ExChainAPI) GetPayload(id eth.PayloadInfo) (*eth.ExecutionPayloadEnvelope, error) {
if v, exist := e.cached.Get(id.ID); exist {
return v.(*eth.ExecutionPayloadEnvelope), nil
}
return nil, errors.New("not found")
}
func (e *ExChainAPI) ChainID(ctx context.Context) (*big.Int, error) { func (e *ExChainAPI) ChainID(ctx context.Context) (*big.Int, error) {
id, err := e.chain.ChainId() id, err := e.chain.ChainId()
if err != nil { if err != nil {
...@@ -47,18 +58,29 @@ func (e *ExChainAPI) ChainID(ctx context.Context) (*big.Int, error) { ...@@ -47,18 +58,29 @@ func (e *ExChainAPI) ChainID(ctx context.Context) (*big.Int, error) {
return new(big.Int).SetUint64(id.Uint64()), nil return new(big.Int).SetUint64(id.Uint64()), nil
} }
func (e *ExChainAPI) NewPayload(params exchain.PayloadParams) (exchain.ExecutionResult, error) { func (e *ExChainAPI) NewPayload(params exchain.PayloadParams) (exchain.ExecutionResult, eth.PayloadInfo, error) {
result, err := e.engine.NewPayload(params) result, err := e.engine.NewPayload(params)
if err != nil { if err != nil {
return exchain.ExecutionResult{}, err return exchain.ExecutionResult{}, eth.PayloadInfo{}, err
} }
if err = e.chain.SaveBlockData(result.Payload, &result.Receipts); err != nil { if err = e.chain.SaveBlockData(result.Payload, &result.Receipts); err != nil {
return exchain.ExecutionResult{}, err return exchain.ExecutionResult{}, eth.PayloadInfo{}, err
} }
return result, nil hash := wrapper.NewBlkWrapper(result.Payload).Hash()
info := eth.PayloadInfo{ID: eth.PayloadID(hash[len(hash)-8:]), Timestamp: uint64(params.Timestamp)}
e.cached.Add(info.ID, &eth.ExecutionPayloadEnvelope{
ExecutionPayload: eth.NewExecutePayload(result.Payload),
ParentBeaconBlockRoot: nil,
})
return result, info, nil
} }
func (e *ExChainAPI) ProcessPayload(block *nebulav1.Block) error { func (e *ExChainAPI) ProcessPayload(block *nebulav1.Block) error {
if blk := e.chain.GetBlock(uint256.NewInt(block.Header.Height)); blk != nil {
// block has been processed
return nil
}
result, err := e.engine.ProcessPayload(block) result, err := e.engine.ProcessPayload(block)
if err != nil { if err != nil {
return err return err
...@@ -71,9 +93,8 @@ func (e *ExChainAPI) PayloadByNumber(ctx context.Context, u uint64) (*eth.Execut ...@@ -71,9 +93,8 @@ func (e *ExChainAPI) PayloadByNumber(ctx context.Context, u uint64) (*eth.Execut
if block == nil { if block == nil {
return &eth.ExecutionPayloadEnvelope{}, errors.New("not found block") return &eth.ExecutionPayloadEnvelope{}, errors.New("not found block")
} }
payload := eth.NewExecutePayload(block)
return &eth.ExecutionPayloadEnvelope{ return &eth.ExecutionPayloadEnvelope{
ExecutionPayload: payload, ExecutionPayload: eth.NewExecutePayload(block),
ParentBeaconBlockRoot: nil, // todo: vicotor fill this field ParentBeaconBlockRoot: nil, // todo: vicotor fill this field
}, nil }, nil
} }
...@@ -85,7 +106,9 @@ func (e *ExChainAPI) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel ...@@ -85,7 +106,9 @@ func (e *ExChainAPI) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel
if err != nil { if err != nil {
return eth.L2BlockRef{}, err return eth.L2BlockRef{}, err
} }
return derive.PayloadToBlockRef(e.rollup, eth.NewExecutePayload(blk)) ref, err := derive.PayloadToBlockRef(e.rollup, eth.NewExecutePayload(blk))
log.WithField("label", label).WithField("ref", ref).Info("L2BlockRefByLabel")
return ref, err
default: default:
return eth.L2BlockRef{}, errors.New("unsupported label") return eth.L2BlockRef{}, errors.New("unsupported label")
} }
...@@ -125,9 +148,11 @@ var ( ...@@ -125,9 +148,11 @@ var (
) )
func NewEngineAPI(cfg *rollup.Config, database chaindb.ChainDB, engine exchain.Engine) *ExChainAPI { func NewEngineAPI(cfg *rollup.Config, database chaindb.ChainDB, engine exchain.Engine) *ExChainAPI {
cache, _ := lru.New(100)
return &ExChainAPI{ return &ExChainAPI{
rollup: cfg, rollup: cfg,
chain: database, chain: database,
engine: engine, engine: engine,
cached: cache,
} }
} }
package mockengine package mockengine
import ( import (
"github.com/ethereum/go-ethereum/common"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1" nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/exchain/wrapper" "github.com/exchain/go-exchain/exchain/wrapper"
"github.com/holiman/uint256"
log "github.com/sirupsen/logrus"
) )
func (m MockEngine) ProcessTx(header *nebulav1.BlockHeader, txs nebulav1.TransactionList) (nebulav1.TransactionReceiptList, error) { func (m MockEngine) ProcessTx(header *nebulav1.BlockHeader, txs nebulav1.TransactionList) (nebulav1.TransactionReceiptList, error) {
...@@ -23,6 +26,12 @@ func (m MockEngine) ProcessTx(header *nebulav1.BlockHeader, txs nebulav1.Transac ...@@ -23,6 +26,12 @@ func (m MockEngine) ProcessTx(header *nebulav1.BlockHeader, txs nebulav1.Transac
receipt.Content = &nebulav1.TransactionReceipt_DepositR{ receipt.Content = &nebulav1.TransactionReceipt_DepositR{
DepositR: &nebulav1.DepositReceipt{}, DepositR: &nebulav1.DepositReceipt{},
} }
deposit := tx.GetDepositTx()
log.WithFields(log.Fields{
"from": common.BytesToAddress(deposit.User),
"coin": string(deposit.Coin),
"value": new(uint256.Int).SetBytes(deposit.Amount).String(),
}).Info("Process deposit tx")
case nebulav1.TxType_LimitTx: case nebulav1.TxType_LimitTx:
receipt.Content = &nebulav1.TransactionReceipt_LimitR{ receipt.Content = &nebulav1.TransactionReceipt_LimitR{
LimitR: &nebulav1.LimitOrderReceipt{}, LimitR: &nebulav1.LimitOrderReceipt{},
......
#!/bin/bash
./opnode genesis l2 --deploy-config ./deployer/config.json --l1-deployments ./deployer/artifact.json --l2-allocs ./deployer/alloc.json --outfile.l2 ./deployer/genesis.json --outfile.rollup ./deployer/rollup.json --l1-rpc=http://18.168.16.120:18888
#!/bin/bash
./opnode genesis init --data-dir node --genesis ./deployer/genesis.json
...@@ -1015,12 +1015,12 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Header, l2GenesisBlockHa ...@@ -1015,12 +1015,12 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Header, l2GenesisBlockHa
RegolithTime: d.RegolithTime(l1StartTime), RegolithTime: d.RegolithTime(l1StartTime),
CanyonTime: d.CanyonTime(l1StartTime), CanyonTime: d.CanyonTime(l1StartTime),
DeltaTime: d.DeltaTime(l1StartTime), DeltaTime: d.DeltaTime(l1StartTime),
EcotoneTime: d.EcotoneTime(l1StartTime), //EcotoneTime: d.EcotoneTime(l1StartTime),
FjordTime: d.FjordTime(l1StartTime), //FjordTime: d.FjordTime(l1StartTime),
GraniteTime: d.GraniteTime(l1StartTime), //GraniteTime: d.GraniteTime(l1StartTime),
HoloceneTime: d.HoloceneTime(l1StartTime), //HoloceneTime: d.HoloceneTime(l1StartTime),
IsthmusTime: d.IsthmusTime(l1StartTime), //IsthmusTime: d.IsthmusTime(l1StartTime),
InteropTime: d.InteropTime(l1StartTime), //InteropTime: d.InteropTime(l1StartTime),
ProtocolVersionsAddress: d.ProtocolVersionsProxy, ProtocolVersionsAddress: d.ProtocolVersionsProxy,
AltDAConfig: altDA, AltDAConfig: altDA,
}, nil }, nil
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1" nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/op-node/rollup" "github.com/exchain/go-exchain/op-node/rollup"
"github.com/exchain/go-exchain/op-service/eth" "github.com/exchain/go-exchain/op-service/eth"
log "github.com/sirupsen/logrus"
) )
// PayloadToBlockRef extracts the essential L2BlockRef information from an execution payload, // PayloadToBlockRef extracts the essential L2BlockRef information from an execution payload,
...@@ -20,6 +21,11 @@ func PayloadToBlockRef(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) ...@@ -20,6 +21,11 @@ func PayloadToBlockRef(rollupCfg *rollup.Config, payload *eth.ExecutionPayload)
} }
l1Origin = genesis.L1 l1Origin = genesis.L1
sequenceNumber = 0 sequenceNumber = 0
log.WithFields(log.Fields{
"blockNumber": payload.BlockNumber,
"blockHash": payload.BlockHash,
"l1info": l1Origin,
}).Debug("using genesis L1 info for L2 block")
} else { } else {
header := payload.Payload.Header header := payload.Payload.Header
l1Origin = eth.BlockID{Hash: common.BytesToHash(header.L1Hash), Number: header.L1Height} l1Origin = eth.BlockID{Hash: common.BytesToHash(header.L1Hash), Number: header.L1Height}
......
...@@ -241,7 +241,7 @@ func NewDriver( ...@@ -241,7 +241,7 @@ func NewDriver(
findL1Origin := sequencing.NewL1OriginSelector(driverCtx, log, cfg, sequencerConfDepth) findL1Origin := sequencing.NewL1OriginSelector(driverCtx, log, cfg, sequencerConfDepth)
sys.Register("origin-selector", findL1Origin, opts) sys.Register("origin-selector", findL1Origin, opts)
sequencer = sequencing.NewSequencer(driverCtx, log, cfg, attrBuilder, findL1Origin, sequencer = sequencing.NewSequencer(driverCtx, log, cfg, attrBuilder, findL1Origin,
sequencerStateListener, sequencerConductor, asyncGossiper, metrics) sequencerStateListener, sequencerConductor, asyncGossiper, metrics, l2)
sys.Register("sequencer", sequencer, opts) sys.Register("sequencer", sequencer, opts)
} else { } else {
sequencer = sequencing.DisabledSequencer{} sequencer = sequencing.DisabledSequencer{}
......
...@@ -177,7 +177,10 @@ func (s *Driver) eventLoop() { ...@@ -177,7 +177,10 @@ func (s *Driver) eventLoop() {
} }
// avoid unnecessary timer resets // avoid unnecessary timer resets
if nextAction == prevTime { if nextAction == prevTime {
s.log.Debug("Sequencer action unchanged", "nextAction", nextAction)
return return
} else {
s.log.Debug("Sequencer action updated", "nextAction", nextAction)
} }
prevTime = nextAction prevTime = nextAction
sequencerCh = sequencerTimer.C sequencerCh = sequencerTimer.C
......
...@@ -44,7 +44,6 @@ type BuildSealEvent struct { ...@@ -44,7 +44,6 @@ type BuildSealEvent struct {
Concluding bool Concluding bool
// payload is promoted to pending-safe if non-zero // payload is promoted to pending-safe if non-zero
DerivedFrom eth.L1BlockRef DerivedFrom eth.L1BlockRef
Envelope *eth.ExecutionPayloadEnvelope
} }
func (ev BuildSealEvent) String() string { func (ev BuildSealEvent) String() string {
...@@ -54,19 +53,31 @@ func (ev BuildSealEvent) String() string { ...@@ -54,19 +53,31 @@ func (ev BuildSealEvent) String() string {
func (eq *EngDeriver) onBuildSeal(ev BuildSealEvent) { func (eq *EngDeriver) onBuildSeal(ev BuildSealEvent) {
sealingStart := time.Now() sealingStart := time.Now()
result, err := eq.ec.engine.GetPayload(ev.Info)
if err != nil {
eq.log.Warn("Cannot seal block", "err", err, "id", ev.Info)
eq.emitter.Emit(PayloadSealExpiredErrorEvent{
Info: ev.Info,
Err: fmt.Errorf("failed to seal execution payload (ID: %s): %w", ev.Info.ID, err),
Concluding: ev.Concluding,
DerivedFrom: ev.DerivedFrom,
})
return
}
envelope := result
if err := sanityCheckPayload(ev.Envelope.ExecutionPayload); err != nil { if err := sanityCheckPayload(envelope.ExecutionPayload); err != nil {
eq.emitter.Emit(PayloadSealInvalidEvent{ eq.emitter.Emit(PayloadSealInvalidEvent{
Info: ev.Info, Info: ev.Info,
Err: fmt.Errorf("failed sanity-check of execution payload contents (ID: %s, blockhash: %s): %w", Err: fmt.Errorf("failed sanity-check of execution payload contents (ID: %s, blockhash: %s): %w",
ev.Info.ID, ev.Envelope.ExecutionPayload.BlockHash, err), ev.Info.ID, envelope.ExecutionPayload.BlockHash, err),
Concluding: ev.Concluding, Concluding: ev.Concluding,
DerivedFrom: ev.DerivedFrom, DerivedFrom: ev.DerivedFrom,
}) })
return return
} }
ref, err := derive.PayloadToBlockRef(eq.cfg, ev.Envelope.ExecutionPayload) ref, err := derive.PayloadToBlockRef(eq.cfg, envelope.ExecutionPayload)
if err != nil { if err != nil {
eq.emitter.Emit(PayloadSealInvalidEvent{ eq.emitter.Emit(PayloadSealInvalidEvent{
Info: ev.Info, Info: ev.Info,
...@@ -83,7 +94,7 @@ func (eq *EngDeriver) onBuildSeal(ev BuildSealEvent) { ...@@ -83,7 +94,7 @@ func (eq *EngDeriver) onBuildSeal(ev BuildSealEvent) {
eq.metrics.RecordSequencerSealingTime(sealTime) eq.metrics.RecordSequencerSealingTime(sealTime)
eq.metrics.RecordSequencerBuildingDiffTime(buildTime - time.Duration(eq.cfg.BlockTime)*time.Second) eq.metrics.RecordSequencerBuildingDiffTime(buildTime - time.Duration(eq.cfg.BlockTime)*time.Second)
txs := ev.Envelope.ExecutionPayload.Transactions() txs := envelope.ExecutionPayload.Transactions()
txnCount := len(txs) txnCount := len(txs)
depositCount, _ := lastDeposit(txs) depositCount, _ := lastDeposit(txs)
eq.metrics.CountSequencedTxsInBlock(txnCount, depositCount) eq.metrics.CountSequencedTxsInBlock(txnCount, depositCount)
...@@ -96,7 +107,7 @@ func (eq *EngDeriver) onBuildSeal(ev BuildSealEvent) { ...@@ -96,7 +107,7 @@ func (eq *EngDeriver) onBuildSeal(ev BuildSealEvent) {
DerivedFrom: ev.DerivedFrom, DerivedFrom: ev.DerivedFrom,
BuildStarted: ev.BuildStarted, BuildStarted: ev.BuildStarted,
Info: ev.Info, Info: ev.Info,
Envelope: ev.Envelope, Envelope: envelope,
Ref: ref, Ref: ref,
}) })
} }
...@@ -3,7 +3,6 @@ package engine ...@@ -3,7 +3,6 @@ package engine
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/exchain/go-exchain/exchain/wrapper"
"time" "time"
"github.com/exchain/go-exchain/op-node/rollup" "github.com/exchain/go-exchain/op-node/rollup"
...@@ -44,23 +43,18 @@ func (eq *EngDeriver) onBuildStart(ev BuildStartEvent) { ...@@ -44,23 +43,18 @@ func (eq *EngDeriver) onBuildStart(ev BuildStartEvent) {
FinalizedBlockHash: fcEvent.FinalizedL2Head.Hash, FinalizedBlockHash: fcEvent.FinalizedL2Head.Hash,
} }
buildStartTime := time.Now() buildStartTime := time.Now()
result, err := startPayload(context.TODO(), eq.ec.engine, fc, ev.Attributes.Attributes) _, info, err := startPayload(context.TODO(), eq.ec.engine, fc, ev.Attributes.Attributes)
if err != nil { if err != nil {
eq.emitter.Emit(rollup.EngineTemporaryErrorEvent{Err: fmt.Errorf("temporarily cannot create new block: %w", err)}) eq.emitter.Emit(rollup.EngineTemporaryErrorEvent{Err: fmt.Errorf("temporarily cannot create new block: %w", err)})
return return
} }
eq.emitter.Emit(fcEvent) eq.emitter.Emit(fcEvent)
hash := wrapper.NewBlkWrapper(result.Payload).Hash()
eq.emitter.Emit(BuildStartedEvent{ eq.emitter.Emit(BuildStartedEvent{
Info: eth.PayloadInfo{ID: eth.PayloadID(hash[len(hash)-8:]), Timestamp: uint64(ev.Attributes.Attributes.Param.Timestamp)}, Info: info,
BuildStarted: buildStartTime, BuildStarted: buildStartTime,
Concluding: ev.Attributes.Concluding, Concluding: ev.Attributes.Concluding,
DerivedFrom: ev.Attributes.DerivedFrom, DerivedFrom: ev.Attributes.DerivedFrom,
Parent: ev.Attributes.Parent, Parent: ev.Attributes.Parent,
Envelope: &eth.ExecutionPayloadEnvelope{
ParentBeaconBlockRoot: nil,
ExecutionPayload: eth.NewExecutePayload(result.Payload),
},
}) })
} }
...@@ -17,7 +17,6 @@ type BuildStartedEvent struct { ...@@ -17,7 +17,6 @@ type BuildStartedEvent struct {
Concluding bool Concluding bool
// payload is promoted to pending-safe if non-zero // payload is promoted to pending-safe if non-zero
DerivedFrom eth.L1BlockRef DerivedFrom eth.L1BlockRef
Envelope *eth.ExecutionPayloadEnvelope
} }
func (ev BuildStartedEvent) String() string { func (ev BuildStartedEvent) String() string {
...@@ -32,7 +31,6 @@ func (eq *EngDeriver) onBuildStarted(ev BuildStartedEvent) { ...@@ -32,7 +31,6 @@ func (eq *EngDeriver) onBuildStarted(ev BuildStartedEvent) {
BuildStarted: ev.BuildStarted, BuildStarted: ev.BuildStarted,
Concluding: ev.Concluding, Concluding: ev.Concluding,
DerivedFrom: ev.DerivedFrom, DerivedFrom: ev.DerivedFrom,
Envelope: ev.Envelope,
}) })
} }
} }
...@@ -36,12 +36,13 @@ const ( ...@@ -36,12 +36,13 @@ const (
var ErrNoFCUNeeded = errors.New("no FCU call was needed") var ErrNoFCUNeeded = errors.New("no FCU call was needed")
type ExecEngine interface { type ExecEngine interface {
NewPayload(params exchain.PayloadParams) (exchain.ExecutionResult, error) NewPayload(params exchain.PayloadParams) (exchain.ExecutionResult, eth.PayloadInfo, error)
ProcessPayload(block *nebulav1.Block) error ProcessPayload(block *nebulav1.Block) error
GetPayload(id eth.PayloadInfo) (*eth.ExecutionPayloadEnvelope, error)
//GetPayload(ctx context.Context, payloadInfo eth.PayloadInfo) (*eth.ExecutionPayloadEnvelope, error) //GetPayload(ctx context.Context, payloadInfo eth.PayloadInfo) (*eth.ExecutionPayloadEnvelope, error)
//ForkchoiceUpdate(ctx context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error) //ForkchoiceUpdate(ctx context.Context, state *eth.ForkchoiceState, attr *eth.PayloadAttributes) (*eth.ForkchoiceUpdatedResult, error)
//NewPayload(ctx context.Context, payload *eth.ExecutionPayload, parentBeaconBlockRoot *common.Hash) (*eth.PayloadStatusV1, error) //NewPayload(ctx context.Context, payload *eth.ExecutionPayload, parentBeaconBlockRoot *common.Hash) (*eth.PayloadStatusV1, error)
//L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error)
} }
type EngineController struct { type EngineController struct {
......
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
// isDepositTx checks an opaqueTx to determine if it is a Deposit Transaction // isDepositTx checks an opaqueTx to determine if it is a Deposit Transaction
// It has to return an error in the case the transaction is empty // It has to return an error in the case the transaction is empty
func isDepositTx(opaqueTx *nebulav1.Transaction) (bool, error) { func isDepositTx(opaqueTx *nebulav1.Transaction) (bool, error) {
return opaqueTx.TxType == nebulav1.TxType_DepositTx, nil return opaqueTx.TxType == nebulav1.TxType_ProtocolTx, nil
} }
// lastDeposit finds the index of last deposit at the start of the transactions. // lastDeposit finds the index of last deposit at the start of the transactions.
...@@ -81,10 +81,10 @@ const ( ...@@ -81,10 +81,10 @@ const (
// startPayload starts an execution payload building process in the provided Engine, with the given attributes. // startPayload starts an execution payload building process in the provided Engine, with the given attributes.
// The severity of the error is distinguished to determine whether the same payload attributes may be re-attempted later. // The severity of the error is distinguished to determine whether the same payload attributes may be re-attempted later.
func startPayload(ctx context.Context, eng ExecEngine, fc eth.ForkchoiceState, attrs *eth.PayloadAttributes) (exchain.ExecutionResult, error) { func startPayload(ctx context.Context, eng ExecEngine, fc eth.ForkchoiceState, attrs *eth.PayloadAttributes) (exchain.ExecutionResult, eth.PayloadInfo, error) {
fcRes, err := eng.NewPayload(*attrs.Param) fcRes, info, err := eng.NewPayload(*attrs.Param)
if err != nil { if err != nil {
return exchain.ExecutionResult{}, fmt.Errorf("failed to create new block: %w", err) return exchain.ExecutionResult{}, eth.PayloadInfo{}, fmt.Errorf("failed to create new block: %w", err)
} }
return fcRes, nil return fcRes, info, nil
} }
...@@ -117,6 +117,8 @@ type Sequencer struct { ...@@ -117,6 +117,8 @@ type Sequencer struct {
latestHeadSet chan struct{} latestHeadSet chan struct{}
l2chain engine.ExecEngine
// toBlockRef converts a payload to a block-ref, and is only configurable for test-purposes // toBlockRef converts a payload to a block-ref, and is only configurable for test-purposes
toBlockRef func(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) (eth.L2BlockRef, error) toBlockRef func(rollupCfg *rollup.Config, payload *eth.ExecutionPayload) (eth.L2BlockRef, error)
} }
...@@ -130,6 +132,7 @@ func NewSequencer(driverCtx context.Context, log log.Logger, rollupCfg *rollup.C ...@@ -130,6 +132,7 @@ func NewSequencer(driverCtx context.Context, log log.Logger, rollupCfg *rollup.C
conductor conductor.SequencerConductor, conductor conductor.SequencerConductor,
asyncGossip AsyncGossiper, asyncGossip AsyncGossiper,
metrics Metrics, metrics Metrics,
l2chain engine.ExecEngine,
) *Sequencer { ) *Sequencer {
return &Sequencer{ return &Sequencer{
ctx: driverCtx, ctx: driverCtx,
...@@ -144,6 +147,7 @@ func NewSequencer(driverCtx context.Context, log log.Logger, rollupCfg *rollup.C ...@@ -144,6 +147,7 @@ func NewSequencer(driverCtx context.Context, log log.Logger, rollupCfg *rollup.C
metrics: metrics, metrics: metrics,
timeNow: time.Now, timeNow: time.Now,
toBlockRef: derive.PayloadToBlockRef, toBlockRef: derive.PayloadToBlockRef,
l2chain: l2chain,
} }
} }
...@@ -179,8 +183,8 @@ func (d *Sequencer) OnEvent(ev event.Event) bool { ...@@ -179,8 +183,8 @@ func (d *Sequencer) OnEvent(ev event.Event) bool {
d.onPayloadSuccess(x) d.onPayloadSuccess(x)
case SequencerActionEvent: case SequencerActionEvent:
d.onSequencerAction(x) d.onSequencerAction(x)
case rollup.EngineTemporaryErrorEvent: //case rollup.EngineTemporaryErrorEvent:
d.onEngineTemporaryError(x) // d.onEngineTemporaryError(x)
case rollup.ResetEvent: case rollup.ResetEvent:
d.onReset(x) d.onReset(x)
case engine.EngineResetConfirmedEvent: case engine.EngineResetConfirmedEvent:
...@@ -307,11 +311,26 @@ func (d *Sequencer) onPayloadInvalid(x engine.PayloadInvalidEvent) { ...@@ -307,11 +311,26 @@ func (d *Sequencer) onPayloadInvalid(x engine.PayloadInvalidEvent) {
func (d *Sequencer) onPayloadSuccess(x engine.PayloadSuccessEvent) { func (d *Sequencer) onPayloadSuccess(x engine.PayloadSuccessEvent) {
// d.latest as building state may already be empty, // d.latest as building state may already be empty,
// if the forkchoice update (that dropped the stale building job) was received before the payload-success. // if the forkchoice update (that dropped the stale building job) was received before the payload-success.
d.log.Info("Sequencer on payload success event", "block", x.Envelope.ExecutionPayload.ID())
if d.latest.Ref != (eth.L2BlockRef{}) && d.latest.Ref.Hash != x.Envelope.ExecutionPayload.BlockHash { if d.latest.Ref != (eth.L2BlockRef{}) && d.latest.Ref.Hash != x.Envelope.ExecutionPayload.BlockHash {
d.log.Info("Sequencer received success event for a different block, ignoring", "d.latest", d.latestHead)
// Not a payload that was built by this sequencer. We can ignore it, and continue upon forkchoice update. // Not a payload that was built by this sequencer. We can ignore it, and continue upon forkchoice update.
return return
} }
d.latest = BuildingState{} d.latest = BuildingState{}
d.nextActionOK = true
now := d.timeNow()
blockTime := time.Duration(d.rollupCfg.BlockTime) * time.Second
payloadTime := time.Unix(int64(x.Ref.Time+d.rollupCfg.BlockTime), 0)
remainingTime := payloadTime.Sub(now)
if remainingTime > blockTime {
// if we have too much time, then wait before starting the build
d.nextAction = payloadTime.Add(-blockTime)
} else {
// otherwise start instantly
d.nextAction = now
}
d.setLatestHead(x.Ref)
d.log.Info("Sequencer inserted block", d.log.Info("Sequencer inserted block",
"block", x.Ref, "parent", x.Envelope.ExecutionPayload.ParentID()) "block", x.Ref, "parent", x.Envelope.ExecutionPayload.ParentID())
// The payload was already published upon sealing. // The payload was already published upon sealing.
...@@ -349,6 +368,7 @@ func (d *Sequencer) onSequencerAction(SequencerActionEvent) { ...@@ -349,6 +368,7 @@ func (d *Sequencer) onSequencerAction(SequencerActionEvent) {
d.latest.Ref = ref d.latest.Ref = ref
} else { } else {
if d.latest.Info != (eth.PayloadInfo{}) { if d.latest.Info != (eth.PayloadInfo{}) {
d.log.Debug("Sequencer action with exist latest", "latest", d.latest.Info)
// We should not repeat the seal request. // We should not repeat the seal request.
d.nextActionOK = false d.nextActionOK = false
// No known payload for block building job, // No known payload for block building job,
...@@ -367,6 +387,8 @@ func (d *Sequencer) onSequencerAction(SequencerActionEvent) { ...@@ -367,6 +387,8 @@ func (d *Sequencer) onSequencerAction(SequencerActionEvent) {
} }
func (d *Sequencer) onEngineTemporaryError(x rollup.EngineTemporaryErrorEvent) { func (d *Sequencer) onEngineTemporaryError(x rollup.EngineTemporaryErrorEvent) {
d.log.Warn("current version not support current event, return directly", "event", "EngineTemporaryErrorEvent")
return
if d.latest == (BuildingState{}) { if d.latest == (BuildingState{}) {
d.log.Debug("Engine reported temporary error while building state is empty", "err", x.Err) d.log.Debug("Engine reported temporary error while building state is empty", "err", x.Err)
} }
...@@ -390,6 +412,8 @@ func (d *Sequencer) onEngineTemporaryError(x rollup.EngineTemporaryErrorEvent) { ...@@ -390,6 +412,8 @@ func (d *Sequencer) onEngineTemporaryError(x rollup.EngineTemporaryErrorEvent) {
} }
func (d *Sequencer) onReset(x rollup.ResetEvent) { func (d *Sequencer) onReset(x rollup.ResetEvent) {
d.log.Warn("current version not support current event, return directly", "event", "ResetEvent")
return
d.log.Error("Sequencer encountered reset signal, aborting work", "err", x.Err) d.log.Error("Sequencer encountered reset signal, aborting work", "err", x.Err)
d.metrics.RecordSequencerReset() d.metrics.RecordSequencerReset()
// try to cancel any ongoing payload building job // try to cancel any ongoing payload building job
...@@ -402,6 +426,8 @@ func (d *Sequencer) onReset(x rollup.ResetEvent) { ...@@ -402,6 +426,8 @@ func (d *Sequencer) onReset(x rollup.ResetEvent) {
} }
func (d *Sequencer) onEngineResetConfirmedEvent(engine.EngineResetConfirmedEvent) { func (d *Sequencer) onEngineResetConfirmedEvent(engine.EngineResetConfirmedEvent) {
d.log.Warn("current version not support current event, return directly", "event", "EngineResetConfirmedEvent")
return
d.nextActionOK = d.active.Load() d.nextActionOK = d.active.Load()
// Before sequencing we can wait a block, // Before sequencing we can wait a block,
// assuming the execution-engine just churned through some work for the reset. // assuming the execution-engine just churned through some work for the reset.
...@@ -413,7 +439,11 @@ func (d *Sequencer) onEngineResetConfirmedEvent(engine.EngineResetConfirmedEvent ...@@ -413,7 +439,11 @@ func (d *Sequencer) onEngineResetConfirmedEvent(engine.EngineResetConfirmedEvent
func (d *Sequencer) onForkchoiceUpdate(x engine.ForkchoiceUpdateEvent) { func (d *Sequencer) onForkchoiceUpdate(x engine.ForkchoiceUpdateEvent) {
d.log.Debug("Sequencer is processing forkchoice update", "unsafe", x.UnsafeL2Head, "latest", d.latestHead) d.log.Debug("Sequencer is processing forkchoice update", "unsafe", x.UnsafeL2Head, "latest", d.latestHead)
d.log.Warn("current version not support current event, return directly", "event", "ForkchoiceUpdate")
return
if !d.active.Load() { if !d.active.Load() {
d.log.Debug("Sequencer is not active, ignoring forkchoice update")
d.setLatestHead(x.UnsafeL2Head) d.setLatestHead(x.UnsafeL2Head)
return return
} }
...@@ -463,6 +493,7 @@ func (d *Sequencer) startBuildingBlock() { ...@@ -463,6 +493,7 @@ func (d *Sequencer) startBuildingBlock() {
// If we do not have data to know what to build on, then request a forkchoice update // If we do not have data to know what to build on, then request a forkchoice update
if l2Head == (eth.L2BlockRef{}) { if l2Head == (eth.L2BlockRef{}) {
d.log.Debug("start building but latest head is empty")
d.emitter.Emit(engine.ForkchoiceRequestEvent{}) d.emitter.Emit(engine.ForkchoiceRequestEvent{})
return return
} }
...@@ -575,8 +606,12 @@ func (d *Sequencer) Init(ctx context.Context, active bool) error { ...@@ -575,8 +606,12 @@ func (d *Sequencer) Init(ctx context.Context, active bool) error {
d.asyncGossip.Start() d.asyncGossip.Start()
// The `latestHead` should be updated, so we can handle start-sequencer requests latestHead, err := d.l2chain.L2BlockRefByLabel(ctx, eth.Unsafe)
d.emitter.Emit(engine.ForkchoiceRequestEvent{}) if err != nil {
d.log.Error("Failed to get latest head", "err", err)
} else {
d.setLatestHead(latestHead)
}
if active { if active {
return d.forceStart() return d.forceStart()
......
...@@ -64,7 +64,10 @@ func NewL1Client(client client.RPC, log log.Logger, metrics caching.Metrics, con ...@@ -64,7 +64,10 @@ func NewL1Client(client client.RPC, log log.Logger, metrics caching.Metrics, con
// L1BlockRefByLabel returns the [eth.L1BlockRef] for the given block label. // L1BlockRefByLabel returns the [eth.L1BlockRef] for the given block label.
// Notice, we cannot cache a block reference by label because labels are not guaranteed to be unique. // Notice, we cannot cache a block reference by label because labels are not guaranteed to be unique.
func (s *L1Client) L1BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L1BlockRef, error) { func (s *L1Client) L1BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L1BlockRef, error) {
return s.BlockRefByLabel(ctx, label)
res, err := s.BlockRefByLabel(ctx, label)
s.log.Debug("Fetching L1 block ref by label", "label", label, "block", res)
return res, err
} }
// L1BlockRefByNumber returns an [eth.L1BlockRef] for the given block number. // L1BlockRefByNumber returns an [eth.L1BlockRef] for the given block number.
......
File added
#!/bin/bash
source .envrc
echo "l1=$L1_RPC_URL"
./opnode \
--data-dir node \
--sequencer.enabled \
--sequencer.l1-confs=5 \
--verifier.l1-confs=4 \
--rollup.config=./deployer/rollup.json \
--rpc.addr=0.0.0.0 \
--p2p.disable \
--rpc.enable-admin \
--p2p.sequencer.key=$GS_SEQUENCER_PRIVATE_KEY \
--l1=$L1_RPC_URL \
--log.level=debug \
--l1.rpckind=$L1_RPC_KIND
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment