@@ -42,6 +42,26 @@ import { RpcProvider as BaseRpcProvider } from '../src/provider/rpc';
42
42
import { RpcProvider as ExtendedRpcProvider } from '../src/provider/extensions/default' ;
43
43
import { StarknetId } from '../src/provider/extensions/starknetId' ;
44
44
45
+ /**
46
+ * Helper function to create expected zero tip estimate for tests
47
+ */
48
+ function expectZeroTipEstimate ( ) {
49
+ return {
50
+ minTip : 0n ,
51
+ maxTip : 0n ,
52
+ averageTip : 0n ,
53
+ medianTip : 0n ,
54
+ modeTip : 0n ,
55
+ recommendedTip : 0n ,
56
+ p90Tip : 0n ,
57
+ p95Tip : 0n ,
58
+ metrics : expect . objectContaining ( {
59
+ blocksAnalyzed : expect . any ( Number ) ,
60
+ transactionsFound : expect . any ( Number ) ,
61
+ } ) ,
62
+ } ;
63
+ }
64
+
45
65
describeIfRpc ( 'RPCProvider' , ( ) => {
46
66
let rpcProvider : RpcProvider ;
47
67
let provider : ProviderInterface ;
@@ -481,31 +501,37 @@ describeIfRpc('RPCProvider', () => {
481
501
describe ( 'Tip Estimation' , ( ) => {
482
502
describeIfRpc ( 'getEstimateTip' , ( ) => {
483
503
test ( 'should estimate tip from latest block or handle insufficient data' , async ( ) => {
484
- try {
485
- const tipEstimate = await rpcProvider . getEstimateTip ( 'latest' , {
486
- minTxsNecessary : 1 , // Use low threshold for test reliability
487
- maxBlocks : 10 , // Use more blocks to increase chance of finding data
488
- } ) ;
504
+ const tipEstimate = await rpcProvider . getEstimateTip ( 'latest' , {
505
+ minTxsNecessary : 1 , // Use low threshold for test reliability
506
+ maxBlocks : 10 , // Use more blocks to increase chance of finding data
507
+ } ) ;
489
508
490
- expect ( tipEstimate ) . toBeDefined ( ) ;
491
- expect ( tipEstimate ) . toEqual ( {
492
- minTip : expect . any ( BigInt ) ,
493
- maxTip : expect . any ( BigInt ) ,
494
- averageTip : expect . any ( BigInt ) ,
495
- medianTip : expect . any ( BigInt ) ,
496
- modeTip : expect . any ( BigInt ) ,
497
- recommendedTip : expect . any ( BigInt ) ,
498
- } ) ;
509
+ expect ( tipEstimate ) . toBeDefined ( ) ;
510
+ expect ( tipEstimate ) . toEqual ( {
511
+ minTip : expect . any ( BigInt ) ,
512
+ maxTip : expect . any ( BigInt ) ,
513
+ averageTip : expect . any ( BigInt ) ,
514
+ medianTip : expect . any ( BigInt ) ,
515
+ modeTip : expect . any ( BigInt ) ,
516
+ recommendedTip : expect . any ( BigInt ) ,
517
+ p90Tip : expect . any ( BigInt ) ,
518
+ p95Tip : expect . any ( BigInt ) ,
519
+ metrics : expect . objectContaining ( {
520
+ blocksAnalyzed : expect . any ( Number ) ,
521
+ transactionsFound : expect . any ( Number ) ,
522
+ } ) ,
523
+ } ) ;
499
524
525
+ // If there's insufficient data, all values should be 0n
526
+ if ( tipEstimate . recommendedTip === 0n ) {
527
+ expect ( tipEstimate ) . toEqual ( expectZeroTipEstimate ( ) ) ;
528
+ } else {
500
529
// Verify tip relationships
501
530
expect ( tipEstimate . minTip ) . toBeLessThanOrEqual ( tipEstimate . maxTip ) ;
502
531
expect ( tipEstimate . recommendedTip ) . toBeGreaterThan ( 0n ) ;
503
532
504
533
// Verify recommended tip is median tip (no buffer)
505
534
expect ( tipEstimate . recommendedTip ) . toBe ( tipEstimate . medianTip ) ;
506
- } catch ( error ) {
507
- // In test environments, there might not be enough V3 invoke transactions with tips
508
- expect ( ( error as Error ) . message ) . toContain ( 'Insufficient transaction data' ) ;
509
535
}
510
536
} ) ;
511
537
@@ -549,26 +575,28 @@ describeIfRpc('RPCProvider', () => {
549
575
} ) ;
550
576
551
577
test ( 'should work with custom maxBlocks or handle insufficient data' , async ( ) => {
552
- try {
553
- const tipEstimate = await rpcProvider . getEstimateTip ( 'latest' , {
554
- minTxsNecessary : 1 ,
555
- maxBlocks : 20 , // Analyze more blocks
556
- } ) ;
578
+ const tipEstimate = await rpcProvider . getEstimateTip ( 'latest' , {
579
+ minTxsNecessary : 1 ,
580
+ maxBlocks : 20 , // Analyze more blocks
581
+ } ) ;
557
582
558
- expect ( tipEstimate ) . toBeDefined ( ) ;
583
+ expect ( tipEstimate ) . toBeDefined ( ) ;
584
+
585
+ // If there's insufficient data, all values should be 0n
586
+ if ( tipEstimate . recommendedTip === 0n ) {
587
+ expect ( tipEstimate ) . toEqual ( expectZeroTipEstimate ( ) ) ;
588
+ } else {
559
589
expect ( tipEstimate . recommendedTip ) . toBeGreaterThan ( 0n ) ;
560
- } catch ( error ) {
561
- expect ( ( error as Error ) . message ) . toContain ( 'Insufficient transaction data' ) ;
562
590
}
563
591
} ) ;
564
592
565
- test ( 'should throw error with insufficient transaction data' , async ( ) => {
566
- await expect (
567
- rpcProvider . getEstimateTip ( 'latest' , {
568
- minTxsNecessary : 1000 , // Unreasonably high requirement
569
- maxBlocks : 1 ,
570
- } )
571
- ) . rejects . toThrow ( 'Insufficient transaction data' ) ;
593
+ test ( 'should return zero values with insufficient transaction data' , async ( ) => {
594
+ const tipEstimate = await rpcProvider . getEstimateTip ( 'latest' , {
595
+ minTxsNecessary : 1000 , // Unreasonably high requirement
596
+ maxBlocks : 1 ,
597
+ } ) ;
598
+
599
+ expect ( tipEstimate ) . toEqual ( expectZeroTipEstimate ( ) ) ;
572
600
} ) ;
573
601
574
602
describeIfDevnet ( 'with devnet transactions' , ( ) => {
@@ -628,27 +656,31 @@ describeIfRpc('RPCProvider', () => {
628
656
await createBlockForDevnet ( ) ;
629
657
}
630
658
631
- try {
632
- // Test with different block ranges
633
- const smallRange = await rpcProvider . getEstimateTip ( 'latest' , {
634
- minTxsNecessary : 1 ,
635
- maxBlocks : 1 ,
636
- } ) ;
659
+ // Test with different block ranges
660
+ const smallRange = await rpcProvider . getEstimateTip ( 'latest' , {
661
+ minTxsNecessary : 1 ,
662
+ maxBlocks : 1 ,
663
+ } ) ;
637
664
638
- const largeRange = await rpcProvider . getEstimateTip ( 'latest' , {
639
- minTxsNecessary : 1 ,
640
- maxBlocks : 10 ,
641
- } ) ;
665
+ const largeRange = await rpcProvider . getEstimateTip ( 'latest' , {
666
+ minTxsNecessary : 1 ,
667
+ maxBlocks : 10 ,
668
+ } ) ;
642
669
643
- expect ( smallRange ) . toBeDefined ( ) ;
644
- expect ( largeRange ) . toBeDefined ( ) ;
670
+ expect ( smallRange ) . toBeDefined ( ) ;
671
+ expect ( largeRange ) . toBeDefined ( ) ;
645
672
646
- // Both should have valid recommendations
673
+ // If insufficient data, values should be 0n
674
+ if ( smallRange . recommendedTip === 0n ) {
675
+ expect ( smallRange ) . toEqual ( expectZeroTipEstimate ( ) ) ;
676
+ } else {
647
677
expect ( smallRange . recommendedTip ) . toBeGreaterThan ( 0n ) ;
678
+ }
679
+
680
+ if ( largeRange . recommendedTip === 0n ) {
681
+ expect ( largeRange ) . toEqual ( expectZeroTipEstimate ( ) ) ;
682
+ } else {
648
683
expect ( largeRange . recommendedTip ) . toBeGreaterThan ( 0n ) ;
649
- } catch ( error ) {
650
- // Expected if devnet transactions don't include tips
651
- expect ( ( error as Error ) . message ) . toContain ( 'Insufficient transaction data' ) ;
652
684
}
653
685
} ) ;
654
686
} ) ;
@@ -660,27 +692,34 @@ describeIfRpc('RPCProvider', () => {
660
692
batch : 50 , // Enable batching
661
693
} ) ;
662
694
663
- try {
664
- const tipEstimate = await batchedProvider . getEstimateTip ( 'latest' , {
665
- minTxsNecessary : 1 ,
666
- maxBlocks : 10 ,
667
- } ) ;
695
+ const tipEstimate = await batchedProvider . getEstimateTip ( 'latest' , {
696
+ minTxsNecessary : 1 ,
697
+ maxBlocks : 10 ,
698
+ } ) ;
668
699
669
- expect ( tipEstimate ) . toBeDefined ( ) ;
670
- expect ( tipEstimate . recommendedTip ) . toBeGreaterThan ( 0n ) ;
700
+ expect ( tipEstimate ) . toBeDefined ( ) ;
701
+
702
+ // Verify the structure is correct
703
+ expect ( tipEstimate ) . toEqual ( {
704
+ minTip : expect . any ( BigInt ) ,
705
+ maxTip : expect . any ( BigInt ) ,
706
+ averageTip : expect . any ( BigInt ) ,
707
+ medianTip : expect . any ( BigInt ) ,
708
+ modeTip : expect . any ( BigInt ) ,
709
+ recommendedTip : expect . any ( BigInt ) ,
710
+ p90Tip : expect . any ( BigInt ) ,
711
+ p95Tip : expect . any ( BigInt ) ,
712
+ metrics : expect . objectContaining ( {
713
+ blocksAnalyzed : expect . any ( Number ) ,
714
+ transactionsFound : expect . any ( Number ) ,
715
+ } ) ,
716
+ } ) ;
671
717
672
- // Verify the structure is the same as non-batched
673
- expect ( tipEstimate ) . toEqual ( {
674
- minTip : expect . any ( BigInt ) ,
675
- maxTip : expect . any ( BigInt ) ,
676
- averageTip : expect . any ( BigInt ) ,
677
- medianTip : expect . any ( BigInt ) ,
678
- modeTip : expect . any ( BigInt ) ,
679
- recommendedTip : expect . any ( BigInt ) ,
680
- } ) ;
681
- } catch ( error ) {
682
- // Batching doesn't change data availability
683
- expect ( ( error as Error ) . message ) . toContain ( 'Insufficient transaction data' ) ;
718
+ // If insufficient data, values should be 0n
719
+ if ( tipEstimate . recommendedTip === 0n ) {
720
+ expect ( tipEstimate ) . toEqual ( expectZeroTipEstimate ( ) ) ;
721
+ } else {
722
+ expect ( tipEstimate . recommendedTip ) . toBeGreaterThan ( 0n ) ;
684
723
}
685
724
} ) ;
686
725
0 commit comments