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
57 changes: 57 additions & 0 deletions block/internal/syncing/da_retriever_tracing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package syncing

import (
"context"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"

"github.com/evstack/ev-node/block/internal/common"
)

var _ DARetriever = (*tracedDARetriever)(nil)

// tracedDARetriever wraps a DARetriever with OpenTelemetry tracing.
type tracedDARetriever struct {
inner DARetriever
tracer trace.Tracer
}

// WithTracingDARetriever wraps a DARetriever with OpenTelemetry tracing.
func WithTracingDARetriever(inner DARetriever) DARetriever {
return &tracedDARetriever{
inner: inner,
tracer: otel.Tracer("ev-node/da-retriever"),
}
}

func (t *tracedDARetriever) RetrieveFromDA(ctx context.Context, daHeight uint64) ([]common.DAHeightEvent, error) {
ctx, span := t.tracer.Start(ctx, "DARetriever.RetrieveFromDA",
trace.WithAttributes(
attribute.Int64("da.height", int64(daHeight)),
),
)
defer span.End()

events, err := t.inner.RetrieveFromDA(ctx, daHeight)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return events, err
}

span.SetAttributes(attribute.Int("event.count", len(events)))

// add block heights from events
if len(events) > 0 {
heights := make([]int64, len(events))
for i, event := range events {
heights[i] = int64(event.Header.Height())
}
span.SetAttributes(attribute.Int64Slice("block.heights", heights))
}

return events, nil
}
123 changes: 123 additions & 0 deletions block/internal/syncing/da_retriever_tracing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package syncing

import (
"context"
"errors"
"testing"

"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/codes"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"

"github.com/evstack/ev-node/block/internal/common"
"github.com/evstack/ev-node/pkg/telemetry/testutil"
"github.com/evstack/ev-node/types"
)

type mockDARetriever struct {
retrieveFromDAFn func(ctx context.Context, daHeight uint64) ([]common.DAHeightEvent, error)
}

func (m *mockDARetriever) RetrieveFromDA(ctx context.Context, daHeight uint64) ([]common.DAHeightEvent, error) {
if m.retrieveFromDAFn != nil {
return m.retrieveFromDAFn(ctx, daHeight)
}
return nil, nil
}

func setupDARetrieverTrace(t *testing.T, inner DARetriever) (DARetriever, *tracetest.SpanRecorder) {
t.Helper()
sr := tracetest.NewSpanRecorder()
tp := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr))
t.Cleanup(func() { _ = tp.Shutdown(context.Background()) })
otel.SetTracerProvider(tp)
return WithTracingDARetriever(inner), sr
}

