Pārlūkot izejas kodu

Remove InstructionContext::verify. Verify in handlers

Change-Id: I661308951de261bff572398b6834523563906907
Reisen 4 gadi atpakaļ
vecāks
revīzija
108a4a2ff9

+ 19 - 51
solana/bridge/program/src/api/governance.rs

@@ -2,7 +2,6 @@ use solitaire::*;
 
 use solana_program::{
     program::invoke_signed,
-    pubkey::Pubkey,
     sysvar::{
         clock::Clock,
         rent::Rent,
@@ -21,7 +20,6 @@ use crate::{
     },
     error::Error::{
         InvalidFeeRecipient,
-        InvalidGovernanceKey,
         InvalidGovernanceWithdrawal,
         InvalidGuardianSetUpgrade,
     },
@@ -31,32 +29,9 @@ use crate::{
         GovernancePayloadTransferFees,
         GovernancePayloadUpgrade,
     },
-    vaa::{
-        ClaimableVAA,
-        DeserializePayload,
-    },
-    CHAIN_ID_SOLANA,
+    vaa::ClaimableVAA,
 };
 
-// Confirm that a ClaimableVAA came from the correct chain, signed by the right emitter.
-fn verify_claim<'a, T>(vaa: &ClaimableVAA<'a, T>) -> Result<()>
-where
-    T: DeserializePayload,
-{
-    let expected_emitter = std::env!("EMITTER_ADDRESS");
-    let current_emitter = format!(
-        "{}",
-        Pubkey::new_from_array(vaa.message.meta().emitter_address)
-    );
-
-    // Fail if the emitter is not the known governance key, or the emitting chain is not Solana.
-    if expected_emitter != current_emitter || vaa.message.meta().emitter_chain != CHAIN_ID_SOLANA {
-        Err(InvalidGovernanceKey.into())
-    } else {
-        Ok(())
-    }
-}
-
 #[derive(FromAccounts)]
 pub struct UpgradeContract<'b> {
     /// Payer for account creation (vaa-claim)
