Skip to content

feat(evm): endorsers return the delta, the initiator stops building one - #2229

Open
atharrva01 wants to merge 3 commits into
LFDT-Panurus:feature/evm-network-driverfrom
atharrva01:evm-initiator-delta-from-response
Open

feat(evm): endorsers return the delta, the initiator stops building one#2229
atharrva01 wants to merge 3 commits into
LFDT-Panurus:feature/evm-network-driverfrom
atharrva01:evm-initiator-delta-from-response

Conversation

@atharrva01

@atharrva01 atharrva01 commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Stacked on #2228 (the diff here will shrink to just the endorsement commit once that merges).

The initiator built its own StateDelta before contacting any endorser, running the request through
the same DeltaFactory as the responder. That is validation work, and validating is exactly what this
flow delegates to endorsers, so every client repeated what N endorsers were already doing, plus a
getToken read per input.

It also cost liveness in a way that was hard to diagnose. The delta covers the public parameters hash
and version, and the digest covers the whole struct, so an initiator reading parameters on the other
side of an update from its endorsers computed a different digest and discarded every signature as an
unknown signer. Its ledger read had the same shape: a node lagging behind failed to build a delta at
all and never contacted an endorser, for a request every endorser would have signed.

It bought no security property either way. The contract only checks that a threshold of registered
endorsers signed the digest, so a quorum that wanted to apply something else would never need the
initiator's cooperation.

EndorseResponse now carries the delta the endorser built, next to its signature, the way a Fabric
proposal response carries the RWSet. The initiator binds each returned delta to the anchor it asked
about, checks the StateDelta invariants, recovers the signature over that delta's own digest, and
groups by delta so one endorser translating differently is outvoted instead of failing the whole
transaction. A shortfall where more than one delta was seen reports that explicitly, since that is a
determinism bug in the translator, not endorsers being unavailable.

Verified: unit tests and -race across the module, the Week 4 gate (drives the real initiator and
responders over in-memory sessions, pinned to the committed Solidity fixture) unchanged, all 55 forge
tests, and the fungible integration suite against real Besu, twice.

The v0.17.0 upgrade updated the tracked modules and missed this one, so
nothing under x/token/services/network/evm builds until go.mod is tidy.

Signed-off-by: atharrva01 <atharvaborade568@gmail.com>
LFDT-Panurus#2180 enabled containedctx and fixed the ttx occurrence. The evm module is a
separate Go module and was not linted in that pass, so make lint has been
failing on it since.

Neither field can be dropped. Ledger.ctx exists because driver.GetStateFnc
passes no context to GetState, and fakeContext.ctx exists because it
implements view.Context, whose Context() method has to return one.

Signed-off-by: atharrva01 <atharvaborade568@gmail.com>
The initiator ran the full validator on every request through the same
DeltaFactory as the responder, to get a digest to verify signatures against
and a delta to put in the transaction. That is the work this flow delegates,
and it bought nothing: the contract's rule is that a threshold of registered
endorsers signed the digest, so a quorum wanting to apply something else
would never need the initiator.

It did cost something. The delta covers the public parameters hash and
version, so an initiator reading parameters on the other side of an update
from its endorsers computed a different digest and discarded every signature
as an unknown signer. Its ledger read had the same shape: a lagging node
failed to build a delta and never contacted an endorser at all.

EndorseResponse now carries the delta the endorser signed, the way a Fabric
proposal response carries the RWSet. The initiator binds each delta to the
anchor it asked about, checks the invariants, recovers the signature over
that delta's digest, and groups by delta so a divergent endorser is outvoted
rather than fatal. A shortfall where more than one delta was seen reports
ErrDivergentDeltas next to ErrInsufficientEndorsements, since that is a
determinism failure and not an availability one.

Raised by Angelo in the sync of 2026-08-14.

Signed-off-by: atharrva01 <atharvaborade568@gmail.com>
atharrva01 added a commit to atharrva01/panurus that referenced this pull request Aug 14, 2026
The initiator no longer builds a StateDelta (LFDT-Panurus#2229): only the endorser's
DeltaFactory does, and that is where the aligned metadata lists actually
come from. "The driver" was accurate before that change and misleading
after it.

Signed-off-by: atharrva01 <atharvaborade568@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant