Skip to content

[Perf] Cache secp256k1_mpt_get_generator_vector result per-issuance instead of recomputing per-transaction #119

@tesseract-ripple

Description

@tesseract-ripple

Severity: Performance; low priority but well-scoped.
Source: Performance posture report (internal draft,
2026-06-08), Recommendation #2.

Problem

secp256k1_mpt_get_generator_vector accounts for ~4% of CPU
during the dominant ConfidentialMPTSend::preclaim path on
the 5-TPS ConfidentialSendOnly workload, per the recent eBPF
profile. The generator vectors G_vec and H_vec are
deterministically derived via HKDF from a label and the
issuance parameters; they are constant for the lifetime of
an issuance
(or, since the labels are "BP_G" / "BP_H",
constant for the lifetime of the protocol — they don't even
depend on issuance state).

Currently rippled recomputes them per verify_agg call,
which is once per ConfidentialMPTSend validated.

Recommended fix

Cache the vector on the rippled side. Two reasonable scopes:

  1. Per-process cache (cleanest). Compute once at startup
    (or first use); reuse for the lifetime of the rippled
    process. Since G_vec/H_vec are protocol-constant (HKDF
    label "BP_G" / "BP_H", fixed N=64×max_m), a single
    process-wide cache suffices.

  2. Per-issuance cache (more general). If the
    instantiation ever becomes issuance-specific, switch to
    a map keyed by issuance ID.

Option 1 is enough for the current protocol; option 2 is the
fallback if the API evolves.

Scope

This is a rippled-side change (caller-side caching). The
mpt-crypto API itself doesn't need to change; the function
can stay pure and the caller manages the cache.

Alternative (mpt-crypto side): add a *_cached variant
of the wrapper that memoizes internally with a thread-safe
cache. Probably overkill — the rippled caller is in a much
better position to manage cache lifetime.

Expected impact

~4% of CPU saved per verifySendProofs call. Modest on its
own, additive on top of the MSM-track speedup from #104 /
#105.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions