Skip to content
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6755a40
add SpansIndex tables
antonis19 Aug 11, 2025
f309f8b
use correct mdbx db
antonis19 Aug 12, 2025
a5d18f6
use spanIndex in MdbxStore
antonis19 Aug 12, 2025
3d34e1a
use new SpanIdAt in snapshots
antonis19 Aug 12, 2025
29fa088
implement spanRangeIndex
antonis19 Aug 13, 2025
13b9f1f
fixing bor mining benchmark
antonis19 Aug 13, 2025
3a9ba35
implement Last() for indexer
antonis19 Aug 13, 2025
9c19d78
fix test by populating bor span snapshots with valid data
antonis19 Aug 13, 2025
e771371
fix snapshot_store tests
antonis19 Aug 13, 2025
531d484
remove another SpanIdAt
antonis19 Aug 14, 2025
3ddbea3
remove SpanIdAt() from Entity()
antonis19 Aug 14, 2025
910d9d6
add tests for Entity()
antonis19 Aug 14, 2025
fc02238
add tests for span rotations
antonis19 Aug 14, 2025
38f47c3
use LastFrozenId() instead
antonis19 Aug 14, 2025
76b4d7d
remove hardcoded table
antonis19 Aug 14, 2025
e0ff53e
pass context to NotifySync()
antonis19 Aug 14, 2025
c29648e
change signature of LastFrozenEntityId()
antonis19 Aug 15, 2025
a10a3d3
Merge branch 'main' of github.com:erigontech/erigon into spans-index
antonis19 Aug 15, 2025
7d880ba
fix more merge conflicts
antonis19 Aug 15, 2025
193d794
add unit tests for spanRangeIndex
antonis19 Aug 15, 2025
60fc408
deprecate legacy SpanIdAt()
antonis19 Aug 15, 2025
f63b41d
Merge branch 'main' of github.com:erigontech/erigon into spans-index
antonis19 Aug 15, 2025
e44c189
Merge branch 'main' of github.com:erigontech/erigon into spans-index
antonis19 Aug 18, 2025
634c8ae
fix lint
antonis19 Aug 18, 2025
291e8b6
do not expose db
antonis19 Aug 18, 2025
e3b5da9
remove -v flag
antonis19 Aug 18, 2025
d91b497
remove DB() method
antonis19 Aug 18, 2025
b747191
use correct signature for NoopEntityStore.LastFrozenEntityId()
antonis19 Aug 18, 2025
466e4d5
remove context from RegisterObserver
antonis19 Aug 18, 2025
069698a
add context cancellation in test
antonis19 Aug 18, 2025
80298f6
check if .seg file is empty
antonis19 Aug 18, 2025
20b502e
remove context from NotifySync
antonis19 Aug 18, 2025
280b858
fix grammar
antonis19 Aug 18, 2025
424b929
wrap error
antonis19 Aug 18, 2025
28f2f82
optimize error handling
antonis19 Aug 18, 2025
59abff6
remove context from handlers
antonis19 Aug 18, 2025
362542e
inline heimdallStore creation
antonis19 Aug 18, 2025
717e3a3
extract buildSpanIndexFromSnapshots function
antonis19 Aug 18, 2025
cd91534
simplify LastEntityId()
antonis19 Aug 18, 2025
cf5fe9d
reinstate LastFrozenEntityId() into EntityStore
antonis19 Aug 18, 2025
ace4fe0
add t.Cleanup(heimdallStore.Close)
antonis19 Aug 18, 2025
3964b21
use t.Cleanup() instead of defer
antonis19 Aug 18, 2025
6353797
more t.Cleanup
antonis19 Aug 18, 2025
9bf82c5
close .idx file when helper returns
antonis19 Aug 18, 2025
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
2 changes: 0 additions & 2 deletions cmd/rpcdaemon/cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,6 @@ func RemoteServices(ctx context.Context, cfg *httpcfg.HttpCfg, logger log.Logger
return nil, nil, nil, nil, nil, nil, nil, ff, nil, nil, err
}

