Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `forkable.WithFinalizedBlockNumMetric`: new option reporting, on the live path, the LIB number of the block that just became head. Takes a `forkable.Uint64Metric` interface so consumers can provide their own metric implementation.
- `DefaultMergedBlocksBundleSize`: new package variable (default `100`) controlling the number of blocks per merged-blocks file assumed by readers when no explicit size is given. Like `GetProtocolFirstStreamableBlock`, it is meant to be set once at process startup.
- `stream.WithMergedBlocksBundleSize`: new `stream` option to set the merged-blocks bundle size for a single stream (overrides the process-wide default; used by substreams tier2 which serves multiple chains at once).
- `FileSource` now fails fast with a clear error when a merged-blocks file contains a block beyond the configured bundle size (store files bigger than the configured size).
Expand Down
4 changes: 4 additions & 0 deletions forkable/forkable.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type Forkable struct {
metricsHeadBlockNum *dmetrics.HeadBlockNum
metricsHeadTimeDrift *dmetrics.HeadTimeDrift
metricsRelativeBlockDrift *dmetrics.HeadBlockRelativeTime
metricsFinalizedBlockNum Uint64Metric

lastLongestChain []*Block
}
Expand Down Expand Up @@ -781,6 +782,9 @@ func (p *Forkable) ProcessBlock(blk *pbbstream.Block, obj any) error {
if p.metricsRelativeBlockDrift != nil {
p.metricsRelativeBlockDrift.SetLastBlock(blk.Time())
}
if p.metricsFinalizedBlockNum != nil {
p.metricsFinalizedBlockNum.SetUint64(blk.LibNum)
}
}

if p.lastBlockSent == nil {
Expand Down
40 changes: 40 additions & 0 deletions forkable/metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package forkable

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

type testUint64Metric struct {
value uint64
set bool
}

func (t *testUint64Metric) SetUint64(value uint64) {
t.value = value
t.set = true
}

func TestForkable_FinalizedBlockNumMetric(t *testing.T) {
finalized := &testUint64Metric{}

p := New(&testForkableSink{}, WithFinalizedBlockNumMetric(finalized), WithExclusiveLIB(bRef("00000003a")))
p.SetLiveMetrics()

require.NoError(t, p.ProcessBlock(tb("00000004a", "00000003a", 3), nil))
assert.Equal(t, uint64(3), finalized.value)

require.NoError(t, p.ProcessBlock(tb("00000005a", "00000004a", 4), nil))
assert.Equal(t, uint64(4), finalized.value)
}

func TestForkable_FinalizedBlockNumMetricNotSetWithoutLiveMetrics(t *testing.T) {
finalized := &testUint64Metric{}

p := New(&testForkableSink{}, WithFinalizedBlockNumMetric(finalized), WithExclusiveLIB(bRef("00000003a")))

require.NoError(t, p.ProcessBlock(tb("00000004a", "00000003a", 3), nil))
assert.False(t, finalized.set, "finalized block num metric must only be updated on the live path")
}
16 changes: 16 additions & 0 deletions forkable/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ func WithMetrics(
}
}

// Uint64Metric is the minimal interface a metric must satisfy to be updated by the
// forkable. It exists so that consumers can provide their own metric implementation
// without bstream having to depend on it.
type Uint64Metric interface {
SetUint64(value uint64)
}

// WithFinalizedBlockNumMetric reports, on the live path, the LIB number of the block
// that just became head. Combined with the head block number metric, it tells how far
// behind finality the head is.
func WithFinalizedBlockNumMetric(finalizedBlockNum Uint64Metric) Option {
return func(f *Forkable) {
f.metricsFinalizedBlockNum = finalizedBlockNum
}
}

func WithWarnOnUnlinkableBlocks(count int) Option {
return func(f *Forkable) {
f.warnOnUnlinkableBlocksCount = count
Expand Down
Loading