11use {
2- anchor_lang:: { prelude:: Clock , AccountDeserialize } ,
2+ crate :: Storage ,
3+ anchor_lang:: {
4+ prelude:: { borsh, AccountInfo , Clock , ProgramError , Pubkey , SolanaSysvar } ,
5+ solana_program:: { ed25519_program, pubkey:: PUBKEY_BYTES , sysvar} ,
6+ AnchorDeserialize , AnchorSerialize ,
7+ } ,
38 bytemuck:: { cast_slice, checked:: try_cast_slice, Pod , Zeroable } ,
49 byteorder:: { ByteOrder , LE } ,
5- solana_program:: {
6- account_info:: AccountInfo ,
7- ed25519_program,
8- program_error:: ProgramError ,
9- pubkey:: PUBKEY_BYTES ,
10- sysvar:: { self , Sysvar } ,
11- } ,
1210 thiserror:: Error ,
1311} ;
1412
@@ -44,33 +42,32 @@ pub struct Ed25519SignatureOffsets {
4442 pub message_instruction_index : u16 ,
4543}
4644
47- /// Sets up `Ed25519SignatureOffsets` for verifying the Pyth Lazer message signature.
48- /// - `instruction_data` must be the *full* input data for your contract's instruction.
49- /// - `instruction_index` is the index of that instruction within the transaction.
50- /// - `starting_offset` is the offset of the Pyth Lazer message within the instruction data.
51- ///
52- /// Panics if `starting_offset` is invalid or the `instruction_data` is not long enough to
53- /// contain the message.
54- pub fn signature_offsets (
55- instruction_data : & [ u8 ] ,
56- instruction_index : u16 ,
57- starting_offset : u16 ,
58- ) -> Ed25519SignatureOffsets {
59- let signature_offset = starting_offset + MAGIC_LEN ;
60- let public_key_offset = signature_offset + SIGNATURE_LEN ;
61- let message_data_size_offset = public_key_offset + PUBKEY_LEN ;
62- let message_data_offset = message_data_size_offset + MESSAGE_SIZE_LEN ;
63- let message_data_size = LE :: read_u16 (
64- & instruction_data[ message_data_size_offset. into ( ) ..message_data_offset. into ( ) ] ,
65- ) ;
66- Ed25519SignatureOffsets {
67- signature_offset,
68- signature_instruction_index : instruction_index,
69- public_key_offset,
70- public_key_instruction_index : instruction_index,
71- message_data_offset,
72- message_data_size,
73- message_instruction_index : instruction_index,
45+ impl Ed25519SignatureOffsets {
46+ /// Sets up `Ed25519SignatureOffsets` for verifying the Pyth Lazer message signature.
47+ /// - `message` is the Pyth Lazer message being sent.
48+ /// - `instruction_index` is the index of that instruction within the transaction.
49+ /// - `starting_offset` is the offset of the Pyth Lazer message within the instruction data.
50+ ///
51+ /// Panics if `starting_offset` is invalid or the `instruction_data` is not long enough to
52+ /// contain the message.
53+ pub fn new ( message : & [ u8 ] , instruction_index : u16 , starting_offset : u16 ) -> Self {
54+ let signature_offset = starting_offset + MAGIC_LEN ;
55+ let public_key_offset = signature_offset + SIGNATURE_LEN ;
56+ let message_data_size_offset = public_key_offset + PUBKEY_LEN ;
57+ let message_data_offset = message_data_size_offset + MESSAGE_SIZE_LEN ;
58+ let message_data_size = LE :: read_u16 (
59+ & message[ ( message_data_size_offset - starting_offset) . into ( )
60+ ..( message_data_offset - starting_offset) . into ( ) ] ,
61+ ) ;
62+ Ed25519SignatureOffsets {
63+ signature_offset,
64+ signature_instruction_index : instruction_index,
65+ public_key_offset,
66+ public_key_instruction_index : instruction_index,
67+ message_data_offset,
68+ message_data_size,
69+ message_instruction_index : instruction_index,
70+ }
7471 }
7572}
7673
@@ -86,12 +83,12 @@ pub fn ed25519_program_args(signatures: &[Ed25519SignatureOffsets]) -> Vec<u8> {
8683}
8784
8885/// A message with a verified ed25519 signature.
89- #[ derive( Debug , Clone , Copy ) ]
90- pub struct VerifiedMessage < ' a > {
86+ #[ derive( Debug , Clone , AnchorSerialize , AnchorDeserialize ) ]
87+ pub struct VerifiedMessage {
9188 /// Public key that signed the message.
92- pub public_key : & ' a [ u8 ] ,
89+ pub public_key : Pubkey ,
9390 /// Signed message payload.
94- pub payload : & ' a [ u8 ] ,
91+ pub payload : Vec < u8 > ,
9592}
9693
9794#[ derive( Debug , Error ) ]
@@ -145,6 +142,12 @@ impl From<SignatureVerificationError> for ProgramError {
145142 }
146143}
147144
145+ impl From < SignatureVerificationError > for anchor_lang:: error:: Error {
146+ fn from ( value : SignatureVerificationError ) -> Self {
147+ ProgramError :: from ( value) . into ( )
148+ }
149+ }
150+
148151/// Verifies a ed25519 signature on Solana by checking that the transaction contains
149152/// a correct call to the built-in `ed25519_program`.
150153///
@@ -154,24 +157,14 @@ impl From<SignatureVerificationError> for ProgramError {
154157/// - `signature_index` is the index of the signature within the inputs to the `ed25519_program`.
155158/// - `message_offset` is the offset of the signed message within the
156159/// input data for the current instruction.
157- pub fn verify_message < ' a > (
158- pyth_storage_account : & AccountInfo ,
160+ pub fn verify_message (
161+ storage : & Storage ,
159162 instruction_sysvar : & AccountInfo ,
160- message_data : & ' a [ u8 ] ,
163+ message_data : & [ u8 ] ,
161164 ed25519_instruction_index : u16 ,
162165 signature_index : u8 ,
163166 message_offset : u16 ,
164- ) -> Result < VerifiedMessage < ' a > , SignatureVerificationError > {
165- if pyth_storage_account. key != & pyth_lazer_solana_contract:: storage:: ID {
166- return Err ( SignatureVerificationError :: InvalidStorageAccountId ) ;
167- }
168- let storage = {
169- let storage_data = pyth_storage_account. data . borrow ( ) ;
170- let mut storage_data: & [ u8 ] = * storage_data;
171- pyth_lazer_solana_contract:: Storage :: try_deserialize ( & mut storage_data)
172- . map_err ( |_| SignatureVerificationError :: InvalidStorageData ) ?
173- } ;
174-
167+ ) -> Result < VerifiedMessage , SignatureVerificationError > {
175168 const SOLANA_FORMAT_MAGIC_LE : u32 = 2182742457 ;
176169
177170 let self_instruction_index =
@@ -300,7 +293,7 @@ pub fn verify_message<'a>(
300293 } ;
301294
302295 Ok ( VerifiedMessage {
303- public_key,
304- payload,
296+ public_key : Pubkey :: new_from_array ( public_key . try_into ( ) . unwrap ( ) ) ,
297+ payload : payload . to_vec ( ) ,
305298 } )
306299}
0 commit comments