@@ -19,32 +19,37 @@ contract MockReader {
1919 _scheduler = scheduler;
2020 }
2121
22- function getLatestPrices (
22+ function getPricesUnsafe (
2323 uint256 subscriptionId ,
2424 bytes32 [] memory priceIds
25- ) external view returns (PythStructs.PriceFeed[] memory ) {
26- return IScheduler (_scheduler).getLatestPrices (subscriptionId, priceIds);
25+ ) external view returns (PythStructs.Price[] memory ) {
26+ return IScheduler (_scheduler).getPricesUnsafe (subscriptionId, priceIds);
27+ }
28+
29+ function getEmaPriceUnsafe (
30+ uint256 subscriptionId ,
31+ bytes32 [] memory priceIds
32+ ) external view returns (PythStructs.Price[] memory ) {
33+ return IScheduler (_scheduler).getEmaPriceUnsafe (subscriptionId, priceIds);
2734 }
2835
2936 function verifyPriceFeeds (
3037 uint256 subscriptionId ,
3138 bytes32 [] memory priceIds ,
3239 PythStructs.PriceFeed[] memory expectedFeeds
3340 ) external view returns (bool ) {
34- PythStructs.PriceFeed [] memory actualFeeds = IScheduler (_scheduler)
35- .getLatestPrices (subscriptionId, priceIds);
41+ PythStructs.Price [] memory actualPrices = IScheduler (_scheduler)
42+ .getPricesUnsafe (subscriptionId, priceIds);
3643
37- if (actualFeeds .length != expectedFeeds.length ) {
44+ if (actualPrices .length != expectedFeeds.length ) {
3845 return false ;
3946 }
4047
41- for (uint i = 0 ; i < actualFeeds .length ; i++ ) {
48+ for (uint i = 0 ; i < actualPrices .length ; i++ ) {
4249 if (
43- actualFeeds[i].id != expectedFeeds[i].id ||
44- actualFeeds[i].price.price != expectedFeeds[i].price.price ||
45- actualFeeds[i].price.conf != expectedFeeds[i].price.conf ||
46- actualFeeds[i].price.publishTime !=
47- expectedFeeds[i].price.publishTime
50+ actualPrices[i].price != expectedFeeds[i].price.price ||
51+ actualPrices[i].conf != expectedFeeds[i].price.conf ||
52+ actualPrices[i].publishTime != expectedFeeds[i].price.publishTime
4853 ) {
4954 return false ;
5055 }
@@ -100,8 +105,8 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
100105 });
101106
102107 SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig ({
103- maxGasPrice: 100 gwei ,
104- maxGasLimit: 1_000_000
108+ maxGasMultiplierCapPct: 10_000 ,
109+ maxFeeMultiplierCapPct: 10_000
105110 });
106111
107112 SchedulerState.SubscriptionParams memory params = SchedulerState
@@ -152,9 +157,9 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
152157 "Deviation threshold mismatch "
153158 );
154159 assertEq (
155- storedParams.gasConfig.maxGasPrice ,
156- 100 gwei ,
157- "Max gas price mismatch "
160+ storedParams.gasConfig.maxGasMultiplierCapPct ,
161+ 10_000 ,
162+ "Max gas multiplier mismatch "
158163 );
159164
160165 assertTrue (status.isActive, "Subscription should be active " );
@@ -181,8 +186,8 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
181186
182187 SchedulerState.GasConfig memory newGasConfig = SchedulerState
183188 .GasConfig ({
184- maxGasPrice: 200 gwei , // Changed from 100 gwei
185- maxGasLimit: 2_000_000 // Changed from 1_000_000
189+ maxGasMultiplierCapPct: 20_000 , // Changed from 10_000
190+ maxFeeMultiplierCapPct: 20_000 // Changed from 10_000
186191 });
187192
188193 SchedulerState.SubscriptionParams memory newParams = SchedulerState
@@ -230,9 +235,9 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
230235 "Deviation threshold mismatch "
231236 );
232237 assertEq (
233- storedParams.gasConfig.maxGasPrice ,
234- 200 gwei ,
235- "Max gas price mismatch "
238+ storedParams.gasConfig.maxGasMultiplierCapPct ,
239+ 20_000 ,
240+ "Max gas multiplier mismatch "
236241 );
237242 }
238243
@@ -583,7 +588,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
583588 scheduler.updatePriceFeeds (subscriptionId, updateData, priceIds);
584589 }
585590
586- function testGetLatestPricesAllFeeds () public {
591+ function testGetPricesUnsafeAllFeeds () public {
587592 // First add a subscription, funds, and update price feeds
588593 uint256 subscriptionId = addTestSubscription ();
589594 uint256 fundAmount = 1 ether ;
@@ -602,7 +607,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
602607
603608 // Get all latest prices (empty priceIds array)
604609 bytes32 [] memory emptyPriceIds = new bytes32 [](0 );
605- PythStructs.PriceFeed [] memory latestPrices = scheduler.getLatestPrices (
610+ PythStructs.Price [] memory latestPrices = scheduler.getPricesUnsafe (
606611 subscriptionId,
607612 emptyPriceIds
608613 );
@@ -621,7 +626,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
621626 );
622627 }
623628
624- function testGetLatestPricesSelectiveFeeds () public {
629+ function testGetPricesUnsafeSelectiveFeeds () public {
625630 // First add a subscription with 3 price feeds, funds, and update price feeds
626631 uint256 subscriptionId = addTestSubscriptionWithFeeds (3 );
627632 uint256 fundAmount = 1 ether ;
@@ -643,7 +648,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
643648 bytes32 [] memory selectedPriceIds = new bytes32 [](1 );
644649 selectedPriceIds[0 ] = priceIds[0 ];
645650
646- PythStructs.PriceFeed [] memory latestPrices = scheduler.getLatestPrices (
651+ PythStructs.Price [] memory latestPrices = scheduler.getPricesUnsafe (
647652 subscriptionId,
648653 selectedPriceIds
649654 );
@@ -681,8 +686,8 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
681686 });
682687
683688 SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig ({
684- maxGasPrice: 100 gwei ,
685- maxGasLimit: 1_000_000
689+ maxGasMultiplierCapPct: 10_000 ,
690+ maxFeeMultiplierCapPct: 10_000
686691 });
687692
688693 SchedulerState.SubscriptionParams memory params = SchedulerState
@@ -717,7 +722,7 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
717722
718723 // Should not revert since whitelist is disabled
719724 // We'll just check that it doesn't revert
720- scheduler.getLatestPrices (subscriptionId, emptyPriceIds);
725+ scheduler.getPricesUnsafe (subscriptionId, emptyPriceIds);
721726 vm.stopPrank ();
722727
723728 // Verify the data is correct
@@ -726,6 +731,61 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
726731 "Price feeds verification failed "
727732 );
728733 }
734+
735+ function testGetEmaPriceUnsafe () public {
736+ // First add a subscription, funds, and update price feeds
737+ uint256 subscriptionId = addTestSubscription ();
738+ uint256 fundAmount = 1 ether ;
739+ scheduler.addFunds {value: fundAmount}(subscriptionId);
740+
741+ bytes32 [] memory priceIds = createPriceIds ();
742+ uint64 publishTime = SafeCast.toUint64 (block .timestamp );
743+ PythStructs.PriceFeed[] memory priceFeeds = createMockPriceFeeds (
744+ publishTime
745+ );
746+
747+ // Ensure EMA prices are set in the mock price feeds
748+ for (uint i = 0 ; i < priceFeeds.length ; i++ ) {
749+ priceFeeds[i].emaPrice.price = priceFeeds[i].price.price * 2 ; // Make EMA price different for testing
750+ priceFeeds[i].emaPrice.conf = priceFeeds[i].price.conf;
751+ priceFeeds[i].emaPrice.publishTime = publishTime;
752+ priceFeeds[i].emaPrice.expo = priceFeeds[i].price.expo;
753+ }
754+
755+ mockParsePriceFeedUpdates (pyth, priceFeeds);
756+ bytes [] memory updateData = createMockUpdateData (priceFeeds);
757+
758+ vm.prank (pusher);
759+ scheduler.updatePriceFeeds (subscriptionId, updateData, priceIds);
760+
761+ // Get EMA prices
762+ bytes32 [] memory emptyPriceIds = new bytes32 [](0 );
763+ PythStructs.Price[] memory emaPrices = scheduler.getEmaPriceUnsafe (
764+ subscriptionId,
765+ emptyPriceIds
766+ );
767+
768+ // Verify all EMA prices were returned
769+ assertEq (
770+ emaPrices.length ,
771+ priceIds.length ,
772+ "Should return all EMA prices "
773+ );
774+
775+ // Verify EMA price values
776+ for (uint i = 0 ; i < emaPrices.length ; i++ ) {
777+ assertEq (
778+ emaPrices[i].price,
779+ priceFeeds[i].emaPrice.price,
780+ "EMA price value mismatch "
781+ );
782+ assertEq (
783+ emaPrices[i].publishTime,
784+ priceFeeds[i].emaPrice.publishTime,
785+ "EMA price publish time mismatch "
786+ );
787+ }
788+ }
729789
730790 function testGetActiveSubscriptions () public {
731791 // Add multiple subscriptions with the test contract as manager
@@ -750,8 +810,8 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
750810 });
751811
752812 SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig ({
753- maxGasPrice: 100 gwei ,
754- maxGasLimit: 1_000_000
813+ maxGasMultiplierCapPct: 10_000 ,
814+ maxFeeMultiplierCapPct: 10_000
755815 });
756816
757817 SchedulerState.SubscriptionParams memory params = SchedulerState
@@ -770,8 +830,9 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
770830 vm.prank (owner);
771831 (
772832 uint256 [] memory activeIds ,
773- SchedulerState.SubscriptionParams[] memory activeParams
774- ) = scheduler.getActiveSubscriptions ();
833+ SchedulerState.SubscriptionParams[] memory activeParams ,
834+ uint256 totalCount
835+ ) = scheduler.getActiveSubscriptions (0 , 10 ); // Start at index 0, get up to 10 results
775836
776837 // Verify active subscriptions
777838 assertEq (activeIds.length , 3 , "Should have 3 active subscriptions " );
@@ -780,6 +841,11 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
780841 3 ,
781842 "Should have 3 active subscription params "
782843 );
844+ assertEq (
845+ totalCount,
846+ 3 ,
847+ "Total count should be 3 "
848+ );
783849
784850 // Verify subscription params
785851 for (uint i = 0 ; i < activeIds.length ; i++ ) {
@@ -800,6 +866,39 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
800866 "Heartbeat seconds mismatch "
801867 );
802868 }
869+
870+ // Test pagination - get only the first subscription
871+ vm.prank (owner);
872+ (
873+ uint256 [] memory firstPageIds ,
874+ SchedulerState.SubscriptionParams[] memory firstPageParams ,
875+ uint256 firstPageTotal
876+ ) = scheduler.getActiveSubscriptions (0 , 1 );
877+
878+ assertEq (firstPageIds.length , 1 , "Should have 1 subscription in first page " );
879+ assertEq (firstPageTotal, 3 , "Total count should still be 3 " );
880+
881+ // Test pagination - get the second page
882+ vm.prank (owner);
883+ (
884+ uint256 [] memory secondPageIds ,
885+ SchedulerState.SubscriptionParams[] memory secondPageParams ,
886+ uint256 secondPageTotal
887+ ) = scheduler.getActiveSubscriptions (1 , 2 );
888+
889+ assertEq (secondPageIds.length , 2 , "Should have 2 subscriptions in second page " );
890+ assertEq (secondPageTotal, 3 , "Total count should still be 3 " );
891+
892+ // Test pagination - start index beyond total count
893+ vm.prank (owner);
894+ (
895+ uint256 [] memory emptyPageIds ,
896+ SchedulerState.SubscriptionParams[] memory emptyPageParams ,
897+ uint256 emptyPageTotal
898+ ) = scheduler.getActiveSubscriptions (10 , 10 );
899+
900+ assertEq (emptyPageIds.length , 0 , "Should have 0 subscriptions when start index is beyond total " );
901+ assertEq (emptyPageTotal, 3 , "Total count should still be 3 " );
803902 }
804903
805904 // Helper function to add a test subscription
@@ -817,8 +916,8 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
817916 });
818917
819918 SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig ({
820- maxGasPrice: 100 gwei ,
821- maxGasLimit: 1_000_000
919+ maxGasMultiplierCapPct: 10_000 ,
920+ maxFeeMultiplierCapPct: 10_000
822921 });
823922
824923 SchedulerState.SubscriptionParams memory params = SchedulerState
@@ -850,8 +949,8 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
850949 });
851950
852951 SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig ({
853- maxGasPrice: 100 gwei ,
854- maxGasLimit: 1_000_000
952+ maxGasMultiplierCapPct: 10_000 ,
953+ maxFeeMultiplierCapPct: 10_000
855954 });
856955
857956 SchedulerState.SubscriptionParams memory params = SchedulerState
@@ -875,8 +974,8 @@ contract SchedulerTest is Test, SchedulerEvents, PulseTestUtils {
875974 readerWhitelist[0 ] = address (reader);
876975
877976 SchedulerState.GasConfig memory gasConfig = SchedulerState.GasConfig ({
878- maxGasPrice: 100 gwei ,
879- maxGasLimit: 1_000_000
977+ maxGasMultiplierCapPct: 10_000 ,
978+ maxFeeMultiplierCapPct: 10_000
880979 });
881980
882981 SchedulerState.SubscriptionParams memory params = SchedulerState
0 commit comments