github.com/ethereum-optimism/optimism@v1.7.2/op-node/rollup/derive/span_batch_test.go (about) 1 package derive 2 3 import ( 4 "bytes" 5 "math" 6 "math/big" 7 "math/rand" 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 13 "github.com/ethereum/go-ethereum/common" 14 "github.com/ethereum/go-ethereum/core/types" 15 "github.com/ethereum/go-ethereum/rlp" 16 17 "github.com/ethereum-optimism/optimism/op-node/rollup" 18 "github.com/ethereum-optimism/optimism/op-service/testutils" 19 ) 20 21 func TestSpanBatchForBatchInterface(t *testing.T) { 22 rng := rand.New(rand.NewSource(0x5432177)) 23 chainID := big.NewInt(rng.Int63n(1000)) 24 25 singularBatches := RandomValidConsecutiveSingularBatches(rng, chainID) 26 blockCount := len(singularBatches) 27 safeL2Head := testutils.RandomL2BlockRef(rng) 28 safeL2Head.Hash = common.BytesToHash(singularBatches[0].ParentHash[:]) 29 30 spanBatch := NewSpanBatch(singularBatches) 31 32 // check interface method implementations except logging 33 require.Equal(t, SpanBatchType, spanBatch.GetBatchType()) 34 require.Equal(t, singularBatches[0].Timestamp, spanBatch.GetTimestamp()) 35 require.Equal(t, singularBatches[0].EpochNum, spanBatch.GetStartEpochNum()) 36 require.True(t, spanBatch.CheckOriginHash(singularBatches[blockCount-1].EpochHash)) 37 require.True(t, spanBatch.CheckParentHash(singularBatches[0].ParentHash)) 38 } 39 40 func TestEmptySpanBatch(t *testing.T) { 41 rng := rand.New(rand.NewSource(0x77556691)) 42 chainID := big.NewInt(rng.Int63n(1000)) 43 spanTxs, err := newSpanBatchTxs(nil, chainID) 44 require.NoError(t, err) 45 46 rawSpanBatch := RawSpanBatch{ 47 spanBatchPrefix: spanBatchPrefix{ 48 relTimestamp: uint64(rng.Uint32()), 49 l1OriginNum: rng.Uint64(), 50 parentCheck: *(*[20]byte)(testutils.RandomData(rng, 20)), 51 l1OriginCheck: *(*[20]byte)(testutils.RandomData(rng, 20)), 52 }, 53 spanBatchPayload: spanBatchPayload{ 54 blockCount: 0, 55 originBits: big.NewInt(0), 56 blockTxCounts: []uint64{}, 57 txs: spanTxs, 58 }, 59 } 60 61 var buf bytes.Buffer 62 err = rawSpanBatch.encodeBlockCount(&buf) 63 assert.NoError(t, err) 64 65 result := buf.Bytes() 66 r := bytes.NewReader(result) 67 var sb RawSpanBatch 68 69 err = sb.decodeBlockCount(r) 70 require.ErrorIs(t, err, ErrEmptySpanBatch) 71 } 72 73 func TestSpanBatchOriginBits(t *testing.T) { 74 rng := rand.New(rand.NewSource(0x77665544)) 75 chainID := big.NewInt(rng.Int63n(1000)) 76 77 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 78 79 blockCount := rawSpanBatch.blockCount 80 81 var buf bytes.Buffer 82 err := rawSpanBatch.encodeOriginBits(&buf) 83 require.NoError(t, err) 84 85 // originBit field is fixed length: single bit 86 originBitBufferLen := blockCount / 8 87 if blockCount%8 != 0 { 88 originBitBufferLen++ 89 } 90 require.Equal(t, buf.Len(), int(originBitBufferLen)) 91 92 result := buf.Bytes() 93 var sb RawSpanBatch 94 sb.blockCount = blockCount 95 r := bytes.NewReader(result) 96 err = sb.decodeOriginBits(r) 97 require.NoError(t, err) 98 99 require.Equal(t, rawSpanBatch.originBits, sb.originBits) 100 } 101 102 func TestSpanBatchPrefix(t *testing.T) { 103 rng := rand.New(rand.NewSource(0x44775566)) 104 chainID := big.NewInt(rng.Int63n(1000)) 105 106 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 107 // only compare prefix 108 rawSpanBatch.spanBatchPayload = spanBatchPayload{} 109 110 var buf bytes.Buffer 111 err := rawSpanBatch.encodePrefix(&buf) 112 require.NoError(t, err) 113 114 result := buf.Bytes() 115 r := bytes.NewReader(result) 116 var sb RawSpanBatch 117 err = sb.decodePrefix(r) 118 require.NoError(t, err) 119 120 require.Equal(t, rawSpanBatch, &sb) 121 } 122 123 func TestSpanBatchRelTimestamp(t *testing.T) { 124 rng := rand.New(rand.NewSource(0x44775566)) 125 chainID := big.NewInt(rng.Int63n(1000)) 126 127 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 128 129 var buf bytes.Buffer 130 err := rawSpanBatch.encodeRelTimestamp(&buf) 131 require.NoError(t, err) 132 133 result := buf.Bytes() 134 r := bytes.NewReader(result) 135 var sb RawSpanBatch 136 err = sb.decodeRelTimestamp(r) 137 require.NoError(t, err) 138 139 require.Equal(t, rawSpanBatch.relTimestamp, sb.relTimestamp) 140 } 141 142 func TestSpanBatchL1OriginNum(t *testing.T) { 143 rng := rand.New(rand.NewSource(0x77556688)) 144 chainID := big.NewInt(rng.Int63n(1000)) 145 146 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 147 148 var buf bytes.Buffer 149 err := rawSpanBatch.encodeL1OriginNum(&buf) 150 require.NoError(t, err) 151 152 result := buf.Bytes() 153 r := bytes.NewReader(result) 154 var sb RawSpanBatch 155 err = sb.decodeL1OriginNum(r) 156 require.NoError(t, err) 157 158 require.Equal(t, rawSpanBatch.l1OriginNum, sb.l1OriginNum) 159 } 160 161 func TestSpanBatchParentCheck(t *testing.T) { 162 rng := rand.New(rand.NewSource(0x77556689)) 163 chainID := big.NewInt(rng.Int63n(1000)) 164 165 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 166 167 var buf bytes.Buffer 168 err := rawSpanBatch.encodeParentCheck(&buf) 169 require.NoError(t, err) 170 171 // parent check field is fixed length: 20 bytes 172 require.Equal(t, buf.Len(), 20) 173 174 result := buf.Bytes() 175 r := bytes.NewReader(result) 176 var sb RawSpanBatch 177 err = sb.decodeParentCheck(r) 178 require.NoError(t, err) 179 180 require.Equal(t, rawSpanBatch.parentCheck, sb.parentCheck) 181 } 182 183 func TestSpanBatchL1OriginCheck(t *testing.T) { 184 rng := rand.New(rand.NewSource(0x77556690)) 185 chainID := big.NewInt(rng.Int63n(1000)) 186 187 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 188 189 var buf bytes.Buffer 190 err := rawSpanBatch.encodeL1OriginCheck(&buf) 191 require.NoError(t, err) 192 193 // l1 origin check field is fixed length: 20 bytes 194 require.Equal(t, buf.Len(), 20) 195 196 result := buf.Bytes() 197 r := bytes.NewReader(result) 198 var sb RawSpanBatch 199 err = sb.decodeL1OriginCheck(r) 200 require.NoError(t, err) 201 202 require.Equal(t, rawSpanBatch.l1OriginCheck, sb.l1OriginCheck) 203 } 204 205 func TestSpanBatchPayload(t *testing.T) { 206 rng := rand.New(rand.NewSource(0x77556691)) 207 chainID := big.NewInt(rng.Int63n(1000)) 208 209 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 210 211 var buf bytes.Buffer 212 err := rawSpanBatch.encodePayload(&buf) 213 require.NoError(t, err) 214 215 result := buf.Bytes() 216 r := bytes.NewReader(result) 217 var sb RawSpanBatch 218 219 err = sb.decodePayload(r) 220 require.NoError(t, err) 221 222 err = sb.txs.recoverV(chainID) 223 require.NoError(t, err) 224 225 require.Equal(t, rawSpanBatch.spanBatchPayload, sb.spanBatchPayload) 226 } 227 228 func TestSpanBatchBlockCount(t *testing.T) { 229 rng := rand.New(rand.NewSource(0x77556691)) 230 chainID := big.NewInt(rng.Int63n(1000)) 231 232 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 233 234 var buf bytes.Buffer 235 err := rawSpanBatch.encodeBlockCount(&buf) 236 require.NoError(t, err) 237 238 result := buf.Bytes() 239 r := bytes.NewReader(result) 240 var sb RawSpanBatch 241 242 err = sb.decodeBlockCount(r) 243 require.NoError(t, err) 244 245 require.Equal(t, rawSpanBatch.blockCount, sb.blockCount) 246 } 247 248 func TestSpanBatchBlockTxCounts(t *testing.T) { 249 rng := rand.New(rand.NewSource(0x77556692)) 250 chainID := big.NewInt(rng.Int63n(1000)) 251 252 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 253 254 var buf bytes.Buffer 255 err := rawSpanBatch.encodeBlockTxCounts(&buf) 256 require.NoError(t, err) 257 258 result := buf.Bytes() 259 r := bytes.NewReader(result) 260 var sb RawSpanBatch 261 262 sb.blockCount = rawSpanBatch.blockCount 263 err = sb.decodeBlockTxCounts(r) 264 require.NoError(t, err) 265 266 require.Equal(t, rawSpanBatch.blockTxCounts, sb.blockTxCounts) 267 } 268 269 func TestSpanBatchTxs(t *testing.T) { 270 rng := rand.New(rand.NewSource(0x77556693)) 271 chainID := big.NewInt(rng.Int63n(1000)) 272 273 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 274 275 var buf bytes.Buffer 276 err := rawSpanBatch.encodeTxs(&buf) 277 require.NoError(t, err) 278 279 result := buf.Bytes() 280 r := bytes.NewReader(result) 281 var sb RawSpanBatch 282 283 sb.blockTxCounts = rawSpanBatch.blockTxCounts 284 err = sb.decodeTxs(r) 285 require.NoError(t, err) 286 287 err = sb.txs.recoverV(chainID) 288 require.NoError(t, err) 289 290 require.Equal(t, rawSpanBatch.txs, sb.txs) 291 } 292 293 func TestSpanBatchRoundTrip(t *testing.T) { 294 rng := rand.New(rand.NewSource(0x77556694)) 295 chainID := big.NewInt(rng.Int63n(1000)) 296 297 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 298 299 var result bytes.Buffer 300 err := rawSpanBatch.encode(&result) 301 require.NoError(t, err) 302 303 var sb RawSpanBatch 304 err = sb.decode(bytes.NewReader(result.Bytes())) 305 require.NoError(t, err) 306 307 err = sb.txs.recoverV(chainID) 308 require.NoError(t, err) 309 310 require.Equal(t, rawSpanBatch, &sb) 311 } 312 313 func TestSpanBatchDerive(t *testing.T) { 314 rng := rand.New(rand.NewSource(0xbab0bab0)) 315 316 chainID := new(big.Int).SetUint64(rng.Uint64()) 317 l2BlockTime := uint64(2) 318 319 for originChangedBit := 0; originChangedBit < 2; originChangedBit++ { 320 singularBatches := RandomValidConsecutiveSingularBatches(rng, chainID) 321 safeL2Head := testutils.RandomL2BlockRef(rng) 322 safeL2Head.Hash = common.BytesToHash(singularBatches[0].ParentHash[:]) 323 genesisTimeStamp := 1 + singularBatches[0].Timestamp - 128 324 325 spanBatch := NewSpanBatch(singularBatches) 326 originChangedBit := uint(originChangedBit) 327 rawSpanBatch, err := spanBatch.ToRawSpanBatch(originChangedBit, genesisTimeStamp, chainID) 328 require.NoError(t, err) 329 330 spanBatchDerived, err := rawSpanBatch.derive(l2BlockTime, genesisTimeStamp, chainID) 331 require.NoError(t, err) 332 333 blockCount := len(singularBatches) 334 require.Equal(t, safeL2Head.Hash.Bytes()[:20], spanBatchDerived.ParentCheck[:]) 335 require.Equal(t, singularBatches[blockCount-1].Epoch().Hash.Bytes()[:20], spanBatchDerived.L1OriginCheck[:]) 336 require.Equal(t, len(singularBatches), int(rawSpanBatch.blockCount)) 337 338 for i := 1; i < len(singularBatches); i++ { 339 require.Equal(t, spanBatchDerived.Batches[i].Timestamp, spanBatchDerived.Batches[i-1].Timestamp+l2BlockTime) 340 } 341 342 for i := 0; i < len(singularBatches); i++ { 343 require.Equal(t, singularBatches[i].EpochNum, spanBatchDerived.Batches[i].EpochNum) 344 require.Equal(t, singularBatches[i].Timestamp, spanBatchDerived.Batches[i].Timestamp) 345 require.Equal(t, singularBatches[i].Transactions, spanBatchDerived.Batches[i].Transactions) 346 } 347 } 348 } 349 350 func TestSpanBatchAppend(t *testing.T) { 351 rng := rand.New(rand.NewSource(0x44337711)) 352 353 chainID := new(big.Int).SetUint64(rng.Uint64()) 354 355 singularBatches := RandomValidConsecutiveSingularBatches(rng, chainID) 356 // initialize empty span batch 357 spanBatch := NewSpanBatch([]*SingularBatch{}) 358 359 L := 2 360 for i := 0; i < L; i++ { 361 spanBatch.AppendSingularBatch(singularBatches[i]) 362 } 363 // initialize with two singular batches 364 spanBatch2 := NewSpanBatch(singularBatches[:L]) 365 366 require.Equal(t, spanBatch, spanBatch2) 367 } 368 369 func TestSpanBatchMerge(t *testing.T) { 370 rng := rand.New(rand.NewSource(0x73314433)) 371 372 genesisTimeStamp := rng.Uint64() 373 chainID := new(big.Int).SetUint64(rng.Uint64()) 374 375 for originChangedBit := 0; originChangedBit < 2; originChangedBit++ { 376 singularBatches := RandomValidConsecutiveSingularBatches(rng, chainID) 377 blockCount := len(singularBatches) 378 379 spanBatch := NewSpanBatch(singularBatches) 380 originChangedBit := uint(originChangedBit) 381 rawSpanBatch, err := spanBatch.ToRawSpanBatch(originChangedBit, genesisTimeStamp, chainID) 382 require.NoError(t, err) 383 384 // check span batch prefix 385 require.Equal(t, rawSpanBatch.relTimestamp, singularBatches[0].Timestamp-genesisTimeStamp, "invalid relative timestamp") 386 require.Equal(t, rollup.Epoch(rawSpanBatch.l1OriginNum), singularBatches[blockCount-1].EpochNum) 387 require.Equal(t, rawSpanBatch.parentCheck[:], singularBatches[0].ParentHash.Bytes()[:20], "invalid parent check") 388 require.Equal(t, rawSpanBatch.l1OriginCheck[:], singularBatches[blockCount-1].EpochHash.Bytes()[:20], "invalid l1 origin check") 389 390 // check span batch payload 391 require.Equal(t, int(rawSpanBatch.blockCount), len(singularBatches)) 392 require.Equal(t, rawSpanBatch.originBits.Bit(0), originChangedBit) 393 for i := 1; i < blockCount; i++ { 394 if rawSpanBatch.originBits.Bit(i) == 1 { 395 require.Equal(t, singularBatches[i].EpochNum, singularBatches[i-1].EpochNum+1) 396 } else { 397 require.Equal(t, singularBatches[i].EpochNum, singularBatches[i-1].EpochNum) 398 } 399 } 400 for i := 0; i < len(singularBatches); i++ { 401 txCount := len(singularBatches[i].Transactions) 402 require.Equal(t, txCount, int(rawSpanBatch.blockTxCounts[i])) 403 } 404 405 // check invariants 406 endEpochNum := rawSpanBatch.l1OriginNum 407 require.Equal(t, endEpochNum, uint64(singularBatches[blockCount-1].EpochNum)) 408 409 // we do not check txs field because it has to be derived to be compared 410 } 411 } 412 413 func TestSpanBatchToSingularBatch(t *testing.T) { 414 rng := rand.New(rand.NewSource(0xbab0bab1)) 415 chainID := new(big.Int).SetUint64(rng.Uint64()) 416 417 for originChangedBit := 0; originChangedBit < 2; originChangedBit++ { 418 singularBatches := RandomValidConsecutiveSingularBatches(rng, chainID) 419 safeL2Head := testutils.RandomL2BlockRef(rng) 420 safeL2Head.Hash = common.BytesToHash(singularBatches[0].ParentHash[:]) 421 safeL2Head.Time = singularBatches[0].Timestamp - 2 422 genesisTimeStamp := 1 + singularBatches[0].Timestamp - 128 423 424 spanBatch := NewSpanBatch(singularBatches) 425 originChangedBit := uint(originChangedBit) 426 rawSpanBatch, err := spanBatch.ToRawSpanBatch(originChangedBit, genesisTimeStamp, chainID) 427 require.NoError(t, err) 428 429 l1Origins := mockL1Origin(rng, rawSpanBatch, singularBatches) 430 431 singularBatches2, err := spanBatch.GetSingularBatches(l1Origins, safeL2Head) 432 require.NoError(t, err) 433 434 // GetSingularBatches does not fill in parent hash of singular batches 435 // empty out parent hash for comparison 436 for i := 0; i < len(singularBatches); i++ { 437 singularBatches[i].ParentHash = common.Hash{} 438 } 439 // check parent hash is empty 440 for i := 0; i < len(singularBatches2); i++ { 441 require.Equal(t, singularBatches2[i].ParentHash, common.Hash{}) 442 } 443 444 require.Equal(t, singularBatches, singularBatches2) 445 } 446 } 447 448 func TestSpanBatchReadTxData(t *testing.T) { 449 cases := []spanBatchTxTest{ 450 {"unprotected legacy tx", 32, testutils.RandomLegacyTx, false}, 451 {"legacy tx", 32, testutils.RandomLegacyTx, true}, 452 {"access list tx", 32, testutils.RandomAccessListTx, true}, 453 {"dynamic fee tx", 32, testutils.RandomDynamicFeeTx, true}, 454 } 455 456 for i, testCase := range cases { 457 t.Run(testCase.name, func(t *testing.T) { 458 rng := rand.New(rand.NewSource(int64(0x109550 + i))) 459 chainID := new(big.Int).SetUint64(rng.Uint64()) 460 signer := types.NewLondonSigner(chainID) 461 if !testCase.protected { 462 signer = types.HomesteadSigner{} 463 } 464 465 var rawTxs [][]byte 466 var txs []*types.Transaction 467 for txIdx := 0; txIdx < testCase.trials; txIdx++ { 468 tx := testCase.mkTx(rng, signer) 469 rawTx, err := tx.MarshalBinary() 470 require.NoError(t, err) 471 rawTxs = append(rawTxs, rawTx) 472 txs = append(txs, tx) 473 } 474 475 for txIdx := 0; txIdx < testCase.trials; txIdx++ { 476 r := bytes.NewReader(rawTxs[i]) 477 _, txType, err := ReadTxData(r) 478 require.NoError(t, err) 479 assert.Equal(t, int(txs[i].Type()), txType) 480 } 481 }) 482 } 483 } 484 485 func TestSpanBatchReadTxDataInvalid(t *testing.T) { 486 dummy, err := rlp.EncodeToBytes("dummy") 487 require.NoError(t, err) 488 489 // test non list rlp decoding 490 r := bytes.NewReader(dummy) 491 _, _, err = ReadTxData(r) 492 require.ErrorContains(t, err, "tx RLP prefix type must be list") 493 } 494 495 func TestSpanBatchBuilder(t *testing.T) { 496 rng := rand.New(rand.NewSource(0xbab1bab1)) 497 chainID := new(big.Int).SetUint64(rng.Uint64()) 498 499 for originChangedBit := 0; originChangedBit < 2; originChangedBit++ { 500 singularBatches := RandomValidConsecutiveSingularBatches(rng, chainID) 501 safeL2Head := testutils.RandomL2BlockRef(rng) 502 if originChangedBit == 0 { 503 safeL2Head.Hash = common.BytesToHash(singularBatches[0].ParentHash[:]) 504 } 505 genesisTimeStamp := 1 + singularBatches[0].Timestamp - 128 506 507 var seqNum uint64 = 1 508 if originChangedBit == 1 { 509 seqNum = 0 510 } 511 spanBatchBuilder := NewSpanBatchBuilder(genesisTimeStamp, chainID) 512 513 require.Equal(t, 0, spanBatchBuilder.GetBlockCount()) 514 515 for i := 0; i < len(singularBatches); i++ { 516 spanBatchBuilder.AppendSingularBatch(singularBatches[i], seqNum) 517 require.Equal(t, i+1, spanBatchBuilder.GetBlockCount()) 518 require.Equal(t, singularBatches[0].ParentHash.Bytes()[:20], spanBatchBuilder.spanBatch.ParentCheck[:]) 519 require.Equal(t, singularBatches[i].EpochHash.Bytes()[:20], spanBatchBuilder.spanBatch.L1OriginCheck[:]) 520 } 521 522 rawSpanBatch, err := spanBatchBuilder.GetRawSpanBatch() 523 require.NoError(t, err) 524 525 // compare with rawSpanBatch not using spanBatchBuilder 526 spanBatch := NewSpanBatch(singularBatches) 527 originChangedBit := uint(originChangedBit) 528 rawSpanBatch2, err := spanBatch.ToRawSpanBatch(originChangedBit, genesisTimeStamp, chainID) 529 require.NoError(t, err) 530 531 require.Equal(t, rawSpanBatch2, rawSpanBatch) 532 533 spanBatchBuilder.Reset() 534 require.Equal(t, 0, spanBatchBuilder.GetBlockCount()) 535 } 536 } 537 538 func TestSpanBatchMaxTxData(t *testing.T) { 539 rng := rand.New(rand.NewSource(0x177288)) 540 541 invalidTx := types.NewTx(&types.DynamicFeeTx{ 542 Data: testutils.RandomData(rng, MaxSpanBatchSize+1), 543 }) 544 545 txEncoded, err := invalidTx.MarshalBinary() 546 require.NoError(t, err) 547 548 r := bytes.NewReader(txEncoded) 549 _, _, err = ReadTxData(r) 550 551 require.ErrorIs(t, err, ErrTooBigSpanBatchSize) 552 } 553 554 func TestSpanBatchMaxOriginBitsLength(t *testing.T) { 555 var sb RawSpanBatch 556 sb.blockCount = math.MaxUint64 557 558 r := bytes.NewReader([]byte{}) 559 err := sb.decodeOriginBits(r) 560 require.ErrorIs(t, err, ErrTooBigSpanBatchSize) 561 } 562 563 func TestSpanBatchMaxBlockCount(t *testing.T) { 564 rng := rand.New(rand.NewSource(0x77556691)) 565 chainID := big.NewInt(rng.Int63n(1000)) 566 567 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 568 rawSpanBatch.blockCount = math.MaxUint64 569 570 var buf bytes.Buffer 571 err := rawSpanBatch.encodeBlockCount(&buf) 572 require.NoError(t, err) 573 574 result := buf.Bytes() 575 r := bytes.NewReader(result) 576 var sb RawSpanBatch 577 err = sb.decodeBlockCount(r) 578 require.ErrorIs(t, err, ErrTooBigSpanBatchSize) 579 } 580 581 func TestSpanBatchMaxBlockTxCount(t *testing.T) { 582 rng := rand.New(rand.NewSource(0x77556692)) 583 chainID := big.NewInt(rng.Int63n(1000)) 584 585 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 586 rawSpanBatch.blockTxCounts[0] = math.MaxUint64 587 588 var buf bytes.Buffer 589 err := rawSpanBatch.encodeBlockTxCounts(&buf) 590 require.NoError(t, err) 591 592 result := buf.Bytes() 593 r := bytes.NewReader(result) 594 var sb RawSpanBatch 595 sb.blockCount = rawSpanBatch.blockCount 596 err = sb.decodeBlockTxCounts(r) 597 require.ErrorIs(t, err, ErrTooBigSpanBatchSize) 598 } 599 600 func TestSpanBatchTotalBlockTxCountNotOverflow(t *testing.T) { 601 rng := rand.New(rand.NewSource(0x77556693)) 602 chainID := big.NewInt(rng.Int63n(1000)) 603 604 rawSpanBatch := RandomRawSpanBatch(rng, chainID) 605 rawSpanBatch.blockTxCounts[0] = MaxSpanBatchSize - 1 606 rawSpanBatch.blockTxCounts[1] = MaxSpanBatchSize - 1 607 // we are sure that totalBlockTxCount will overflow on uint64 608 609 var buf bytes.Buffer 610 err := rawSpanBatch.encodeBlockTxCounts(&buf) 611 require.NoError(t, err) 612 613 result := buf.Bytes() 614 r := bytes.NewReader(result) 615 var sb RawSpanBatch 616 sb.blockTxCounts = rawSpanBatch.blockTxCounts 617 err = sb.decodeTxs(r) 618 619 require.ErrorIs(t, err, ErrTooBigSpanBatchSize) 620 }