flashbots / flashbots/mev-boost-relay

issues decoding deneb payloads

Open
#731 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
498
Forks
147
PR merge metrics
No merged PRs in 30d

Description

Describe the bug
we're not entirely sure of the cause, only of the obvious error / panic

{
  "err": "BUG: count '130' higher than limit '8'",
  "level": "error",
  "method": "POST",
  "msg": "http request panic: POST /eth/v1/builder/blinded_blocks",
  "service": "relay/api",
  "time": "2025-05-12T21:00:25.321447032Z",
  "trace": "goroutine 1101784 [running]:\nruntime/debug.Stack()\n\truntime/debug/stack.go:26 +0x5e\ngithub.com/flashbots/mev-boost-relay/services/api.(*RelayAPI).getRouter.LoggingMiddlewareLogrus.func2.1()\n\tgithub.com/flashbots/go-utils@v0.11.0/httplogger/httplogger.go:132 +0x19e\npanic({0xfc1620?, 0xc01b844f20?})\n\truntime/panic.go:792 +0x132\ngithub.com/ferranbt/fastssz.(*Hasher).merkleizeImpl(0x1040?, {0xc01f0b7420?, 0x47dade?, 0x1300?}, {0xc01f0b7420?, 0xc01b831100?, 0x100?}, 0x8)\n\tgithub.com/ferranbt/fastssz@v0.1.4/hasher.go:364 +0x59a\ngithub.com/ferranbt/fastssz.(*Hasher).MerkleizeWithMixin(0xc000272680, 0x120, 0x81fa, 0xc01f0ad300?)\n\tgithub.com/ferranbt/fastssz@v0.1.4/hasher.go:288 +0x177\ngithub.com/ferranbt/fastssz.(*Hasher).PutBitlist(0xc000272680, {0xc01f0ad300?, 0x100?, 0x120?}, 0x800)\n\tgithub.com/ferranbt/fastssz@v0.1.4/hasher.go:232 +0x219\ngithub.com/attestantio/go-eth2-client/spec/phase0.(*Attestation).HashTreeRootWith(0xc0002e6200, {0x135b2f0, 0xc000272680})\n\tgithub.com/attestantio/go-eth2-client@v0.25.0/spec/phase0/attestation_ssz.go:114 +0x63\ngithub.com/attestantio/go-eth2-client/api/v1/deneb.(*BlindedBeaconBlockBody).HashTreeRootWith(0xc01b824780, {0x135b2f0, 0xc000272680})\n\tgithub.com/attestantio/go-eth2-client@v0.25.0/api/v1/deneb/blindedbeaconblockbody_ssz.go:507 +0x369\ngithub.com/attestantio/go-eth2-client/api/v1/deneb.(*BlindedBeaconBlock).HashTreeRootWith(0xc01c5a67e0, {0x135b2f0, 0xc000272680})\n\tgithub.com/attestantio/go-eth2-client@v0.25.0/api/v1/deneb/blindedbeaconblock_ssz.go:128 +0xc6\ngithub.com/ferranbt/fastssz.HashWithDefaultHasher({0x134a028, 0xc01c5a67e0})\n\tgithub.com/ferranbt/fastssz@v0.1.4/hasher.go:47 +0x73\ngithub.com/attestantio/go-eth2-client/api/v1/deneb.(*BlindedBeaconBlock).HashTreeRoot(...)\n\tgithub.com/attestantio/go-eth2-client@v0.25.0/api/v1/deneb/blindedbeaconblock_ssz.go:108\ngithub.com/attestantio/go-eth2-client/api.(*VersionedSignedBlindedBeaconBlock).Root(0xebf4000bc40c0002?)\n\tgithub.com/attestantio/go-eth2-client@v0.25.0/api/versionedsignedblindedbeaconblock.go:166 +0x199\ngithub.com/flashbots/mev-boost-relay/services/api.verifyBlockSignature(0xc038bc3290, {0x0, 0x0, 0x0, 0x0, 0x6a, 0x95, 0xa1, 0xa9, 0x67, ...}, ...)\n\tgithub.com/flashbots/mev-boost-relay/services/api/utils.go:169 +0x45\ngithub.com/flashbots/mev-boost-relay/services/api.(*RelayAPI).checkProposerSignature(0x286d01c2cb71a2ad?, 0xc725ea1f12e42f32?, {0xc01f09029c?, 0x9299d0933eb1fb9f?, 0x70a4a9402cc7d2e9?})\n\tgithub.com/flashbots/mev-boost-relay/services/api/service.go:1468 +0x113\ngithub.com/flashbots/mev-boost-relay/services/api.(*RelayAPI).handleGetPayload(0xc000244008, {0x1348858, 0xc01b60bf20}, 0xc01b824500)\n\tgithub.com/flashbots/mev-boost-relay/services/api/service.go:1774 +0x27b5\nnet/http.HandlerFunc.ServeHTTP(0xc01b8243c0?, {0x1348858?, 0xc01b60bf20?}, 0x2?)\n\tnet/http/server.go:2294 +0x29\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc000052300, {0x1348858, 0xc01b60bf20}, 0xc01b824140)\n\tgithub.com/gorilla/mux@v1.8.1/mux.go:212 +0x1e2\ngithub.com/flashbots/mev-boost-relay/services/api.(*RelayAPI).getRouter.LoggingMiddlewareLogrus.func2({0x134a6b8, 0xc010c94a80}, 0xc01b824140)\n\tgithub.com/flashbots/go-utils@v0.11.0/httplogger/httplogger.go:139 +0xfc\nnet/http.HandlerFunc.ServeHTTP(0x0?, {0x134a6b8?, 0xc010c94a80?}, 0x4?)\n\tnet/http/server.go:2294 +0x29\ngithub.com/NYTimes/gziphandler.GzipHandlerWithOpts.func1.1({0x1348c18, 0xc011ceb420}, 0xc01b824140)\n\tgithub.com/NYTimes/gziphandler@v1.1.1/gzip.go:336 +0x275\nnet/http.HandlerFunc.ServeHTTP(0x41b405?, {0x1348c18?, 0xc011ceb420?}, 0xc011ceb401?)\n\tnet/http/server.go:2294 +0x29\nnet/http.serverHandler.ServeHTTP({0x13456b8?}, {0x1348c18?, 0xc011ceb420?}, 0x6?)\n\tnet/http/server.go:3301 +0x8e\nnet/http.(*conn).serve(0xc01bcf6990, {0x134c458, 0xc00023a390})\n\tnet/http/server.go:2102 +0x625\ncreated by net/http.(*Server).Serve in goroutine 1\n\tnet/http/server.go:3454 +0x485\n",
  "version": ""
}

what is clear from the stacktrace is, payload api is panic-ing for signed blinded block requests (the most critical one!) but only while trying to verify a signature for a deneb block. post-fork, we shouldn't be getting any of those.

it seems in verifyBlockSignature while computing signingData.HashTreeRoot() we blow up. since we're post fork this seems easy enough to solve by checking if the payload is an electra payload and otherwise rejecting the request entirely.

why the panic happens is not clear to us.

leading explanation for us is that some old clients are still sending Deneb payloads. we particularly noted some DVT clusters sent with mev-boost 1.7 user agents but this seemed a partial explanation at best.

Expected behavior

  1. to reject payloads only valid pre-fork, post-fork would be nice
  2. to not panic when verifying old signatures

Which version are you using:
we run a slightly modified forked version. although the above seems unlikely due to our modifications it could be. would be interesting if other relays, specifically those running this code saw the same error.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in services/api/utils.go at verifyBlockSignature, then trace its callers in service.go through checkProposerSignature and handleGetPayload. Reproduce or inspect signed blinded-block verification for Deneb requests and determine the existing API response path. Done means pre-fork payloads are rejected without a panic during signature verification.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, backend, blockchain
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.