#pragma once /** Utilities for trace context propagation across nodes. Provides serialization/deserialization of OTel trace context to/from Protocol Buffer TraceContext messages (P2P cross-node propagation). Wired into the P2P message flow via PropagationHelpers.h for TMTransaction, TMProposeSet, and TMValidation messages. Only compiled when XRPL_ENABLE_TELEMETRY is defined. @see PropagationHelpers.h (high-level inject helpers), TxTracing.h (transaction receive-side extraction), ConsensusReceiveTracing.h (proposal/validation receive-side). */ #ifdef XRPL_ENABLE_TELEMETRY #include #include #include #include #include #include #include #include namespace xrpl { namespace telemetry { /** Extract OTel context from a protobuf TraceContext message. @param proto The protobuf TraceContext received from a peer. @return An OTel Context with the extracted parent span, or an empty context if the protobuf fields are missing or invalid. */ inline opentelemetry::context::Context extractFromProtobuf(protocol::TraceContext const& proto) { namespace trace = opentelemetry::trace; if (!proto.has_trace_id() || proto.trace_id().size() != 16 || !proto.has_span_id() || proto.span_id().size() != 8) { return opentelemetry::context::Context{}; } auto const* rawTraceId = reinterpret_cast(proto.trace_id().data()); auto const* rawSpanId = reinterpret_cast(proto.span_id().data()); trace::TraceId const traceId( opentelemetry::nostd::span(rawTraceId, 16)); trace::SpanId const spanId(opentelemetry::nostd::span(rawSpanId, 8)); trace::TraceFlags const flags( proto.has_trace_flags() ? static_cast(proto.trace_flags()) : static_cast(0)); trace::SpanContext const spanCtx(traceId, spanId, flags, /* remote = */ true); return opentelemetry::context::Context{}.SetValue( trace::kSpanKey, opentelemetry::nostd::shared_ptr(new trace::DefaultSpan(spanCtx))); } /** Inject the current span's trace context into a protobuf TraceContext. @param ctx The OTel context containing the span to propagate. @param proto The protobuf TraceContext to populate. */ inline void injectToProtobuf(opentelemetry::context::Context const& ctx, protocol::TraceContext& proto) { namespace trace = opentelemetry::trace; auto const span = trace::GetSpan(ctx); if (!span) return; auto const& spanCtx = span->GetContext(); if (!spanCtx.IsValid()) return; // Serialize trace_id (16 bytes) auto const& traceId = spanCtx.trace_id(); proto.set_trace_id(traceId.Id().data(), trace::TraceId::kSize); // Serialize span_id (8 bytes) auto const& spanId = spanCtx.span_id(); proto.set_span_id(spanId.Id().data(), trace::SpanId::kSize); // Serialize flags proto.set_trace_flags(spanCtx.trace_flags().flags()); } } // namespace telemetry } // namespace xrpl #endif // XRPL_ENABLE_TELEMETRY