Prechádzať zdrojové kódy

refactor: make emitter chain & post vaa program configurable

swimricky 2 rokov pred
rodič
commit
3478494842

+ 1 - 1
target_chains/solana/Anchor.toml

@@ -18,6 +18,6 @@ cli_build = "cargo build --package pyth-solana-receiver-cli --features devnet"
 
 
 cli_test_mainnet = "cargo run --package pyth-solana-receiver-cli --features mainnet post-and-receive-vaa -u https://api.mainnet-beta.solana.com -v UE5BVQEAAAADuAEAAAADDQAbXgddtAJnEhoLE4JAxcuyokAmnoTS4qSvkw0gJpNC+TtBZApwDqsQbCXgmYOuygk6QVsV1JpKYAUa72h95m0EAQNrHPMh1kCYvYyA/6J0qOp8nrtpzVFFoAagmMqJzKDmAV8MCVvpFuy5EPu69UO95UUnZZhX/hk4y7wdTfhedTYdAQR6SL0tbSGSlWHLSzs2wpWVx8N0RFtFULp9EkCSUnxAnma3UI/hFz/78fvtRp/qx1HT8M4/8zSEuVbwd8pdeBsvAQZoD/eilZ2nvs1eHoXKz7FhW3UxVCYUZbNnJmY/Iqc6hw6+7yIJ9sh1cKvWkI+ug1ZC9KiOK90/cxipRcbaa+9+AQd5SGi5/En6R/jIoNF+iqza6YbJht0CZ02NkcGl1LOU23sptShlj3rV8NbiP8n9hV995zVDpO4j4lxJRgEyveoKAQgOwavPcVLbTn45goFiKWw7qN+MALLOP42/j8g4am+1GU8+pwEWqWvyJX0Ja+sINXYzDuCmkIVRcTQ0KW+M6tjrAQpJJe4E6+cuA59wmC7sVn5EB3zL/ILaAR00viSmrZFIeTZwmFu/WXQDnM6KRdAydalvfLCFp69w7PXTsRZ6qZdcAQyMDRjaChbqarjOW1xDU2xa2RT0ZgZEphCdWjxhbeet+hdsjsSlR/EYjBZWiEPJybOcEHb8fHb0/IXk9HUstIC6AQ18kAn8R1EHEdpYQ/d91dE/fAyFw2ZdsoazNIO4A1wNMipxpZyt31XLpkSZwnIUpt65VpOzPjnfvo13cEO0JBGyAQ6MCCPDol1OWtcXcTyVV4nhjbKXf1HPaWXXe4Z3Z+4AdEf+o+020qlbqgHlZ78m10S63E3+EodWXRcFsjCWtYsZAQ9FcKjBl86Adz+MsTtRp/ixSVFn1C3YLgcJ0WXOur1LrSFY1Vx0L0/LE8UTkJDXjxr/Vjw9MJ+MO7636omRNf3WABEkYX/9G+cTxfg6IZYYR346LVwb/2DzoeGK+2leGriR7Wl2XWnoCRLzXAvMXRYVCOXvThf/tKOKT9tSNXaHdqabARIKYMpsCs8G3LEfi9M8wizeExT5NknDMPN1SLwimmvSf2EKFfujir9nPpZQ1Xfm1ZmycoGNM2UZaMrtRomrM9NeAGVcy4MAAAAAABrhAfrtrFhR4yubI7X5QRqMK6xKrj7U3XuBHdGnLqSqcQAAAAABlfAvAUFVV1YAAAAAAAabjpgAACcQ4m9pYxIYDwWSb17+tMjLME6z1owBAFUA5i32yLSoX+GmfbRNwS3l2zMPesZrctxliv7fD0pBW0MAAANQh+v0TQAAAABXLlbN////+AAAAABlXMuCAAAAAGVcy4IAAANY89SSgAAAAABcNVH+CnrtHqVfUZAj59jeC89ZKnqKwi74B/AarJjj0/XaRMzvndCZBCRp4O3CnbyoPb7CtEUsAMCzmXXT/QJrFiJoCVGC+Ept4uJzaIZi7gOgaefhMVFFe43MEVmHj17tWyDgL0yymOCPbv2+vINEkfK9P9PV2cjRGbo6LDGtSN9J0l3Ni3CwKjkpFlWw7/BQawHz7u8b9zgtwpVzkzQeWZr0UeJek937S8nxcNctJ8B2JyCzUY/1ocTDJTaia64Hha+JHscLjDj+BOOt"
