From 881e68dbbb29dd326f4d30edd262b45c62b52123 Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Tue, 17 Dec 2024 16:57:43 +0100 Subject: [PATCH] Implement AuRa remoteConsensusEngine (#13141) Follow-up on PR #13125 --- cmd/rpcdaemon/cli/config.go | 27 ++++++++++++++++++++------- consensus/aura/aura.go | 10 ++++++++++ consensus/aura/epoch.go | 9 ++++++++- erigon-lib/kv/helpers.go | 18 ++++++++++++++++++ erigon-lib/kv/tables.go | 5 +++++ polygon/bor/bor.go | 22 +--------------------- 6 files changed, 62 insertions(+), 29 deletions(-) diff --git a/cmd/rpcdaemon/cli/config.go b/cmd/rpcdaemon/cli/config.go index 41d5c087cdf..a55ac8b7af3 100644 --- a/cmd/rpcdaemon/cli/config.go +++ b/cmd/rpcdaemon/cli/config.go @@ -69,6 +69,7 @@ import ( "github.com/erigontech/erigon/consensus/merge" "github.com/erigontech/erigon/core/rawdb" "github.com/erigontech/erigon/core/state" + "github.com/erigontech/erigon/core/tracing" "github.com/erigontech/erigon/core/types" "github.com/erigontech/erigon/core/vm/evmtypes" "github.com/erigontech/erigon/eth/ethconfig" @@ -979,6 +980,8 @@ type remoteConsensusEngine struct { engine consensus.Engine } +var _ consensus.Engine = (*remoteConsensusEngine)(nil) + func (e *remoteConsensusEngine) HasEngine() bool { return e.engine != nil } @@ -1019,10 +1022,18 @@ func (e *remoteConsensusEngine) init(db kv.RoDB, blockReader services.FullBlockR // TODO(yperbasis): try to unify with CreateConsensusEngine var eng consensus.Engine if cc.Aura != nil { - // TODO(yperbasis): support Aura remoteConsensusEngine - return errors.New("aura remoteConsensusEngine is not supported yet") - } else if cc.Clique != nil { - return errors.New("clique remoteConsensusEngine is not supported") + auraKv, err := remotedb.NewRemote(gointerfaces.VersionFromProto(remotedbserver.KvServiceAPIVersion), logger, remoteKV). + WithBucketsConfig(kv.AuRaTablesCfg). + Open() + + if err != nil { + return err + } + + eng, err = aura.NewRo(cc.Aura, auraKv) + if err != nil { + return err + } } else if cc.Bor != nil { borKv, err := remotedb.NewRemote(gointerfaces.VersionFromProto(remotedbserver.KvServiceAPIVersion), logger, remoteKV). WithBucketsConfig(kv.BorTablesCfg). @@ -1033,6 +1044,8 @@ func (e *remoteConsensusEngine) init(db kv.RoDB, blockReader services.FullBlockR } eng = bor.NewRo(cc, borKv, blockReader, logger) + } else if cc.Clique != nil { + return errors.New("clique remoteConsensusEngine is not supported") } else { eng = ethash.NewFaker() } @@ -1085,12 +1098,12 @@ func (e *remoteConsensusEngine) Close() error { return e.engine.Close() } -func (e *remoteConsensusEngine) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, syscall consensus.SysCallCustom, logger log.Logger) { +func (e *remoteConsensusEngine) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, syscall consensus.SysCallCustom, logger log.Logger, tracer *tracing.Hooks) { if err := e.validateEngineReady(); err != nil { panic(err) } - e.engine.Initialize(config, chain, header, state, syscall, logger, nil) + e.engine.Initialize(config, chain, header, state, syscall, logger, tracer) } func (e *remoteConsensusEngine) GetTransferFunc() evmtypes.TransferFunc { @@ -1125,7 +1138,7 @@ func (e *remoteConsensusEngine) Finalize(_ *chain.Config, _ *types.Header, _ *st panic("remoteConsensusEngine.Finalize not supported") } -func (e *remoteConsensusEngine) FinalizeAndAssemble(_ *chain.Config, _ *types.Header, _ *state.IntraBlockState, _ types.Transactions, _ []*types.Header, _ types.Receipts, _ []*types.Withdrawal, _ consensus.ChainReader, _ consensus.SystemCall, _ consensus.Call, _ log.Logger) (*types.Block, types.Transactions, types.Receipts, error) { +func (e *remoteConsensusEngine) FinalizeAndAssemble(_ *chain.Config, _ *types.Header, _ *state.IntraBlockState, _ types.Transactions, _ []*types.Header, _ types.Receipts, _ []*types.Withdrawal, _ consensus.ChainReader, _ consensus.SystemCall, _ consensus.Call, _ log.Logger) (*types.Block, types.Transactions, types.Receipts, types.FlatRequests, error) { panic("remoteConsensusEngine.FinalizeAndAssemble not supported") } diff --git a/consensus/aura/aura.go b/consensus/aura/aura.go index 1ce7be14920..84d4a5c1b1e 100644 --- a/consensus/aura/aura.go +++ b/consensus/aura/aura.go @@ -323,6 +323,16 @@ func NewAuRa(spec *chain.AuRaConfig, db kv.RwDB) (*AuRa, error) { return c, nil } +// NewRo is used by the RPC daemon +func NewRo(spec *chain.AuRaConfig, db kv.RoDB) (*AuRa, error) { + c, err := NewAuRa(spec, kv.RwWrapper{RoDB: db}) + if err != nil { + return nil, err + } + c.e.readonly = true + return c, nil +} + // A helper accumulator function mapping a step duration and a step duration transition timestamp // to the corresponding step number and the correct starting second of the step. func nextStepTimeDuration(info StepDurationInfo, time uint64) (uint64, uint64, bool) { diff --git a/consensus/aura/epoch.go b/consensus/aura/epoch.go index 5012b427c62..630aa1ea183 100644 --- a/consensus/aura/epoch.go +++ b/consensus/aura/epoch.go @@ -26,7 +26,8 @@ import ( ) type NonTransactionalEpochReader struct { - db kv.RwDB + db kv.RwDB + readonly bool } func newEpochReader(db kv.RwDB) *NonTransactionalEpochReader { @@ -40,6 +41,9 @@ func (cr *NonTransactionalEpochReader) GetEpoch(hash libcommon.Hash, number uint }) } func (cr *NonTransactionalEpochReader) PutEpoch(hash libcommon.Hash, number uint64, proof []byte) error { + if cr.readonly { + return nil + } return cr.db.UpdateNosync(context.Background(), func(tx kv.RwTx) error { return rawdb.WriteEpoch(tx, number, hash, proof) }) @@ -51,6 +55,9 @@ func (cr *NonTransactionalEpochReader) GetPendingEpoch(hash libcommon.Hash, numb }) } func (cr *NonTransactionalEpochReader) PutPendingEpoch(hash libcommon.Hash, number uint64, proof []byte) error { + if cr.readonly { + return nil + } return cr.db.UpdateNosync(context.Background(), func(tx kv.RwTx) error { return rawdb.WritePendingEpoch(tx, number, hash, proof) }) diff --git a/erigon-lib/kv/helpers.go b/erigon-lib/kv/helpers.go index 62bf938b2aa..a960100625a 100644 --- a/erigon-lib/kv/helpers.go +++ b/erigon-lib/kv/helpers.go @@ -33,6 +33,24 @@ import ( "github.com/erigontech/erigon-lib/common" ) +// Adapts an RoDB to the RwDB interface (invoking write operations results in error) +type RwWrapper struct { + RoDB +} + +func (w RwWrapper) Update(ctx context.Context, f func(tx RwTx) error) error { + return errors.New("Update not implemented") +} +func (w RwWrapper) UpdateNosync(ctx context.Context, f func(tx RwTx) error) error { + return errors.New("UpdateNosync not implemented") +} +func (w RwWrapper) BeginRw(ctx context.Context) (RwTx, error) { + return nil, errors.New("BeginRw not implemented") +} +func (w RwWrapper) BeginRwNosync(ctx context.Context) (RwTx, error) { + return nil, errors.New("BeginRwNosync not implemented") +} + func DefaultPageSize() datasize.ByteSize { osPageSize := os.Getpagesize() if osPageSize < 4096 { // reduce further may lead to errors (because some data is just big) diff --git a/erigon-lib/kv/tables.go b/erigon-lib/kv/tables.go index 0d12d2563de..3752d92daf1 100644 --- a/erigon-lib/kv/tables.go +++ b/erigon-lib/kv/tables.go @@ -581,6 +581,11 @@ var ChaindataTablesCfg = TableCfg{ TblTracesToIdx: {Flags: DupSort}, } +var AuRaTablesCfg = TableCfg{ + Epoch: {}, + PendingEpoch: {}, +} + var BorTablesCfg = TableCfg{ BorFinality: {Flags: DupSort}, BorTxLookup: {Flags: DupSort}, diff --git a/polygon/bor/bor.go b/polygon/bor/bor.go index 1bba50d515d..9e9ccc0a428 100644 --- a/polygon/bor/bor.go +++ b/polygon/bor/bor.go @@ -409,26 +409,6 @@ func New( return c } -type rwWrapper struct { - kv.RoDB -} - -func (w rwWrapper) Update(ctx context.Context, f func(tx kv.RwTx) error) error { - return errors.New("Update not implemented") -} - -func (w rwWrapper) UpdateNosync(ctx context.Context, f func(tx kv.RwTx) error) error { - return errors.New("UpdateNosync not implemented") -} - -func (w rwWrapper) BeginRw(ctx context.Context) (kv.RwTx, error) { - return nil, errors.New("BeginRw not implemented") -} - -func (w rwWrapper) BeginRwNosync(ctx context.Context) (kv.RwTx, error) { - return nil, errors.New("BeginRwNosync not implemented") -} - // NewRo is used by the rpcdaemon and tests which need read only access to the provided data services func NewRo(chainConfig *chain.Config, db kv.RoDB, blockReader services.FullBlockReader, logger log.Logger) *Bor { // get bor config @@ -445,7 +425,7 @@ func NewRo(chainConfig *chain.Config, db kv.RoDB, blockReader services.FullBlock return &Bor{ chainConfig: chainConfig, config: borConfig, - DB: rwWrapper{db}, + DB: kv.RwWrapper{RoDB: db}, blockReader: blockReader, logger: logger, Recents: recents,