kaysentinel / raw /transcript /README.md
karanjahpn
Add missing transcript README.md from previous commit
1b950d4
|
Raw
History Blame Contribute Delete
4.87 kB

Transcript rewrite + Multiplexer + Differential Validation

This replaces the earlier tagged-union raw/transcript/transcript.go (nativeEvent/tracePayload + StreamProjection + deterministic hash) with a flat, single-struct RawEvent design, per an explicit decision to trade away the deterministic hash and immutable-projection guarantees for lower per-event allocation cost. If you want the hash/projection version back, it's recoverable from git history (commit ed2bd8a).

What was extended beyond the pasted draft

The pasted RawEvent/EventKind only covered TxStart/TxEnd/Enter/Exit/ Fault/BalanceChange, with only AppendEnter/AppendExit actually implemented. That's not enough to capture what EMES-V1 (docs/emes_profile.md) needs to reconstruct an SSR -- nonce, code, and storage mutations, self-destruct, and account creation were missing entirely. This version adds KindNonceChange, KindCodeChange, KindStorageChange, KindSelfDestruct, KindAccountCreated and their Append* methods, following the same flat-struct design.

One inconsistency kept rather than silently fixed: the original design's stated goal was eliminating string allocations, but RawEvent.ErrType is still a string. Noted in the source rather than either silently dropping error type info or silently ignoring the stated goal.

Bugs found and fixed (multiplexer/broadcast.go)

Checked against the real core/tracing/hooks.go (not assumed), three signature mismatches:

  1. OnTxStart was missing the from common.Address parameter TxStartHook requires, and used a value tracing.VMContext instead of the required pointer *tracing.VMContext.
  2. OnEnter's value parameter was typed *uint256.Int; EnterHook requires *big.Int.
  3. OnFault didn't match FaultHook at all -- the real signature is func(pc uint64, op byte, gas, cost uint64, scope OpContext, depth int, err error), missing the scope OpContext parameter entirely and in a different parameter order (pasted had depth first; the real hook has it second-to-last).

Also: the pasted BroadcastSink.WiringToGethHooks() only implemented OnEnter and left the rest as a comment ("mirror this exact wrapper structure"). All five remaining hooks (OnTxStart, OnTxEnd, OnExit, OnFault, OnBalanceChange) are now actually implemented, not left as a placeholder, and the method was renamed Hooks() for consistency with tracer.Tracer.Hooks() elsewhere in this repo.

Other fixes (validation/normalizer.go, validation/engine.go)

  • normalizer.go imported kay-sentinel/raw/transcript (hyphenated module name); this repo's actual module is kaysentinel (see go.mod). Fixed to kaysentinel/raw/transcript.
  • engine.go's comparison method was unexported (compareSemanticFields), making it uncallable from outside package validation -- presumably an oversight for something meant to be a differential-testing API. Exported as CompareSemanticFields.
  • Noted, not fixed: SemanticEvent only carries the fields shown (Sequence/Opcode/Depth/From/To/Value/GasUsed/Reverted/ErrType), so a differential check can't currently catch a mismatch in, say, a specific storage slot's before/after value -- only that some event of a given Kind/Sequence differs on the fields that do exist.

Verification performed

go build ./raw/... ./validation/... ./multiplexer/...
go vet   ./raw/... ./validation/... ./multiplexer/...

Both clean. Beyond that, an actual end-to-end run:

  • Registered two HookSinks on a BroadcastSink: one that records into an ExecutionTranscript, one that deliberately panics on OnEnter.
  • Drove a fake transaction through bus.Hooks(). Confirmed: the panicking sink's panic was caught, recorded as a PanicReport naming the right sink and callback, and did not propagate (strictMode=false) -- and confirmed it was evicted: a second round of hook calls produced no new panic and no new report, proving eviction actually removes the sink rather than just logging and continuing to call it.
  • The recording sink's transcript was fed through EventNormalizer and DifferentialValidator: comparing a stream against itself matched on every event, and a deliberately injected field mismatch (Depth: 99) was correctly caught and reported with the expected tabular diff format.

Status

Compiles, vets clean, and the panic-isolation + differential-validation behavior was actually exercised, not just compiled. Not yet wired into tracer.Tracer from the earlier EMES-V1 work -- this and that tracer are currently two separate, non-integrated ways of collecting events from Geth's tracing.Hooks. Deciding whether to merge them or keep both for different purposes (e.g. this one for a legacy-vs-new differential period) is an open decision, not resolved here.