-cli_test_devnet = "cargo run --package pyth-solana-receiver-cli --features devnet post-and-receive-vaa -u https://api.devnet.solana.com -v UE5BVQEAAAAAoAEAAAAAAQCeeKXuDxu9EGbfkvoMx8eN8NduvQcYMZGKG5uGIyGF1CNFK9Yer7XCnxtBKI7e4K+a1psXU7sf5FnoI8nx6vdzAWVeYaYAAAAAABrhAfrtrFhR4yubI7X5QRqMK6xKrj7U3XuBHdGnLqSqcQAAAAACQ0P8AUFVV1YAAAAAAAaxOqcAACcQOrsKoozp6g1+3rAM3jx7IZT5yucBAFUAY1TWhcJH8e/Db5Z2F77/ouvVqV2P/hfeRJhQXJIwZ7gAAAAAB7Qy1wAAAAAAApWk////+AAAAABlXmGlAAAAAGVeYaQAAAAAB7Ib2AAAAAAAAmiICj05zr0cjtpu9ob2FqfTCtiNsUeIYch4tEBsiPlkkG+oqxjxjZ+k/fCElwyv85cj7ZJUyTC7rQgq/SvRrH+FKjekRMlSt5vu27rfIL6TCnE3iK0DY5CDDTczidxcs7V1thabVZF2MeITDKEkTqpX5e/3CLomW+XAQ+MBQ78/zW0QnHOyG7gwhhjHVcIuHGlW9kNDIdM7C6GTT11Lq/N1eIDf63h3Vp0XdDtkZPRItrDAOYfOnDLobHufIirCf+lrGKNaj/gMjidf"
+cli_test_devnet = "cargo run --package pyth-solana-receiver-cli --features devnet post-and-receive-vaa -u https://api.devnet.solana.com -v UE5BVQEAAAAAoAEAAAAAAQDCFSTOZmeUWH7qzSEF+gukA+oi1gpOSHwfdAMJZE2VfSRWCR6xuNJ3pQ12oKAd3FoOS71rEoXSYj9igqY9h0b+AWVg8fgAAAAAABrhAfrtrFhR4yubI7X5QRqMK6xKrj7U3XuBHdGnLqSqcQAAAAACSXqUAUFVV1YAAAAAAAa3qo4AACcQRCsBJTS2/wlgw5ZORh6f8kWyQFwBAFUAY1TWhcJH8e/Db5Z2F77/ouvVqV2P/hfeRJhQXJIwZ7gAAAAACFUoLgAAAAAAAeq4////+AAAAABlYPH4AAAAAGVg8fYAAAAACFRuXAAAAAAAAo9UCvHCZxNgx7SdTwRXEO9ImUqEnl+3ZtuREFX7+JlVCL+VyVED/Nqj3EuPIZyB1U59wUNXfZ8wOQPkHaVqSaHVFRAc5Ku47JBjGktlArIRY15W7dnd8//UyOhRDsLaKQeF6bHh9cCOaHHn1aPoeaSHTCTa/Roe/uRZdaiCY9NeH69Y9DnB67+/x4Nm4hNqOV0HOuCzf52fxkh07RtkNVDNO6lhoG2TPRiAFgMfTKbL7Edf87SJPy5NZU3MXfGJax3Uqpe5DoYuIPSI"
 
 test = "anchor build -- --features devnet && cargo test-bpf --features devnet -- --show-output"

+ 7 - 4
target_chains/solana/cli/src/main.rs