func TestTracedDARetriever_RetrieveFromDA_Success(t *testing.T) {
mock := &mockDARetriever{
retrieveFromDAFn: func(ctx context.Context, daHeight uint64) ([]common.DAHeightEvent, error) {
return []common.DAHeightEvent{
{
Header: &types.SignedHeader{
Header: types.Header{
BaseHeader: types.BaseHeader{Height: 100},
},
},
DaHeight: daHeight,
Source: common.SourceDA,
},
{
Header: &types.SignedHeader{
Header: types.Header{
BaseHeader: types.BaseHeader{Height: 101},
},
},
DaHeight: daHeight,
Source: common.SourceDA,
},
}, nil
},
}
retriever, sr := setupDARetrieverTrace(t, mock)
ctx := context.Background()

events, err := retriever.RetrieveFromDA(ctx, 50)
require.NoError(t, err)
require.Len(t, events, 2)

spans := sr.Ended()
require.Len(t, spans, 1)
span := spans[0]
require.Equal(t, "DARetriever.RetrieveFromDA", span.Name())
require.Equal(t, codes.Unset, span.Status().Code)

attrs := span.Attributes()
testutil.RequireAttribute(t, attrs, "da.height", int64(50))
testutil.RequireAttribute(t, attrs, "event.count", 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test is great for verifying the success case. To make it more comprehensive, it would be beneficial to also assert that the block.heights attribute is correctly set on the span when events are returned.

The testutil.RequireAttribute helper doesn't seem to support slice attributes, so you might need to perform this check manually. Here's a suggestion to add this verification:

Suggested change
testutil.RequireAttribute(t, attrs, "event.count", 2)
testutil.RequireAttribute(t, attrs, "event.count", 2)
// Check for block.heights attribute
var heightsValue attribute.Value
for _, attr := range attrs {
if attr.Key == "block.heights" {
heightsValue = attr.Value
break
}
}
require.NotNil(t, heightsValue, "attribute 'block.heights' not found")
require.Equal(t, attribute.INT64SLICE, heightsValue.Type())
require.Equal(t, []int64{100, 101}, heightsValue.AsInt64Slice())

}

func TestTracedDARetriever_RetrieveFromDA_NoEvents(t *testing.T) {
mock := &mockDARetriever{
retrieveFromDAFn: func(ctx context.Context, daHeight uint64) ([]common.DAHeightEvent, error) {
return []common.DAHeightEvent{}, nil
},
}
retriever, sr := setupDARetrieverTrace(t, mock)
ctx := context.Background()

events, err := retriever.RetrieveFromDA(ctx, 50)
require.NoError(t, err)
require.Empty(t, events)

spans := sr.Ended()
require.Len(t, spans, 1)
span := spans[0]
require.Equal(t, codes.Unset, span.Status().Code)

attrs := span.Attributes()
testutil.RequireAttribute(t, attrs, "event.count", 0)
}

func TestTracedDARetriever_RetrieveFromDA_Error(t *testing.T) {
expectedErr := errors.New("DA retrieval failed")
mock := &mockDARetriever{
retrieveFromDAFn: func(ctx context.Context, daHeight uint64) ([]common.DAHeightEvent, error) {
return nil, expectedErr
},
}
retriever, sr := setupDARetrieverTrace(t, mock)
ctx := context.Background()

_, err := retriever.RetrieveFromDA(ctx, 50)
require.Error(t, err)
require.Equal(t, expectedErr, err)

spans := sr.Ended()
require.Len(t, spans, 1)
span := spans[0]
require.Equal(t, codes.Error, span.Status().Code)
require.Equal(t, expectedErr.Error(), span.Status().Description)
}
3 changes: 3 additions & 0 deletions block/internal/syncing/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ func (s *Syncer) Start(ctx context.Context) error {

// Initialize handlers
s.daRetriever = NewDARetriever(s.daClient, s.cache, s.genesis, s.logger)
if s.config.Instrumentation.IsTracingEnabled() {
s.daRetriever = WithTracingDARetriever(s.daRetriever)
}
s.fiRetriever = da.NewForcedInclusionRetriever(s.daClient, s.logger, s.config, s.genesis.DAStartHeight, s.genesis.DAEpochForcedInclusion)
s.p2pHandler = NewP2PHandler(s.headerStore.Store(), s.dataStore.Store(), s.cache, s.genesis, s.logger)
if currentHeight, err := s.store.Height(s.ctx); err != nil {
Expand Down
7 changes: 4 additions & 3 deletions test/docker-e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ require (
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/bcp-innovations/hyperlane-cosmos v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.20.0 // indirect
github.com/bytedance/sonic v1.13.1 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect
github.com/bytedance/gopkg v0.1.3 // indirect
github.com/bytedance/sonic v1.14.2 // indirect
github.com/bytedance/sonic/loader v0.4.0 // indirect
github.com/celestiaorg/go-square/v3 v3.0.2 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/consensys/gnark-crypto v0.18.1 // indirect
github.com/containerd/continuity v0.4.5 // indirect
github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect
Expand Down
20 changes: 9 additions & 11 deletions test/docker-e2e/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,12 @@ github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/
github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE=
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g=
github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=
github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=
github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=
github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/celestiaorg/celestia-core v0.39.4 h1:h0WaG8KsP0JyiAVhHipoIgvBP0CYLG/9whUccy1lDlY=
github.com/celestiaorg/celestia-core v0.39.4/go.mod h1:t7cSYwLFmpz5RjIBpC3QjpbRoa+RfQ0ULdh+LciKuq8=
Expand Down Expand Up @@ -162,9 +163,8 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
Expand Down Expand Up @@ -561,12 +561,10 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/klauspost/reedsolomon v1.12.5 h1:4cJuyH926If33BeDgiZpI5OU0pE+wUHZvMSyNGqN73Y=
github.com/klauspost/reedsolomon v1.12.5/go.mod h1:LkXRjLYGM8K/iQfujYnaPeDmhZLqkrGUyG9p7zs5L68=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
Expand Down Expand Up @@ -853,6 +851,7 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
Expand Down Expand Up @@ -1233,7 +1232,6 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y=
nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=
pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
Expand Down