@@ -101,8 +76,7 @@ pub fn upgrade_contract(
     accs: &mut UpgradeContract,
     _data: UpgradeContractData,
 ) -> Result<()> {
-    verify_claim(&accs.vaa)?;
-
+    accs.vaa.verify(ctx.program_id)?;
     accs.vaa.claim(ctx, accs.payer.key)?;
 
     let upgrade_ix = solana_program::bpf_loader_upgradeable::upgrade(
@@ -141,17 +115,6 @@ pub struct UpgradeGuardianSet<'b> {
 }
 
 impl<'b> InstructionContext<'b> for UpgradeGuardianSet<'b> {
-    fn verify(&self, _program_id: &Pubkey) -> Result<()> {
-        if self.guardian_set_old.index != self.vaa.new_guardian_set_index - 1 {
-            return Err(InvalidGuardianSetUpgrade.into());
-        }
-
-        if self.bridge.guardian_set_index != self.vaa.new_guardian_set_index - 1 {
-            return Err(InvalidGuardianSetUpgrade.into());
-        }
-
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize, Default)]
@@ -162,8 +125,17 @@ pub fn upgrade_guardian_set(
     accs: &mut UpgradeGuardianSet,
     _data: UpgradeGuardianSetData,
 ) -> Result<()> {
-    verify_claim(&accs.vaa)?;
+    // Enforce single increments when upgrading.
+    if accs.guardian_set_old.index != accs.vaa.new_guardian_set_index - 1 {
+        return Err(InvalidGuardianSetUpgrade.into());
+    }
+
+    // Confirm that the version the bridge has active is the previous version.
+    if accs.bridge.guardian_set_index != accs.vaa.new_guardian_set_index - 1 {
+        return Err(InvalidGuardianSetUpgrade.into());
+    }
 
+    accs.vaa.verify(ctx.program_id)?;
     accs.guardian_set_old.verify_derivation(
         ctx.program_id,
         &GuardianSetDerivationData {
@@ -224,10 +196,8 @@ impl<'b> InstructionContext<'b> for SetFees<'b> {
 pub struct SetFeesData {}
 
 pub fn set_fees(ctx: &ExecutionContext, accs: &mut SetFees, _data: SetFeesData) -> Result<()> {
-    verify_claim(&accs.vaa)?;
-
+    accs.vaa.verify(ctx.program_id)?;
     accs.vaa.claim(ctx, accs.payer.key)?;
-
     accs.bridge.config.fee = accs.vaa.fee.as_u64();
 
     Ok(())
@@ -255,13 +225,6 @@ pub struct TransferFees<'b> {
 }
 
 impl<'b> InstructionContext<'b> for TransferFees<'b> {
-    fn verify(&self, _program_id: &Pubkey) -> Result<()> {
-        if self.vaa.to != self.recipient.key.to_bytes() {
-            return Err(InvalidFeeRecipient.into());
-        }
-
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize, Default)]
@@ -272,7 +235,12 @@ pub fn transfer_fees(
     accs: &mut TransferFees,
     _data: TransferFeesData,
 ) -> Result<()> {
-    verify_claim(&accs.vaa)?;
+    // Make sure the account loaded to receive funds is equal to the one the VAA requested.
+    if accs.vaa.to != accs.recipient.key.to_bytes() {
+        return Err(InvalidFeeRecipient.into());
+    }
+
+    accs.vaa.verify(ctx.program_id)?;
 
     if accs
         .fee_collector

+ 2 - 5
solana/bridge/program/src/api/post_message.rs

@@ -15,7 +15,6 @@ use crate::{
     CHAIN_ID_SOLANA,
 };
 use solana_program::{
-    pubkey::Pubkey,
     sysvar::clock::Clock,
 };
 use solitaire::{
@@ -59,10 +58,6 @@ pub struct PostMessage<'b> {
 }
 
 impl<'b> InstructionContext<'b> for PostMessage<'b> {
-    fn verify(&self, program_id: &Pubkey) -> Result<()> {
-        self.sequence.verify_derivation(program_id, &self.into())?;
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize)]
@@ -86,6 +81,8 @@ pub fn post_message(
     trace!("Emitter Address: {}", accs.emitter.info().key);
     trace!("Nonce: {}", data.nonce);
 
+    accs.sequence.verify_derivation(ctx.program_id, &(&*accs).into())?;
+
     let msg_derivation = MessageDerivationData {
         emitter_key: accs.emitter.key.to_bytes(),
         emitter_chain: CHAIN_ID_SOLANA,

+ 1 - 7
solana/bridge/program/src/api/post_vaa.rs

@@ -30,10 +30,7 @@ use byteorder::{
     WriteBytesExt,
 };
 use sha3::Digest;
-use solana_program::{
-    program_error::ProgramError,
-    pubkey::Pubkey,
-};
+use solana_program::program_error::ProgramError;
 use solitaire::{
     processors::seeded::Seeded,
     CreationLamports::Exempt,
@@ -77,9 +74,6 @@ pub struct PostVAA<'b> {
 }
 
 impl<'b> InstructionContext<'b> for PostVAA<'b> {
-    fn verify(&self, _program_id: &Pubkey) -> Result<()> {
-        Ok(())
-    }
 }
 
 #[derive(Default, BorshSerialize, BorshDeserialize)]

+ 18 - 5
solana/bridge/program/src/vaa.rs

@@ -6,6 +6,7 @@ use crate::{
     error::Error::{
         InvalidGovernanceAction,
         InvalidGovernanceChain,
+        InvalidGovernanceKey,
         InvalidGovernanceModule,
         VAAAlreadyExecuted,
     },
@@ -25,7 +26,6 @@ use solitaire::{
     CreationLamports::Exempt,
     Data,
     ExecutionContext,
-    InstructionContext,
     Peel,
     SolitaireError,
     *,
@@ -158,12 +158,25 @@ impl<'b, T: DeserializePayload> Deref for ClaimableVAA<'b, T> {
     }
 }
 
-impl<'b, T: DeserializePayload> InstructionContext<'b> for ClaimableVAA<'b, T> {
-    fn verify(&self, program_id: &Pubkey) -> Result<()> {
+impl<'b, T: DeserializePayload> ClaimableVAA<'b, T> {
+    pub fn verify(&self, program_id: &Pubkey) -> Result<()> {
+        trace!("Seq: {}", self.message.meta().sequence);
+
         // Do the Posted Message verification
+        let (expected_emitter, current_emitter) = (
+            std::env!("EMITTER_ADDRESS"),
+            format!(
+                "{}",
+                Pubkey::new_from_array(self.message.meta().emitter_address)
+            ),
+        );
+
+        // Fail if the emitter is not the known governance key, or the emitting chain is not Solana.
+        if expected_emitter != current_emitter || self.message.meta().emitter_chain != CHAIN_ID_SOLANA {
+            return Err(InvalidGovernanceKey.into());
+        }
 
         // Verify that the claim account is derived correctly
-        trace!("Seq: {}", self.message.meta().sequence);
         self.claim.verify_derivation(
             program_id,
             &ClaimDerivationData {
@@ -272,4 +285,4 @@ impl VAA {
 
         Ok(v)
     }
-}
+}

+ 0 - 4
solana/bridge/program_stub/src/api/post_vaa.rs

@@ -18,7 +18,6 @@ use bridge::{
     },
     CHAIN_ID_SOLANA,
 };
-use solana_program::pubkey::Pubkey;
 use solitaire::{
     processors::seeded::Seeded,
     CreationLamports::Exempt,
@@ -54,9 +53,6 @@ pub struct PostVAA<'b> {
 }
 
 impl<'b> InstructionContext<'b> for PostVAA<'b> {
-    fn verify(&self, _program_id: &Pubkey) -> Result<()> {
-        Ok(())
-    }
 }
 
 #[derive(Default, BorshSerialize, BorshDeserialize)]

+ 0 - 3
solana/modules/token_bridge/program/src/api/attest.rs

@@ -78,9 +78,6 @@ pub struct AttestToken<'b> {
 }
 
 impl<'b> InstructionContext<'b> for AttestToken<'b> {
-    fn verify(&self, _: &Pubkey) -> Result<()> {
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize, Default)]

+ 41 - 43
solana/modules/token_bridge/program/src/api/complete_transfer.rs

@@ -71,35 +71,6 @@ impl<'a> From<&CompleteNative<'a>> for CustodyAccountDerivationData {
 }
 
 impl<'b> InstructionContext<'b> for CompleteNative<'b> {
-    fn verify(&self, program_id: &Pubkey) -> Result<()> {
-        // Verify the chain registration
-        self.chain_registration
-            .verify_derivation(program_id, &(self.into()))?;
-
-        // Verify that the custody account is derived correctly
-        self.custody.verify_derivation(program_id, &(self.into()))?;
-
-        // Verify mints
-        if self.mint.info().key != self.to.info().key {
-            return Err(InvalidMint.into());
-        }
-        if self.mint.info().key != self.custody.info().key {
-            return Err(InvalidMint.into());
-        }
-        if &self.custody.owner != self.custody_signer.key {
-            return Err(InvalidMint.into());
-        }
-
-        // Verify VAA
-        if self.vaa.token_address != self.mint.info().key.to_bytes() {
-            return Err(InvalidMint.into());
-        }
-        if self.vaa.token_chain != 1 {
-            return Err(InvalidChain.into());
-        }
-
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize, Default)]
@@ -110,6 +81,33 @@ pub fn complete_native(
     accs: &mut CompleteNative,
     data: CompleteNativeData,
 ) -> Result<()> {
+    // Verify the chain registration
+    let derivation_data: EndpointDerivationData = (&*accs).into();
+    accs.chain_registration.verify_derivation(ctx.program_id, &derivation_data)?;
+
+    // Verify that the custody account is derived correctly
+    let derivation_data: CustodyAccountDerivationData = (&*accs).into();
+    accs.custody.verify_derivation(ctx.program_id, &derivation_data)?;
+
+    // Verify mints
+    if accs.mint.info().key != accs.to.info().key {
+        return Err(InvalidMint.into());
+    }
+    if accs.mint.info().key != accs.custody.info().key {
+        return Err(InvalidMint.into());
+    }
+    if &accs.custody.owner != accs.custody_signer.key {
+        return Err(InvalidMint.into());
+    }
+
+    // Verify VAA
+    if accs.vaa.token_address != accs.mint.info().key.to_bytes() {
+        return Err(InvalidMint.into());
+    }
+    if accs.vaa.token_chain != 1 {
+        return Err(InvalidChain.into());
+    }
+
     // Prevent vaa double signing
     accs.vaa.claim(ctx, accs.payer.key)?;
 
@@ -171,20 +169,6 @@ impl<'a> From<&CompleteWrapped<'a>> for WrappedDerivationData {
 }
 
 impl<'b> InstructionContext<'b> for CompleteWrapped<'b> {
-    fn verify(&self, program_id: &Pubkey) -> Result<()> {
-        // Verify the chain registration
-        self.chain_registration
-            .verify_derivation(program_id, &(self.into()))?;
-
-        // Verify mint
-        self.mint.verify_derivation(program_id, &(self.into()))?;
-
-        // Verify mints
-        if self.mint.info().key != self.to.info().key {
-            return Err(InvalidMint.into());
-        }
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize, Default)]
@@ -195,6 +179,20 @@ pub fn complete_wrapped(
     accs: &mut CompleteWrapped,
     data: CompleteWrappedData,
 ) -> Result<()> {
+    // Verify the chain registration
+    let derivation_data: EndpointDerivationData = (&*accs).into();
+    accs.chain_registration
+        .verify_derivation(ctx.program_id, &derivation_data)?;
+
+    // Verify mint
+    let derivation_data: WrappedDerivationData = (&*accs).into();
+    accs.mint.verify_derivation(ctx.program_id, &derivation_data)?;
+
+    // Verify mints
+    if accs.mint.info().key != accs.to.info().key {
+        return Err(InvalidMint.into());
+    }
+
     accs.vaa.claim(ctx, accs.payer.key)?;
 
     // Mint tokens

+ 7 - 8
solana/modules/token_bridge/program/src/api/create_wrapped.rs

@@ -72,14 +72,6 @@ impl<'a> From<&CreateWrapped<'a>> for WrappedDerivationData {
 }
 
 impl<'b> InstructionContext<'b> for CreateWrapped<'b> {
-    fn verify(&self, program_id: &Pubkey) -> Result<()> {
-        self.mint.verify_derivation(program_id, &(self.into()))?;
-        self.meta.verify_derivation(program_id, &(self.into()))?;
-        self.chain_registration
-            .verify_derivation(program_id, &(self.into()))?;
-
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize, Default)]
@@ -90,6 +82,13 @@ pub fn create_wrapped(
     accs: &mut CreateWrapped,
     data: CreateWrappedData,
 ) -> Result<()> {
+    let derivation_data: WrappedDerivationData = (&*accs).into();
+    accs.mint.verify_derivation(ctx.program_id, &derivation_data)?;
+    accs.meta.verify_derivation(ctx.program_id, &derivation_data)?;
+
+    let derivation_data: EndpointDerivationData = (&*accs).into();
+    accs.chain_registration.verify_derivation(ctx.program_id, &derivation_data)?;
+
     accs.vaa.claim(ctx, accs.payer.key)?;
 
     // Create mint account

+ 3 - 4
solana/modules/token_bridge/program/src/api/governance.rs

@@ -140,10 +140,6 @@ impl<'a> From<&RegisterChain<'a>> for EndpointDerivationData {
 }
 
 impl<'b> InstructionContext<'b> for RegisterChain<'b> {
-    fn verify(&self, program_id: &Pubkey) -> Result<()> {
-        self.endpoint.verify_derivation(program_id, &self.into())?;
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize, Default)]
@@ -154,6 +150,9 @@ pub fn register_chain(
     accs: &mut RegisterChain,
     data: RegisterChainData,
 ) -> Result<()> {
+    let derivation_data: EndpointDerivationData = (&*accs).into();
+    accs.endpoint.verify_derivation(ctx.program_id, &derivation_data)?;
+
     // Claim VAA
     accs.vaa.claim(ctx, accs.payer.key)?;
 

+ 30 - 35
solana/modules/token_bridge/program/src/api/transfer.rs

@@ -105,24 +105,6 @@ impl<'a> From<&TransferNative<'a>> for CustodyAccountDerivationData {
 }
 
 impl<'b> InstructionContext<'b> for TransferNative<'b> {
-    fn verify(&self, program_id: &Pubkey) -> Result<()> {
-        // Verify that the custody account is derived correctly
-        self.custody.verify_derivation(program_id, &self.into())?;
-
-        // Verify mints
-        if self.mint.info().key != self.from.info().key {
-            return Err(TokenBridgeError::InvalidMint.into());
-        }
-
-        // Verify that the token is not a wrapped token
-        if let COption::Some(mint_authority) = self.mint.mint_authority {
-            if mint_authority == MintSigner::key(None, program_id) {
-                return Err(TokenBridgeError::TokenNotNative.into());
-            }
-        }
-
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize, Default)]
@@ -139,6 +121,22 @@ pub fn transfer_native(
     accs: &mut TransferNative,
     data: TransferNativeData,
 ) -> Result<()> {
+    // Verify that the custody account is derived correctly
+    let derivation_data: CustodyAccountDerivationData = (&*accs).into();
+    accs.custody.verify_derivation(ctx.program_id, &derivation_data)?;
+
+    // Verify mints
+    if accs.mint.info().key != accs.from.info().key {
+        return Err(TokenBridgeError::InvalidMint.into());
+    }
+
+    // Verify that the token is not a wrapped token
+    if let COption::Some(mint_authority) = accs.mint.mint_authority {
+        if mint_authority == MintSigner::key(None, ctx.program_id) {
+            return Err(TokenBridgeError::TokenNotNative.into());
+        }
+    }
+
     if !accs.custody.is_initialized() {
         accs.custody
             .create(&(&*accs).into(), ctx, accs.payer.key, Exempt)?;
@@ -246,23 +244,6 @@ impl<'a> From<&TransferWrapped<'a>> for WrappedDerivationData {
 }
 
 impl<'b> InstructionContext<'b> for TransferWrapped<'b> {
-    fn verify(&self, program_id: &Pubkey) -> Result<()> {
-        // Verify that the from account is owned by the from_owner
-        if &self.from.owner != self.from_owner.key {
-            return Err(WrongAccountOwner.into());
-        }
-
-        // Verify mints
-        if self.mint.info().key != &self.from.mint {
-            return Err(TokenBridgeError::InvalidMint.into());
-        }
-
-        // Verify that meta is correct
-        self.wrapped_meta
-            .verify_derivation(program_id, &self.into())?;
-
-        Ok(())
-    }
 }
 
 #[derive(BorshDeserialize, BorshSerialize, Default)]
@@ -279,6 +260,20 @@ pub fn transfer_wrapped(
     accs: &mut TransferWrapped,
     data: TransferWrappedData,
 ) -> Result<()> {
+    // Verify that the from account is owned by the from_owner
+    if &accs.from.owner != accs.from_owner.key {
+        return Err(WrongAccountOwner.into());
+    }
+
+    // Verify mints
+    if accs.mint.info().key != &accs.from.mint {
+        return Err(TokenBridgeError::InvalidMint.into());
+    }
+
+    // Verify that meta is correct
+    accs.wrapped_meta
+        .verify_derivation(ctx.program_id, &(&*accs).into())?;
+
     // Burn tokens
     let burn_ix = spl_token::instruction::burn(
         &spl_token::id(),

+ 10 - 14
solana/pyth2wormhole/program/src/set_config.rs

@@ -16,20 +16,6 @@ pub struct SetConfig<'b> {
 }
 
 impl<'b> InstructionContext<'b> for SetConfig<'b> {
-    fn verify(&self, _program_id: &Pubkey) -> SoliResult<()> {
-        if &self.config.0.owner != self.current_owner.info().key {
-            msg!(
-                "Current owner account mismatch (expected {:?})",
-                self.config.0.owner
-            );
-            return Err(SolitaireError::InvalidSigner(
-                self.current_owner.info().key.clone(),
-            ));
-        }
-
-        Ok(())
-    }
-
     fn deps(&self) -> Vec<Pubkey> {
         vec![]
     }
@@ -41,6 +27,16 @@ pub fn set_config(
     accs: &mut SetConfig,
     data: Pyth2WormholeConfig,
 ) -> SoliResult<()> {
+    if &accs.config.0.owner != accs.current_owner.info().key {
+        msg!(
+            "Current owner account mismatch (expected {:?})",
+            accs.config.0.owner
+        );
+        return Err(SolitaireError::InvalidSigner(
+            accs.current_owner.info().key.clone(),
+        ));
+    }
+
     accs.config.1 = data;
 
     Ok(())

+ 0 - 4
solana/solitaire/program/src/lib.rs

@@ -110,10 +110,6 @@ impl CreationLamports {
 }
 
 pub trait InstructionContext<'a> {
-    fn verify(&self, program_id: &Pubkey) -> Result<()> {
-        Ok(())
-    }
-
     fn deps(&self) -> Vec<Pubkey> {
         vec![]
     }

+ 0 - 4
solana/solitaire/rocksalt/src/lib.rs

@@ -120,10 +120,6 @@ pub fn derive_from_accounts(input: TokenStream) -> TokenStream {
         impl #combined_impl_g solitaire::Peel<'a, 'b, 'c> for #name #type_g {
             fn peel<I>(ctx: &'c mut Context<'a, 'b, 'c, I>) -> solitaire::Result<Self> where Self: Sized {
                 let v: #name #type_g = FromAccounts::from(ctx.this, ctx.iter, ctx.data)?;
-
-                // Verify the instruction constraints
-                solitaire::InstructionContext::verify(&v, ctx.this)?;
-
                 Ok(v)
             }