// NOTE: bor_* RPCs are not fully supported when using polygon.sync (https://github.com/erigontech/erigon/issues/11171)
// Skip the compatibility check, until we have a schema in erigon-lib
engine = bor.NewRo(cc, blockReader, logger)
} else if cc != nil && cc.Aura != nil {
consensusDB, err := kv2.New(kv.ConsensusDB, logger).Path(filepath.Join(cfg.DataDir, "aura")).Accede(true).Open(ctx)
Expand Down
58 changes: 32 additions & 26 deletions db/kv/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,19 +132,21 @@ const (
PendingEpoch = "DevPendingEpoch" // block_num_u64+block_hash->transition_proof

// BOR
BorTxLookup = "BlockBorTransactionLookup" // transaction_hash -> block_num_u64
BorEvents = "BorEvents" // event_id -> event_payload
BorEventNums = "BorEventNums" // block_num -> event_id (last event_id in that block)
BorEventProcessedBlocks = "BorEventProcessedBlocks" // block_num -> block_time, tracks processed blocks in the bridge, used for unwinds and restarts, gets pruned
BorEventTimes = "BorEventTimes" // timestamp -> event_id
BorSpans = "BorSpans" // span_id -> span (in JSON encoding)
BorMilestones = "BorMilestones" // milestone_id -> milestone (in JSON encoding)
BorMilestoneEnds = "BorMilestoneEnds" // start block_num -> milestone_id (first block of milestone)
BorCheckpoints = "BorCheckpoints" // checkpoint_id -> checkpoint (in JSON encoding)
BorCheckpointEnds = "BorCheckpointEnds" // start block_num -> checkpoint_id (first block of checkpoint)
BorProducerSelections = "BorProducerSelections" // span_id -> span selection with accumulated proposer priorities (in JSON encoding)
BorWitnesses = "BorWitnesses" // block_num_u64 + block_hash -> witness
BorWitnessSizes = "BorWitnessSizes" // block_num_u64 + block_hash -> witness size (uint64)
BorTxLookup = "BlockBorTransactionLookup" // transaction_hash -> block_num_u64
BorEvents = "BorEvents" // event_id -> event_payload
BorEventNums = "BorEventNums" // block_num -> event_id (last event_id in that block)
BorEventProcessedBlocks = "BorEventProcessedBlocks" // block_num -> block_time, tracks processed blocks in the bridge, used for unwinds and restarts, gets pruned
BorEventTimes = "BorEventTimes" // timestamp -> event_id
BorSpans = "BorSpans" // span_id -> span (in JSON encoding)
BorSpansIndex = "BorSpansIndex" // span.StartBlockNumber -> span.Id
BorMilestones = "BorMilestones" // milestone_id -> milestone (in JSON encoding)
BorMilestoneEnds = "BorMilestoneEnds" // start block_num -> milestone_id (first block of milestone)
BorCheckpoints = "BorCheckpoints" // checkpoint_id -> checkpoint (in JSON encoding)
BorCheckpointEnds = "BorCheckpointEnds" // start block_num -> checkpoint_id (first block of checkpoint)
BorProducerSelections = "BorProducerSelections" // span_id -> span selection with accumulated proposer priorities (in JSON encoding)
BorProducerSelectionsIndex = "BorProducerSelectionsIndex" // span.StartBlockNumber -> span.Id
BorWitnesses = "BorWitnesses" // block_num_u64 + block_hash -> witness
BorWitnessSizes = "BorWitnessSizes" // block_num_u64 + block_hash -> witness size (uint64)

// Downloader
BittorrentCompletion = "BittorrentCompletion"
Expand Down Expand Up @@ -349,11 +351,13 @@ var ChaindataTables = []string{
BorEventProcessedBlocks,
BorEventTimes,
BorSpans,
BorSpansIndex,
BorMilestones,
BorMilestoneEnds,
BorCheckpoints,
BorCheckpointEnds,
BorProducerSelections,
BorProducerSelectionsIndex,
BorWitnesses,
BorWitnessSizes,
TblAccountVals,
Expand Down Expand Up @@ -586,19 +590,21 @@ var AuRaTablesCfg = TableCfg{
}

var BorTablesCfg = TableCfg{
BorTxLookup: {Flags: DupSort},
BorEvents: {Flags: DupSort},
BorEventNums: {Flags: DupSort},
BorEventProcessedBlocks: {Flags: DupSort},
BorEventTimes: {Flags: DupSort},
BorSpans: {Flags: DupSort},
BorCheckpoints: {Flags: DupSort},
BorCheckpointEnds: {Flags: DupSort},
BorMilestones: {Flags: DupSort},
BorMilestoneEnds: {Flags: DupSort},
BorProducerSelections: {Flags: DupSort},
BorWitnesses: {Flags: DupSort},
BorWitnessSizes: {Flags: DupSort},
BorTxLookup: {Flags: DupSort},
BorEvents: {Flags: DupSort},
BorEventNums: {Flags: DupSort},
BorEventProcessedBlocks: {Flags: DupSort},
BorEventTimes: {Flags: DupSort},
BorSpans: {Flags: DupSort},
BorSpansIndex: {Flags: DupSort},
BorProducerSelectionsIndex: {Flags: DupSort},
BorCheckpoints: {Flags: DupSort},
BorCheckpointEnds: {Flags: DupSort},
BorMilestones: {Flags: DupSort},
BorMilestoneEnds: {Flags: DupSort},
BorProducerSelections: {Flags: DupSort},
BorWitnesses: {Flags: DupSort},
BorWitnessSizes: {Flags: DupSort},
}

var TxpoolTablesCfg = TableCfg{}
Expand Down
6 changes: 5 additions & 1 deletion polygon/heimdall/client_idle.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ func NewIdleClient(cfg buildercfg.MiningConfig) Client {

func (c *IdleClient) FetchLatestSpan(ctx context.Context) (*Span, error) {
return &Span{
StartBlock: 0,
EndBlock: 255,
ValidatorSet: ValidatorSet{
Validators: []*Validator{
{
Expand All @@ -55,7 +57,9 @@ func (c *IdleClient) FetchLatestSpan(ctx context.Context) (*Span, error) {

func (c *IdleClient) FetchSpan(ctx context.Context, spanID uint64) (*Span, error) {
return &Span{
Id: SpanId(spanID),
Id: SpanId(spanID),
StartBlock: 0,
EndBlock: 255,
ValidatorSet: ValidatorSet{
Validators: []*Validator{
{
Expand Down
25 changes: 16 additions & 9 deletions polygon/heimdall/entity_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ import (
)

var databaseTablesCfg = kv.TableCfg{
kv.BorCheckpoints: {},
kv.BorCheckpointEnds: {},
kv.BorMilestones: {},
kv.BorMilestoneEnds: {},
kv.BorSpans: {},
kv.BorProducerSelections: {},
kv.BorCheckpoints: {},
kv.BorCheckpointEnds: {},
kv.BorMilestones: {},
kv.BorMilestoneEnds: {},
kv.BorSpans: {},
kv.BorSpansIndex: {},
kv.BorProducerSelections: {},
kv.BorProducerSelectionsIndex: {},
}

//go:generate mockgen -typed=true -source=./entity_store.go -destination=./entity_store_mock.go -package=heimdall
Expand All @@ -46,7 +48,6 @@ type EntityStore[TEntity Entity] interface {
Close()

LastEntityId(ctx context.Context) (uint64, bool, error)
LastFrozenEntityId() uint64
LastEntity(ctx context.Context) (TEntity, bool, error)
Entity(ctx context.Context, id uint64) (TEntity, bool, error)
PutEntity(ctx context.Context, id uint64, entity TEntity) error
Expand All @@ -56,6 +57,8 @@ type EntityStore[TEntity Entity] interface {
DeleteToBlockNum(ctx context.Context, unwindPoint uint64, limit int) (int, error)
DeleteFromBlockNum(ctx context.Context, unwindPoint uint64) (int, error)

RangeIndex() RangeIndex

SnapType() snaptype.Type
}

Expand All @@ -72,7 +75,7 @@ func (NoopEntityStore[TEntity]) Close() {}
func (NoopEntityStore[TEntity]) LastEntityId(ctx context.Context) (uint64, bool, error) {
return 0, false, errors.New("noop")
}
func (NoopEntityStore[TEntity]) LastFrozenEntityId() uint64 { return 0 }
func (NoopEntityStore[TEntity]) LastFrozenEntityId() (uint64, bool, error) { return 0, false, nil }
func (NoopEntityStore[TEntity]) LastEntity(ctx context.Context) (TEntity, bool, error) {
var res TEntity
return res, false, errors.New("noop")
Expand Down Expand Up @@ -142,6 +145,10 @@ func (s *mdbxEntityStore[TEntity]) WithTx(tx kv.Tx) EntityStore[TEntity] {
return txEntityStore[TEntity]{s, tx}
}

func (s *mdbxEntityStore[TEntity]) RangeIndex() RangeIndex {
return s.blockNumToIdIndex
}

func (s *mdbxEntityStore[TEntity]) Close() {
}

Expand Down Expand Up @@ -222,7 +229,7 @@ func (s *mdbxEntityStore[TEntity]) PutEntity(ctx context.Context, id uint64, ent
defer tx.Rollback()

if err = (txEntityStore[TEntity]{s, tx}).PutEntity(ctx, id, entity); err != nil {
return nil
return err
}

return tx.Commit()
Expand Down
76 changes: 38 additions & 38 deletions polygon/heimdall/entity_store_mock.go

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

33 changes: 33 additions & 0 deletions polygon/heimdall/range_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

type RangeIndex interface {
Lookup(ctx context.Context, blockNum uint64) (uint64, bool, error)
Last(ctx context.Context) (uint64, bool, error)
}

type TransactionalRangeIndexer interface {
Expand Down Expand Up @@ -128,6 +129,18 @@ func (i *dbRangeIndex) Lookup(ctx context.Context, blockNum uint64) (uint64, boo
return id, ok, err
}

func (i *dbRangeIndex) Last(ctx context.Context) (uint64, bool, error) {
var lastKey uint64
var ok bool

err := i.db.View(ctx, func(tx kv.Tx) error {
var err error
lastKey, ok, err = i.WithTx(tx).Last(ctx)
return err
})
return lastKey, ok, err
}

func (i *txRangeIndex) Lookup(ctx context.Context, blockNum uint64) (uint64, bool, error) {
cursor, err := i.tx.Cursor(i.table)
if err != nil {
Expand All @@ -149,6 +162,26 @@ func (i *txRangeIndex) Lookup(ctx context.Context, blockNum uint64) (uint64, boo
return id, true, err
}

// last key in the index
func (i *txRangeIndex) Last(ctx context.Context) (uint64, bool, error) {
cursor, err := i.tx.Cursor(i.table)
if err != nil {
return 0, false, err
}
defer cursor.Close()
key, value, err := cursor.Last()
if err != nil {
return 0, false, err
}

if value == nil || key == nil {
return 0, false, nil
}

lastKey := rangeIndexKeyParse(key)
return lastKey, true, nil
}

// Lookup ids for the given range [blockFrom, blockTo). Return boolean which checks if the result is reliable to use, because
// heimdall data can be not published yet for [blockFrom, blockTo), in that case boolean OK will be false
func (i *dbRangeIndex) GetIDsBetween(ctx context.Context, blockFrom, blockTo uint64) ([]uint64, bool, error) {
Expand Down
2 changes: 1 addition & 1 deletion polygon/heimdall/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func (s *Service) Run(ctx context.Context) error {
}

s.RegisterSpanObserver(func(span *Span) {
s.spanBlockProducersTracker.ObserveSpanAsync(span)
s.spanBlockProducersTracker.ObserveSpanAsync(ctx, span)
})

milestoneObserver := s.RegisterMilestoneObserver(func(milestone *Milestone) {
Expand Down
8 changes: 3 additions & 5 deletions polygon/heimdall/service_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,8 @@ func NewMdbxStore(logger log.Logger, dataDir string, accede bool, roTxLimit int6
}

func newMdbxStore(db *polygoncommon.Database) *MdbxStore {
spanIndex := RangeIndexFunc(
func(ctx context.Context, blockNum uint64) (uint64, bool, error) {
return uint64(SpanIdAt(blockNum)), true, nil
})
spanIndex := NewSpanRangeIndex(db, kv.BorSpansIndex)
producerSelectionIndex := NewSpanRangeIndex(db, kv.BorProducerSelectionsIndex)

return &MdbxStore{
db: db,
Expand All @@ -57,7 +55,7 @@ func newMdbxStore(db *polygoncommon.Database) *MdbxStore {
spans: newMdbxEntityStore(
db, kv.BorSpans, Spans, generics.New[Span], spanIndex),
spanBlockProducerSelections: newMdbxEntityStore(
db, kv.BorProducerSelections, nil, generics.New[SpanBlockProducerSelection], spanIndex),
db, kv.BorProducerSelections, nil, generics.New[SpanBlockProducerSelection], producerSelectionIndex),
}
}

Expand Down
5 changes: 4 additions & 1 deletion polygon/heimdall/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,10 @@ func (suite *ServiceTestSuite) SetupSuite() {
})

suite.eg.Go(func() error {
return suite.service.Run(suite.ctx)
defer suite.cancel()
err := suite.service.Run(suite.ctx)
require.ErrorIs(suite.T(), err, context.Canceled)
return err
})

lastMilestone, ok, err := suite.service.SynchronizeMilestones(suite.ctx)
Expand Down
Loading
Loading