@@ -179,12 +179,13 @@ fn main() -> Result<()> {
                                     rent: Rent::id(),
                                     clock: Clock::id(),
                                     system_program: system_program::ID,
-                                    wormhole_program: wormhole,
+                                    post_vaa_program: wormhole,
                                 }
                                 .to_account_metas(None);
                             let post_acc_update_data_vaa_ix_data =
                                 pyth_solana_receiver::instruction::PostAccumulatorUpdateVaa {
-                                    data: accumulator_update_data_only_vaa_bytes,
+                                    emitter_chain: wormhole::Chain::Pythnet.into(),
+                                    data:          accumulator_update_data_only_vaa_bytes,
                                 }
                                 .data();
                             let post_acc_update_data_vaa_ix = Instruction::new_with_bytes(
@@ -246,12 +247,14 @@ fn main() -> Result<()> {
                     println!("update_bytes_len: {}", update_bytes_len);
 
                     let post_updates_accounts = pyth_solana_receiver::accounts::PostUpdates {
-                        payer:      payer.pubkey(),
-                        posted_vaa: vaa_pubkey,
+                        payer:            payer.pubkey(),
+                        posted_vaa:       vaa_pubkey,
+                        post_vaa_program: wormhole,
                     }
                     .to_account_metas(None);
                     let post_updates_ix_data = pyth_solana_receiver::instruction::PostUpdates {
                         vaa_hash,
+                        emitter_chain: wormhole::Chain::Pythnet.into(),
                         price_updates: update_bytes,
                     }
                     .data();

+ 35 - 15
target_chains/solana/programs/pyth-solana-receiver/src/lib.rs

@@ -27,10 +27,6 @@ use {
     sha3::Digest,
     state::AnchorVaa,
     std::io::Write,
-    wormhole::Chain::{
-        self,
-        Pythnet,
-    },
     wormhole_anchor_sdk::{
         wormhole as wormhole_anchor,
         wormhole::SEED_PREFIX_POSTED_VAA,
@@ -64,6 +60,7 @@ pub mod pyth_solana_receiver {
     ///           all the data needed for postVaa can fit in one txn.
     pub fn post_accumulator_update_vaa(
         ctx: Context<PostAccUpdateDataVaa>,
+        emitter_chain: u16,
         data: Vec<u8>, // accumulatorUpdateData {vaa, updates: [] }
     ) -> Result<()> {
         // verify accumulator update data header
@@ -73,7 +70,11 @@ pub mod pyth_solana_receiver {
             Proof::WormholeMerkle { vaa, updates: _ } => {
                 let vaa: Vaa<&RawMessage> = serde_wormhole::from_slice(vaa.as_ref()).unwrap();
                 let (header, body): (Header, Body<&RawMessage>) = vaa.into();
-
+                require_eq!(
+                    <wormhole_sdk::Chain as Into<u16>>::into(body.emitter_chain),
+                    emitter_chain,
+                    ReceiverError::InvalidEmitterChain
+                );
                 let post_vaa_ix_data = PostVAAInstructionData {
                     version:            header.version,
                     guardian_set_index: header.guardian_set_index,
@@ -86,7 +87,7 @@ pub mod pyth_solana_receiver {
                     payload:            body.payload.to_vec(),
                 };
                 let post_vaa_ix = Instruction {
-                    program_id: ctx.accounts.wormhole_program.key(),
+                    program_id: ctx.accounts.post_vaa_program.key(),
                     accounts:   vec![
                         AccountMeta::new_readonly(ctx.accounts.guardian_set.key(), false),
                         AccountMeta::new_readonly(ctx.accounts.bridge_config.key(), false),
@@ -105,13 +106,29 @@ pub mod pyth_solana_receiver {
         Ok(())
     }
 
+    /// Verify the updates using the posted_vaa account
+    ///  * `vaa_hash` hash post of the post_vaa data to derive the address of the post_vaa account
+    ///  * `emitter_chain` expected emitter_chain from the post_vaa account
+    ///  * `price_updates` Vec of bytes for the updates to verify and post on-chain
+    ///
+    /// TODO:
+    ///    - use a `config` account that can only be modified by governance for checking emitter_chain
+    ///      and other constraints
+    ///
+
     #[allow(unused_variables)]
     pub fn post_updates(
         ctx: Context<PostUpdates>,
         vaa_hash: [u8; 32], // used for pda seeds
+        emitter_chain: u16,
         price_updates: Vec<Vec<u8>>,
     ) -> Result<()> {
         let vaa = &ctx.accounts.posted_vaa;
+        require_eq!(
+            vaa.emitter_chain(),
+            emitter_chain,
+            ReceiverError::InvalidEmitterChain
+        );
         let wh_message = WormholeMessage::try_from_bytes(vaa.payload.as_slice())
             .map_err(|_| ReceiverError::InvalidWormholeMessage)?;
         msg!("constructed wh_message {:?}", wh_message);
@@ -151,27 +168,29 @@ pub mod pyth_solana_receiver {
 }
 
 #[derive(Accounts)]
-#[instruction(vaa_hash: [u8; 32])]
+#[instruction(vaa_hash: [u8; 32], emitter_chain: u16)]
 pub struct PostUpdates<'info> {
     #[account(mut)]
-    pub payer:      Signer<'info>,
+    pub payer:            Signer<'info>,
     #[account(
-        constraint = Chain::from(posted_vaa.emitter_chain()) == Pythnet @ ReceiverError::InvalidEmitterChain,
         seeds = [
             SEED_PREFIX_POSTED_VAA,
             &vaa_hash
         ],
-        seeds::program = wormhole_anchor::program::Wormhole::id(),
+        seeds::program = post_vaa_program.key(),
         bump
     )]
-    pub posted_vaa: Box<Account<'info, AnchorVaa>>,
+    pub posted_vaa:       Box<Account<'info, AnchorVaa>>,
+    /// CHECK: program that called post_vaa
+    pub post_vaa_program: AccountInfo<'info>,
 }
 
 impl crate::accounts::PostUpdates {
-    pub fn populate(payer: &Pubkey, posted_vaa: &Pubkey) -> Self {
+    pub fn populate(payer: &Pubkey, posted_vaa: &Pubkey, post_vaa_program: &Pubkey) -> Self {
         crate::accounts::PostUpdates {
-            payer:      *payer,
-            posted_vaa: *posted_vaa,
+            payer:            *payer,
+            posted_vaa:       *posted_vaa,
+            post_vaa_program: *post_vaa_program,
         }
     }
 }
@@ -193,7 +212,8 @@ pub struct PostAccUpdateDataVaa<'info> {
     pub clock:            Sysvar<'info, Clock>,
     pub rent:             Sysvar<'info, Rent>,
     pub system_program:   Program<'info, System>,
-    pub wormhole_program: Program<'info, wormhole_anchor::program::Wormhole>,
+    /// CHECK: program that will call post_vaa
+    pub post_vaa_program: UncheckedAccount<'info>,
 }
 
 #[derive(Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize)]

+ 0 - 2
target_chains/solana/programs/pyth-solana-receiver/src/state.rs

@@ -12,8 +12,6 @@ use {
 impl Owner for AnchorVaa {
     fn owner() -> Pubkey {
         PostedVaaData::owner()
-        // // wormhole address on solana devnet
-        // Pubkey::from_str("3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5").unwrap()
     }
 }