I've benchmarked encoding and decoding of signed-blinded-beacon-block payloads with SSZ vs JSON: flashbots/go-boost-utils#50
SSZ seems 40-50x faster:
BenchmarkJSONvsSSZEncoding/Encode_JSON-10 18561 62939 ns/op 50754 B/op 274 allocs/op
BenchmarkJSONvsSSZEncoding/Encode_SSZ-10 855457 1368 ns/op 9472 B/op 1 allocs/op
BenchmarkJSONvsSSZEncoding/Decode_JSON-10 7621 153292 ns/op 30433 B/op 613 allocs/op
BenchmarkJSONvsSSZEncoding/Decode_SSZ-10 276904 3968 ns/op 10116 B/op 152 allocs/op
This would be particularly relevant for getPayload calls, because of the payload size and timing constraints (but perhaps also interesting for getHeader and registerValidator).
Each getPayload call currently does 8 JSON encoding and decoding steps (if we include mev-boost in the mix):
- BN encodes the
getPayload request body (signed blinded beacon block)
- mev-boost decodes the
getPayload request body
- mev-boost encodes the
getPayload request body
- relay decodes the
getPayload request body
- relay encodes the
getPayload response body (execution payload)
- mev-boost decodes the
getPayload response body
- mev-boost encodes the
getPayload response body
- BN decodes the
getPayload response body
Considering 20-40ms per coding on average, that's up to 200-300ms JSON latency (or more).
Sending the data SSZ encoded could reliably shave 200-250ms off each getPayload roundtrip.
I propose we add SSZ encoded payloads as first-class citizens.
Questions:
- How can this work with relays that didn't (yet) support SSZ encoded payloads? 🤔
- How can we make this backward compatible, so it will also work if a given relay didn't yet upgrade?
- Should the BN just try to send the
getPayload with SSZ body, and if the relay responds with an error then try with JSON again? Or should it send an accept-encoding: ssz header to getHeader, and if it receives the header in SSZ encoding then use SSZ for getPayload too, otherwise fall back to JSON?
I've benchmarked encoding and decoding of signed-blinded-beacon-block payloads with SSZ vs JSON: flashbots/go-boost-utils#50
SSZ seems 40-50x faster:
This would be particularly relevant for
getPayloadcalls, because of the payload size and timing constraints (but perhaps also interesting forgetHeaderandregisterValidator).Each
getPayloadcall currently does 8 JSON encoding and decoding steps (if we include mev-boost in the mix):getPayloadrequest body (signed blinded beacon block)getPayloadrequest bodygetPayloadrequest bodygetPayloadrequest bodygetPayloadresponse body (execution payload)getPayloadresponse bodygetPayloadresponse bodygetPayloadresponse bodyConsidering 20-40ms per coding on average, that's up to 200-300ms JSON latency (or more).
Sending the data SSZ encoded could reliably shave 200-250ms off each
getPayloadroundtrip.I propose we add SSZ encoded payloads as first-class citizens.
Questions:
getPayloadwith SSZ body, and if the relay responds with an error then try with JSON again? Or should it send anaccept-encoding: sszheader to getHeader, and if it receives the header in SSZ encoding then use SSZ for getPayload too, otherwise fall back to JSON?