@@ -158,30 +158,12 @@ func TestValidatorService_MistmatchedBlobFields(t *testing.T) {
158158 (* i )[0 ].Blob = deneb.Blob {0 , 0 , 0 }
159159 },
160160 },
161- {
162- name : "mismatched kzg commitment" ,
163- modification : func (i * []* deneb.BlobSidecar ) {
164- (* i )[0 ].KZGCommitment = deneb.KZGCommitment {0 , 0 , 0 }
165- },
166- },
167- {
168- name : "mismatched kzg proof" ,
169- modification : func (i * []* deneb.BlobSidecar ) {
170- (* i )[0 ].KZGProof = deneb.KZGProof {0 , 0 , 0 }
171- },
172- },
173161 {
174162 name : "mismatched signed block header" ,
175163 modification : func (i * []* deneb.BlobSidecar ) {
176164 (* i )[0 ].SignedBlockHeader = nil
177165 },
178166 },
179- {
180- name : "mismatched kzg commitment inclusion proof" ,
181- modification : func (i * []* deneb.BlobSidecar ) {
182- (* i )[0 ].KZGCommitmentInclusionProof = deneb.KZGCommitmentInclusionProof {{1 , 2 , 9 }}
183- },
184- },
185167 }
186168
187169 for _ , test := range tests {
@@ -215,3 +197,100 @@ func TestValidatorService_MistmatchedBlobFields(t *testing.T) {
215197 })
216198 }
217199}
200+
201+ // TestValidatorService_KZGProofMismatchWithValidBlobAPI tests the scenario where:
202+ // - Beacon node returns invalid/zeroed KZG proofs (e.g., post-Fulu blob)
203+ // - Blob API has valid computed KZG proofs
204+ // - All other data matches
205+ // This should be accepted as valid
206+ func TestValidatorService_KZGProofMismatchWithValidBlobAPI (t * testing.T ) {
207+ validator , headers , beacon , blob := setup (t )
208+
209+ beacon .setResponses (headers )
210+ blob .setResponses (headers )
211+
212+ // Deep copy the beacon data and zero out KZG fields to simulate beacon node bug
213+ d , err := json .Marshal (headers .SidecarsByBlock [blockOne ])
214+ require .NoError (t , err )
215+ var beaconData []* deneb.BlobSidecar
216+ err = json .Unmarshal (d , & beaconData )
217+ require .NoError (t , err )
218+
219+ // Simulate beacon node bug: set KZG proof to point at infinity (0xc0...)
220+ for i := range beaconData {
221+ beaconData [i ].KZGProof = deneb.KZGProof {0xc0 }
222+ beaconData [i ].KZGCommitmentInclusionProof = deneb.KZGCommitmentInclusionProof {}
223+ }
224+
225+ beacon .setResponse (blockOne , 200 , storage.BlobSidecars {Data : beaconData }, nil )
226+
227+ result := validator .checkBlobs (context .Background (), phase0 .Slot (blobtest .StartSlot ), phase0 .Slot (blobtest .EndSlot ))
228+
229+ // Should have no errors - KZG mismatch accepted because blob API has valid proofs
230+ require .Empty (t , result .MismatchedStatus )
231+ require .Empty (t , result .ErrorFetching )
232+ require .Empty (t , result .MismatchedData )
233+ }
234+
235+ // TestValidatorService_KZGProofMismatchWithInvalidBlobAPI tests the scenario where:
236+ // - Both beacon node and blob API have different KZG proofs
237+ // - Blob API's KZG proofs are INVALID
238+ // This should be reported as an error
239+ func TestValidatorService_KZGProofMismatchWithInvalidBlobAPI (t * testing.T ) {
240+ validator , headers , beacon , blob := setup (t )
241+
242+ beacon .setResponses (headers )
243+ blob .setResponses (headers )
244+
245+ // Deep copy the blob data and set invalid KZG proof
246+ d , err := json .Marshal (headers .SidecarsByBlock [blockOne ])
247+ require .NoError (t , err )
248+ var blobData []* deneb.BlobSidecar
249+ err = json .Unmarshal (d , & blobData )
250+ require .NoError (t , err )
251+
252+ // Set invalid KZG proof on blob API
253+ for i := range blobData {
254+ blobData [i ].KZGProof = deneb.KZGProof {0xde , 0xad , 0xbe , 0xef }
255+ }
256+
257+ blob .setResponse (blockOne , 200 , storage.BlobSidecars {Data : blobData }, nil )
258+
259+ result := validator .checkBlobs (context .Background (), phase0 .Slot (blobtest .StartSlot ), phase0 .Slot (blobtest .EndSlot ))
260+
261+ // Should report mismatch because blob API has invalid KZG proofs
262+ require .Empty (t , result .MismatchedStatus )
263+ require .Empty (t , result .ErrorFetching )
264+ require .Len (t , result .MismatchedData , 2 )
265+ require .Equal (t , result .MismatchedData , []string {blockOne , blockOne })
266+ }
267+
268+ // TestValidatorService_DifferentSidecarCount tests the scenario where:
269+ // - Beacon and blob API return different numbers of sidecars
270+ // This should be reported as an error
271+ func TestValidatorService_DifferentSidecarCount (t * testing.T ) {
272+ validator , headers , beacon , blob := setup (t )
273+
274+ beacon .setResponses (headers )
275+ blob .setResponses (headers )
276+
277+ // Set blob API to return fewer sidecars
278+ d , err := json .Marshal (headers .SidecarsByBlock [blockOne ])
279+ require .NoError (t , err )
280+ var blobData []* deneb.BlobSidecar
281+ err = json .Unmarshal (d , & blobData )
282+ require .NoError (t , err )
283+
284+ // Remove one sidecar
285+ blobData = blobData [:len (blobData )- 1 ]
286+
287+ blob .setResponse (blockOne , 200 , storage.BlobSidecars {Data : blobData }, nil )
288+
289+ result := validator .checkBlobs (context .Background (), phase0 .Slot (blobtest .StartSlot ), phase0 .Slot (blobtest .EndSlot ))
290+
291+ // Should report mismatch due to different sidecar counts
292+ require .Empty (t , result .MismatchedStatus )
293+ require .Empty (t , result .ErrorFetching )
294+ require .Len (t , result .MismatchedData , 2 )
295+ require .Equal (t , result .MismatchedData , []string {blockOne , blockOne })
296+ }
0 commit comments