@@ -300,6 +300,146 @@ describe('updateDataFeedsInLoop', () => {
300
300
} ) ;
301
301
} ) ;
302
302
303
+ describe ( 'updateBeacons' , ( ) => {
304
+ it ( 'calls updateBeaconWithSignedData in Api3ServerV1 contract for single beacon' , async ( ) => {
305
+ state . updateState ( ( currentState ) => ( {
306
+ ...currentState ,
307
+ beaconValues : {
308
+ '0x2ba0526238b0f2671b7981fd7a263730619c8e849a528088fd4a92350a8c2f2c' : validSignedData ,
309
+ '0xa5ddf304a7dcec62fa55449b7fe66b33339fd8b249db06c18423d5b0da7716c2' : undefined as any ,
310
+ '0x8fa9d00cb8f2d95b1299623d97a97696ed03d0e3350e4ea638f469beabcdabcd' : validSignedData ,
311
+ } ,
312
+ } ) ) ;
313
+
314
+ const txCountSpy = jest . spyOn ( ethers . providers . StaticJsonRpcProvider . prototype , 'getTransactionCount' ) ;
315
+ txCountSpy . mockResolvedValueOnce ( 212 ) ;
316
+
317
+ const timestamp = 1649664085 ;
318
+
319
+ const updateBeaconWithSignedDataMock = jest
320
+ . fn ( )
321
+ . mockReturnValueOnce ( { hash : ethers . utils . hexlify ( ethers . utils . randomBytes ( 32 ) ) } ) ;
322
+ const callStaticTryMulticallMock = jest . fn ( ) . mockReturnValueOnce ( {
323
+ successes : [ true , true ] ,
324
+ returndata : [
325
+ ethers . utils . defaultAbiCoder . encode ( [ 'int224' , 'uint32' ] , [ ethers . BigNumber . from ( 41000000000 ) , timestamp - 30 ] ) ,
326
+ ethers . utils . defaultAbiCoder . encode ( [ 'int224' , 'uint32' ] , [ ethers . BigNumber . from ( 40000000000 ) , timestamp ] ) ,
327
+ ] ,
328
+ } ) ;
329
+ jest . spyOn ( Api3ServerV1Factory , 'connect' ) . mockImplementation (
330
+ ( _dapiServerAddress , _provider ) =>
331
+ ( {
332
+ connect ( _signerOrProvider : ethers . Signer | ethers . providers . Provider | string ) {
333
+ return this ;
334
+ } ,
335
+ updateBeaconWithSignedData : updateBeaconWithSignedDataMock ,
336
+ interface : {
337
+ encodeFunctionData : ( functionFragment : string , values : [ any ] ) : string => {
338
+ if ( functionFragment === 'dataFeeds' )
339
+ return '0x67a7cfb741c3d6e0ee82ae3d33356c4dceb84e98d1a0b361db0f51081fc5a2541ae51683' ;
340
+
341
+ if ( functionFragment === 'readDataFeedWithId' ) {
342
+ switch ( values [ 0 ] ) {
343
+ case '0x2ba0526238b0f2671b7981fd7a263730619c8e849a528088fd4a92350a8c2f2c' :
344
+ return '0xa5fc076f2ba0526238b0f2671b7981fd7a263730619c8e849a528088fd4a92350a8c2f2c' ;
345
+ case '0xa5ddf304a7dcec62fa55449b7fe66b33339fd8b249db06c18423d5b0da7716c2' :
346
+ return '0xa5fc076fa5ddf304a7dcec62fa55449b7fe66b33339fd8b249db06c18423d5b0da7716c2' ;
347
+ case '0x8fa9d00cb8f2d95b1299623d97a97696ed03d0e3350e4ea638f469beabcdabcd' :
348
+ return '0xa5fc076f8fa9d00cb8f2d95b1299623d97a97696ed03d0e3350e4ea638f469beabcdabcd' ;
349
+ }
350
+ }
351
+
352
+ if ( functionFragment === 'updateBeaconWithSignedData' )
353
+ return '0x1a0a0b3e0000000000000000000000005656d3a378b1aadfddcf4196ea364a9d786172909ec34b00a5019442dcd05a4860ff2bf015164b368cb83fcb756088fcabcdabcd000000000000000000000000000000000000000000000000000000006253e05500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000009dc41b78000000000000000000000000000000000000000000000000000000000000000418aace553ec28f53cc976c8a2469d50f16de121d248495117aca36feb4950957827570e0648f82bdbc0afa6cb69dd9fe37dc7f9d58ae3aa06450e627e06c1b8031b00000000000000000000000000000000000000000000000000000000000000' ;
354
+
355
+ if ( functionFragment === 'updateBeaconSetWithBeacons' )
356
+ return '0x00aae33f00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002924b5d4cb3ec6366ae4302a1ca6aec035594ea3ea48a102d160b50b0c43ebfb5bf7ce55d109fd196de2a8bf1515d166c56c9decbe9cb473656bbca30d5743990' ;
357
+
358
+ return '' ;
359
+ } ,
360
+ } ,
361
+ callStatic : { tryMulticall : callStaticTryMulticallMock } ,
362
+ } as any )
363
+ ) ;
364
+
365
+ const groups = api . groupDataFeedsByProviderSponsor ( ) ;
366
+
367
+ await api . updateBeacons ( groups [ 0 ] , Date . now ( ) ) ;
368
+
369
+ expect ( callStaticTryMulticallMock ) . toHaveBeenCalledTimes ( 1 ) ;
370
+ expect ( updateBeaconWithSignedDataMock ) . toHaveBeenCalledTimes ( 1 ) ;
371
+ } ) ;
372
+
373
+ it ( 'calls tryMulticall in Api3ServerV1 contract for multiple beacon updates' , async ( ) => {
374
+ state . updateState ( ( currentState ) => ( {
375
+ ...currentState ,
376
+ beaconValues : {
377
+ '0x2ba0526238b0f2671b7981fd7a263730619c8e849a528088fd4a92350a8c2f2c' : validSignedData ,
378
+ '0xa5ddf304a7dcec62fa55449b7fe66b33339fd8b249db06c18423d5b0da7716c2' : validSignedData ,
379
+ '0x8fa9d00cb8f2d95b1299623d97a97696ed03d0e3350e4ea638f469beabcdabcd' : validSignedData ,
380
+ } ,
381
+ } ) ) ;
382
+
383
+ const txCountSpy = jest . spyOn ( ethers . providers . StaticJsonRpcProvider . prototype , 'getTransactionCount' ) ;
384
+ txCountSpy . mockResolvedValueOnce ( 212 ) ;
385
+
386
+ const timestamp = 1649664085 ;
387
+
388
+ const tryMulticallMock = jest
389
+ . fn ( )
390
+ . mockReturnValueOnce ( { hash : ethers . utils . hexlify ( ethers . utils . randomBytes ( 32 ) ) } ) ;
391
+ const callStaticTryMulticallMock = jest . fn ( ) . mockReturnValueOnce ( {
392
+ successes : [ true , true ] ,
393
+ returndata : [
394
+ ethers . utils . defaultAbiCoder . encode ( [ 'int224' , 'uint32' ] , [ ethers . BigNumber . from ( 41000000000 ) , timestamp - 30 ] ) ,
395
+ ethers . utils . defaultAbiCoder . encode ( [ 'int224' , 'uint32' ] , [ ethers . BigNumber . from ( 39000000000 ) , timestamp - 30 ] ) ,
396
+ ] ,
397
+ } ) ;
398
+ jest . spyOn ( Api3ServerV1Factory , 'connect' ) . mockImplementation (
399
+ ( _dapiServerAddress , _provider ) =>
400
+ ( {
401
+ connect ( _signerOrProvider : ethers . Signer | ethers . providers . Provider | string ) {
402
+ return this ;
403
+ } ,
404
+ tryMulticall : tryMulticallMock ,
405
+ interface : {
406
+ encodeFunctionData : ( functionFragment : string , values : [ any ] ) : string => {
407
+ if ( functionFragment === 'dataFeeds' )
408
+ return '0x67a7cfb741c3d6e0ee82ae3d33356c4dceb84e98d1a0b361db0f51081fc5a2541ae51683' ;
409
+
410
+ if ( functionFragment === 'readDataFeedWithId' ) {
411
+ switch ( values [ 0 ] ) {
412
+ case '0x2ba0526238b0f2671b7981fd7a263730619c8e849a528088fd4a92350a8c2f2c' :
413
+ return '0xa5fc076f2ba0526238b0f2671b7981fd7a263730619c8e849a528088fd4a92350a8c2f2c' ;
414
+ case '0xa5ddf304a7dcec62fa55449b7fe66b33339fd8b249db06c18423d5b0da7716c2' :
415
+ return '0xa5fc076fa5ddf304a7dcec62fa55449b7fe66b33339fd8b249db06c18423d5b0da7716c2' ;
416
+ case '0x8fa9d00cb8f2d95b1299623d97a97696ed03d0e3350e4ea638f469beabcdabcd' :
417
+ return '0xa5fc076f8fa9d00cb8f2d95b1299623d97a97696ed03d0e3350e4ea638f469beabcdabcd' ;
418
+ }
419
+ }
420
+
421
+ if ( functionFragment === 'updateBeaconWithSignedData' )
422
+ return '0x1a0a0b3e0000000000000000000000005656d3a378b1aadfddcf4196ea364a9d786172909ec34b00a5019442dcd05a4860ff2bf015164b368cb83fcb756088fcabcdabcd000000000000000000000000000000000000000000000000000000006253e05500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000009dc41b78000000000000000000000000000000000000000000000000000000000000000418aace553ec28f53cc976c8a2469d50f16de121d248495117aca36feb4950957827570e0648f82bdbc0afa6cb69dd9fe37dc7f9d58ae3aa06450e627e06c1b8031b00000000000000000000000000000000000000000000000000000000000000' ;
423
+
424
+ if ( functionFragment === 'updateBeaconSetWithBeacons' )
425
+ return '0x00aae33f00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002924b5d4cb3ec6366ae4302a1ca6aec035594ea3ea48a102d160b50b0c43ebfb5bf7ce55d109fd196de2a8bf1515d166c56c9decbe9cb473656bbca30d5743990' ;
426
+
427
+ return '' ;
428
+ } ,
429
+ } ,
430
+ callStatic : { tryMulticall : callStaticTryMulticallMock } ,
431
+ } as any )
432
+ ) ;
433
+
434
+ const groups = api . groupDataFeedsByProviderSponsor ( ) ;
435
+
436
+ await api . updateBeacons ( groups [ 0 ] , Date . now ( ) ) ;
437
+
438
+ expect ( callStaticTryMulticallMock ) . toHaveBeenCalledTimes ( 1 ) ;
439
+ expect ( tryMulticallMock ) . toHaveBeenCalledTimes ( 1 ) ;
440
+ } ) ;
441
+ } ) ;
442
+
303
443
describe ( 'updateBeaconSets' , ( ) => {
304
444
it ( 'calls updateBeaconSetWithBeacons in Api3ServerV1 contract' , async ( ) => {
305
445
state . updateState ( ( currentState ) => ( {
0 commit comments