diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 3e45ad9e4f..91b6511f71 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -638,6 +638,9 @@ func (api *ConsensusAPI) NewPayloadV4(params engine.ExecutableData, versionedHas return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadV4 must only be called for prague payloads")) } requests := convertRequests(executionRequests) + if err := validateRequests(requests); err != nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err) + } return api.newPayload(params, versionedHashes, beaconRoot, requests, false) } @@ -727,6 +730,9 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV4(params engine.ExecutableData, v return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadWithWitnessV4 must only be called for prague payloads")) } requests := convertRequests(executionRequests) + if err := validateRequests(requests); err != nil { + return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(err) + } return api.newPayload(params, versionedHashes, beaconRoot, requests, true) } @@ -1287,3 +1293,20 @@ func convertRequests(hex []hexutil.Bytes) [][]byte { } return req } + +// validateRequests checks that requests are ordered by their type and are not empty. +func validateRequests(requests [][]byte) error { + var last byte + for _, req := range requests { + // No empty requests. + if len(req) < 2 { + return fmt.Errorf("empty request: %v", req) + } + // Check that requests are ordered by their type. + if req[0] < last { + return fmt.Errorf("invalid request order: %v", req) + } + last = req[0] + } + return nil +}