@@ -15,15 +15,13 @@ use {
15
15
} ,
16
16
} ,
17
17
anyhow:: {
18
- anyhow,
19
- Context ,
20
- Result ,
18
+ anyhow, bail, Context , Result
21
19
} ,
22
20
bincode:: Options ,
23
- bytemuck:: cast_slice,
21
+ bytemuck:: { bytes_of , cast_slice} ,
24
22
chrono:: Utc ,
25
23
futures_util:: future:: join_all,
26
- pyth_price_publisher:: accounts:: publisher_prices :: PublisherPrice ,
24
+ pyth_price_publisher:: accounts:: buffer :: BufferedPrice ,
27
25
pyth_sdk:: Identifier ,
28
26
pyth_sdk_solana:: state:: PriceStatus ,
29
27
serde:: Serialize ,
@@ -451,6 +449,7 @@ pub async fn publish_batches<S>(
451
449
publish_keypair : & Keypair ,
452
450
oracle_program_key : Pubkey ,
453
451
publish_program_key : Option < Pubkey > ,
452
+ publisher_buffer_key : Option < Pubkey > ,
454
453
max_batch_size : usize ,
455
454
staleness_threshold : Duration ,
456
455
compute_unit_limit : u32 ,
@@ -489,6 +488,7 @@ where
489
488
publish_keypair,
490
489
oracle_program_key,
491
490
publish_program_key,
491
+ publisher_buffer_key,
492
492
batch,
493
493
staleness_threshold,
494
494
compute_unit_limit,
@@ -533,6 +533,7 @@ async fn publish_batch<S>(
533
533
publish_keypair : & Keypair ,
534
534
oracle_program_key : Pubkey ,
535
535
publish_program_key : Option < Pubkey > ,
536
+ publisher_buffer_key : Option < Pubkey > ,
536
537
batch : & [ PermissionedUpdate ] ,
537
538
staleness_threshold : Duration ,
538
539
compute_unit_limit : u32 ,
@@ -576,35 +577,36 @@ where
576
577
}
577
578
578
579
if let Some ( publish_program_key) = publish_program_key {
579
- let ( instruction, unsupported_updates ) = create_instruction_with_publish_program (
580
+ let instruction = create_instruction_with_publish_program (
580
581
publish_keypair. pubkey ( ) ,
581
582
publish_program_key,
583
+ publisher_buffer_key. context ( "must specify publisher_buffer_key if publish_program_key is specified" ) ?,
582
584
updates,
583
585
) ?;
584
- updates = unsupported_updates;
585
- instructions. push ( instruction) ;
586
- }
587
- for update in updates {
588
- let instruction = if let Some ( accumulator_program_key) = accumulator_key {
589
- create_instruction_with_accumulator (
590
- publish_keypair. pubkey ( ) ,
591
- oracle_program_key,
592
- Pubkey :: from ( update. feed_id . to_bytes ( ) ) ,
593
- & update. info ,
594
- network_state. current_slot ,
595
- accumulator_program_key,
596
- ) ?
597
- } else {
598
- create_instruction_without_accumulator (
599
- publish_keypair. pubkey ( ) ,
600
- oracle_program_key,
601
- Pubkey :: from ( update. feed_id . to_bytes ( ) ) ,
602
- & update. info ,
603
- network_state. current_slot ,
604
- ) ?
605
- } ;
606
-
607
586
instructions. push ( instruction) ;
587
+ } else {
588
+ for update in updates {
589
+ let instruction = if let Some ( accumulator_program_key) = accumulator_key {
590
+ create_instruction_with_accumulator (
591
+ publish_keypair. pubkey ( ) ,
592
+ oracle_program_key,
593
+ Pubkey :: from ( update. feed_id . to_bytes ( ) ) ,
594
+ & update. info ,
595
+ network_state. current_slot ,
596
+ accumulator_program_key,
597
+ ) ?
598
+ } else {
599
+ create_instruction_without_accumulator (
600
+ publish_keypair. pubkey ( ) ,
601
+ oracle_program_key,
602
+ Pubkey :: from ( update. feed_id . to_bytes ( ) ) ,
603
+ & update. info ,
604
+ network_state. current_slot ,
605
+ ) ?
606
+ } ;
607
+
608
+ instructions. push ( instruction) ;
609
+ }
608
610
}
609
611
610
612
// Pay priority fees, if configured
@@ -800,28 +802,31 @@ fn create_instruction_without_accumulator(
800
802
fn create_instruction_with_publish_program (
801
803
publish_pubkey : Pubkey ,
802
804
publish_program_key : Pubkey ,
805
+ publisher_buffer_key : Pubkey ,
803
806
prices : Vec < PermissionedUpdate > ,
804
- ) -> Result < ( Instruction , Vec < PermissionedUpdate > ) > {
805
- let mut unsupported_updates = Vec :: new ( ) ;
806
- let ( buffer_key , _buffer_bump ) = Pubkey :: find_program_address (
807
- & [ "BUFFER" . as_bytes ( ) , & publish_pubkey. to_bytes ( ) ] ,
807
+ ) -> Result < Instruction > {
808
+ use pyth_price_publisher :: instruction :: { Instruction as PublishInstruction , SubmitPricesArgsHeader , PUBLISHER_CONFIG_SEED } ;
809
+ let ( publisher_config_key , publisher_config_bump ) = Pubkey :: find_program_address (
810
+ & [ PUBLISHER_CONFIG_SEED . as_bytes ( ) , & publish_pubkey. to_bytes ( ) ] ,
808
811
& publish_program_key,
809
812
) ;
810
813
811
814
let mut values = Vec :: new ( ) ;
812
815
for update in prices {
813
816
if update. feed_index == 0 {
814
- unsupported_updates. push ( update) ;
815
- } else {
816
- values. push ( PublisherPrice :: new (
817
- update. feed_index ,
818
- ( update. info . status as u8 ) . into ( ) ,
819
- update. info . price ,
820
- update. info . conf ,
821
- ) ?) ;
817
+ bail ! ( "no feed index for feed {:?}" , update. feed_id) ;
822
818
}
819
+ values. push ( BufferedPrice :: new (
820
+ update. feed_index ,
821
+ ( update. info . status as u8 ) . into ( ) ,
822
+ update. info . price ,
823
+ update. info . conf ,
824
+ ) ?) ;
823
825
}
824
- let mut data = vec ! [ 1 ] ;
826
+ let mut data = vec ! [ PublishInstruction :: SubmitPrices as u8 ] ;
827
+ data. extend_from_slice ( bytes_of ( & SubmitPricesArgsHeader {
828
+ publisher_config_bump,
829
+ } ) ) ;
825
830
data. extend ( cast_slice ( & values) ) ;
826
831
827
832
let instruction = Instruction {
@@ -833,14 +838,19 @@ fn create_instruction_with_publish_program(
833
838
is_writable: true ,
834
839
} ,
835
840
AccountMeta {
836
- pubkey: buffer_key,
841
+ pubkey: publisher_config_key,
842
+ is_signer: false ,
843
+ is_writable: false ,
844
+ } ,
845
+ AccountMeta {
846
+ pubkey: publisher_buffer_key,
837
847
is_signer: false ,
838
848
is_writable: true ,
839
849
} ,
840
850
] ,
841
851
data,
842
852
} ;
843
- Ok ( ( instruction, unsupported_updates ) )
853
+ Ok ( instruction)
844
854
}
845
855
846
856
fn create_instruction_with_accumulator (
0 commit comments