mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
Add consensus.accept.apply span with ledger close time attributes
Add a new trace span in doAccept() capturing ledger close time details: - xrpl.consensus.close_time: agreed-upon close time (epoch seconds) - xrpl.consensus.close_time_correct: whether validators converged (per avCT_CONSENSUS_PCT = 75% threshold) - xrpl.consensus.close_resolution_ms: time rounding granularity - xrpl.consensus.state: "finished" or "moved_on" (consensus failure) - xrpl.consensus.proposing: whether this node was proposing Update Tempo datasource with close time filters, plan docs with new span inventory, and add test coverage for the attribute pattern. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -152,11 +152,22 @@ gantt
|
||||
|
||||
**Total Effort**: 11 days
|
||||
|
||||
### Spans Produced
|
||||
|
||||
| Span Name | Location | Attributes |
|
||||
| --------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `consensus.proposal.send` | `RCLConsensus.cpp:177` | `xrpl.consensus.round` |
|
||||
| `consensus.ledger_close` | `RCLConsensus.cpp:282` | `xrpl.consensus.ledger.seq`, `xrpl.consensus.mode` |
|
||||
| `consensus.accept` | `RCLConsensus.cpp:395` | `xrpl.consensus.proposers`, `xrpl.consensus.round_time_ms` |
|
||||
| `consensus.accept.apply` | `RCLConsensus.cpp:453` | `xrpl.consensus.close_time`, `close_time_correct`, `close_resolution_ms`, `state`, `proposing`, `round_time_ms`, `ledger.seq` |
|
||||
| `consensus.validation.send` | `RCLConsensus.cpp:753` | `xrpl.consensus.proposing` |
|
||||
|
||||
### Exit Criteria
|
||||
|
||||
- [x] Complete consensus round traces
|
||||
- [x] Phase transitions visible
|
||||
- [x] Proposals and validations traced
|
||||
- [x] Close time agreement tracked (per `avCT_CONSENSUS_PCT`)
|
||||
- [x] No impact on consensus timing
|
||||
- [ ] Multi-validator test network validated
|
||||
|
||||
|
||||
@@ -213,9 +213,32 @@
|
||||
|
||||
**Parallel work**: Tasks 4.2, 4.3, and 4.4 can run in parallel after 4.1 is complete. Task 4.5 depends on all three. Task 4.6 depends on 4.2 and Phase 3.
|
||||
|
||||
### Implemented Spans
|
||||
|
||||
| Span Name | Method | Key Attributes |
|
||||
| --------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `consensus.proposal.send` | `Adaptor::propose` | `xrpl.consensus.round` |
|
||||
| `consensus.ledger_close` | `Adaptor::onClose` | `xrpl.consensus.ledger.seq`, `xrpl.consensus.mode` |
|
||||
| `consensus.accept` | `Adaptor::onAccept` | `xrpl.consensus.proposers`, `xrpl.consensus.round_time_ms` |
|
||||
| `consensus.accept.apply` | `Adaptor::doAccept` | `xrpl.consensus.close_time`, `close_time_correct`, `close_resolution_ms`, `state`, `proposing`, `round_time_ms`, `ledger.seq` |
|
||||
| `consensus.validation.send` | `Adaptor::onAccept` (via validate) | `xrpl.consensus.proposing` |
|
||||
|
||||
#### Close Time Attributes (consensus.accept.apply)
|
||||
|
||||
The `consensus.accept.apply` span captures ledger close time agreement details
|
||||
driven by `avCT_CONSENSUS_PCT` (75% validator agreement threshold):
|
||||
|
||||
- **`xrpl.consensus.close_time`** — Agreed-upon ledger close time (epoch seconds). When validators disagree (`consensusCloseTime == epoch`), this is synthetically set to `prevCloseTime + 1s`.
|
||||
- **`xrpl.consensus.close_time_correct`** — `true` if validators reached agreement, `false` if they "agreed to disagree" (close time forced to prev+1s).
|
||||
- **`xrpl.consensus.close_resolution_ms`** — Rounding granularity for close time (starts at 30s, decreases as ledger interval stabilizes).
|
||||
- **`xrpl.consensus.state`** — `"finished"` (normal) or `"moved_on"` (consensus failed, adopted best available).
|
||||
- **`xrpl.consensus.proposing`** — Whether this node was proposing.
|
||||
- **`xrpl.consensus.round_time_ms`** — Total consensus round duration.
|
||||
|
||||
**Exit Criteria** (from [06-implementation-phases.md §6.11.4](./06-implementation-phases.md)):
|
||||
|
||||
- [ ] Complete consensus round traces
|
||||
- [ ] Phase transitions visible
|
||||
- [ ] Proposals and validations traced
|
||||
- [ ] Close time agreement tracked (per `avCT_CONSENSUS_PCT`)
|
||||
- [ ] No impact on consensus timing
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# Phase 1b (infra): Base filters — node identity, service, span name, status.
|
||||
# Phase 2 (RPC): RPC command, status, role filters.
|
||||
# Phase 3 (TX): Transaction hash, local/peer origin, status.
|
||||
# Phase 4 (Cons): Consensus mode, round, ledger sequence.
|
||||
# Phase 4 (Cons): Consensus mode, round, ledger sequence, close time.
|
||||
|
||||
apiVersion: 1
|
||||
|
||||
@@ -130,3 +130,18 @@ datasources:
|
||||
operator: "="
|
||||
scope: span
|
||||
type: static
|
||||
- id: consensus-close-time-correct
|
||||
tag: xrpl.consensus.close_time_correct
|
||||
operator: "="
|
||||
scope: span
|
||||
type: dynamic
|
||||
- id: consensus-state
|
||||
tag: xrpl.consensus.state
|
||||
operator: "="
|
||||
scope: span
|
||||
type: dynamic
|
||||
- id: consensus-close-resolution
|
||||
tag: xrpl.consensus.close_resolution_ms
|
||||
operator: "="
|
||||
scope: span
|
||||
type: dynamic
|
||||
|
||||
@@ -82,6 +82,35 @@ TEST(TracingMacros, conditional_guards)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TracingMacros, consensus_close_time_attributes)
|
||||
{
|
||||
// Verify the consensus.accept.apply attribute pattern compiles and
|
||||
// doesn't crash with NullTelemetry. Mirrors the real instrumentation
|
||||
// in RCLConsensus::Adaptor::doAccept().
|
||||
telemetry::Telemetry::Setup setup;
|
||||
setup.enabled = false;
|
||||
beast::Journal::Sink& sink = beast::Journal::getNullSink();
|
||||
beast::Journal j(sink);
|
||||
auto tel = telemetry::make_Telemetry(setup, j);
|
||||
|
||||
{
|
||||
XRPL_TRACE_CONSENSUS(*tel, "consensus.accept.apply");
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.ledger.seq", static_cast<int64_t>(42));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.close_time", static_cast<int64_t>(780000000));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.close_time_correct", true);
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.close_resolution_ms", static_cast<int64_t>(30000));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.state", std::string("finished"));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.proposing", true);
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.round_time_ms", static_cast<int64_t>(3500));
|
||||
}
|
||||
// close_time_correct=false path (agreed to disagree)
|
||||
{
|
||||
XRPL_TRACE_CONSENSUS(*tel, "consensus.accept.apply");
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.close_time_correct", false);
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.state", std::string("moved_on"));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XRPL_ENABLE_TELEMETRY
|
||||
|
||||
TEST(TracingMacros, span_guard_raii)
|
||||
|
||||
@@ -443,6 +443,27 @@ RCLConsensus::Adaptor::doAccept(
|
||||
closeTimeCorrect = true;
|
||||
}
|
||||
|
||||
// Trace the ledger application phase with close time details.
|
||||
// This span runs on the jtACCEPT job queue thread (posted by onAccept),
|
||||
// separate from the consensus.accept span which fires synchronously in
|
||||
// onAccept. It captures the agreed-upon close time, whether validators
|
||||
// converged on it (per avCT_CONSENSUS_PCT), and the consensus outcome.
|
||||
XRPL_TRACE_CONSENSUS(app_.getTelemetry(), "consensus.accept.apply");
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.ledger.seq", static_cast<int64_t>(prevLedger.seq() + 1));
|
||||
XRPL_TRACE_SET_ATTR(
|
||||
"xrpl.consensus.close_time",
|
||||
static_cast<int64_t>(consensusCloseTime.time_since_epoch().count()));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.close_time_correct", closeTimeCorrect);
|
||||
XRPL_TRACE_SET_ATTR(
|
||||
"xrpl.consensus.close_resolution_ms",
|
||||
static_cast<int64_t>(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(closeResolution).count()));
|
||||
XRPL_TRACE_SET_ATTR(
|
||||
"xrpl.consensus.state", std::string(consensusFail ? "moved_on" : "finished"));
|
||||
XRPL_TRACE_SET_ATTR("xrpl.consensus.proposing", proposing);
|
||||
XRPL_TRACE_SET_ATTR(
|
||||
"xrpl.consensus.round_time_ms", static_cast<int64_t>(result.roundTime.read().count()));
|
||||
|
||||
JLOG(j_.debug()) << "Report: Prop=" << (proposing ? "yes" : "no")
|
||||
<< " val=" << (validating_ ? "yes" : "no")
|
||||
<< " corLCL=" << (haveCorrectLCL ? "yes" : "no")
|
||||
|
||||
Reference in New Issue
Block a user