solitaire: reduce Claim complexity

This commit is contained in:
Reisen 2022-06-27 18:20:10 +00:00 committed by Csongor Kiss
parent 82ea938317
commit 5da7ad0ef5
15 changed files with 164 additions and 157 deletions

View File

@ -1,5 +1,28 @@
//! ClaimData accounts are one off markers that can be combined with other accounts to represent
//! data that can only be used once.
//! Claim accounts add replay protection to Messages.
//!
//! Claim accounts work by having the constraint that they must be uninitialized. This means once a
//! Claim account has been created, they can no longer be passed to an instruction. This gives us
//! the behaviour of replay protection.
//!
//! Example usage:
//!
//! ```rust,noplayground,no_run
//! struct ExampleAccounts {
//! message: PayloadMessage<'info, Example>,
//! claim: Claim<'info>,
//! payer: Mut<Signer<'info>>,
//! }
//!
//! // Note that as a Claim must be uninitialized, only the first time this instruction is called
//! // will succeed, subsequent calls will fail the `Uninitialized` check.
//! fn read_message(
//! ctx: &ExecutionContext,
//! accs: &mut ExampleAccounts,
//! data: (),
//! ) {
//! claim::consume(ctx, &accs.payer.key, &mut accs.claim, &accs.vaa)?;
//! }
//! ```
use borsh::{
BorshDeserialize,
@ -9,15 +32,63 @@ use serde::{
Deserialize,
Serialize,
};
use solana_program::pubkey::Pubkey;
use solitaire::{
processors::seeded::Seeded,
AccountOwner,
AccountState,
AccountState::*,
CreationLamports::Exempt,
Data,
Owned,
Result,
*,
};
pub type Claim<'a, const State: AccountState> = Data<'a, ClaimData, { State }>;
use crate::{
DeserializePayload,
PayloadMessage,
};
pub type Claim<'a> = Data<'a, ClaimData, { Uninitialized }>;
/// Consume a claim by initializing the account. Initialized claims act as an indicator proving
/// that a message has been consumed.
#[must_use]
pub fn consume<T>(
ctx: &ExecutionContext,
payer: &Pubkey,
claim: &mut Claim,
message: &PayloadMessage<T>,
) -> Result<()>
where
T: DeserializePayload,
{
// Verify that the claim account is derived correctly before claiming.
claim.verify_derivation(
ctx.program_id,
&ClaimDerivationData {
emitter_address: message.meta().emitter_address,
emitter_chain: message.meta().emitter_chain,
sequence: message.meta().sequence,
},
)?;
// Claim the account by initializing it with a value.
claim.create(
&ClaimDerivationData {
emitter_address: message.meta().emitter_address,
emitter_chain: message.meta().emitter_chain,
sequence: message.meta().sequence,
},
ctx,
payer,
Exempt,
)?;
claim.claimed = true;
Ok(())
}
#[derive(Default, Clone, Copy, BorshDeserialize, BorshSerialize, Serialize, Deserialize)]
pub struct ClaimData {
@ -36,7 +107,7 @@ pub struct ClaimDerivationData {
pub sequence: u64,
}
impl<'b, const State: AccountState> Seeded<&ClaimDerivationData> for Claim<'b, { State }> {
impl<'b> Seeded<&ClaimDerivationData> for Claim<'b> {
fn seeds(data: &ClaimDerivationData) -> Vec<Vec<u8>> {
return vec![
data.emitter_address.to_vec(),

View File

@ -1,5 +1,3 @@
use solitaire::*;
use solana_program::{
program::invoke_signed,
pubkey::Pubkey,
@ -11,10 +9,15 @@ use solana_program::{
use solitaire::{
processors::seeded::Seeded,
CreationLamports::Exempt,
*,
};
use crate::{
accounts::{
claim::{
self,
Claim,
},
Bridge,
GuardianSet,
GuardianSetDerivationData,
@ -31,19 +34,18 @@ use crate::{
GovernancePayloadTransferFees,
GovernancePayloadUpgrade,
},
vaa::ClaimableVAA,
DeserializePayload,
PayloadMessage,
CHAIN_ID_SOLANA,
};
/// Fail if the emitter is not the known governance key, or the emitting chain is not Solana.
fn verify_governance<T>(vaa: &PayloadMessage<T>) -> Result<()>
where
T: DeserializePayload,
{
let expected_emitter = std::env!("EMITTER_ADDRESS");
let current_emitter = format!("{}", Pubkey::new_from_array(vaa.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.meta().emitter_chain != CHAIN_ID_SOLANA {
Err(InvalidGovernanceKey.into())
} else {
@ -62,8 +64,8 @@ pub struct UpgradeContract<'b> {
/// GuardianSet change VAA
pub vaa: PayloadMessage<'b, GovernancePayloadUpgrade>,
/// Claim account representing whether the vaa has already been consumed.
pub vaa_claim: ClaimableVAA<'b>,
/// An Uninitialized Claim account to consume the VAA.
pub claim: Mut<Claim<'b>>,
/// PDA authority for the loader
pub upgrade_authority: Derive<Info<'b>, "upgrade">,
@ -96,7 +98,7 @@ pub fn upgrade_contract(
_data: UpgradeContractData,
) -> Result<()> {
verify_governance(&accs.vaa)?;
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, &accs.payer.key, &mut accs.claim, &accs.vaa)?;
let upgrade_ix = solana_program::bpf_loader_upgradeable::upgrade(
ctx.program_id,
@ -126,8 +128,8 @@ pub struct UpgradeGuardianSet<'b> {
/// GuardianSet change VAA
pub vaa: PayloadMessage<'b, GovernancePayloadGuardianSetChange>,
/// Claim account representing whether the vaa has already been consumed.
pub vaa_claim: ClaimableVAA<'b>,
/// An Uninitialized Claim account to consume the VAA.
pub claim: Mut<Claim<'b>>,
/// Old guardian set
pub guardian_set_old: Mut<GuardianSet<'b, { AccountState::Initialized }>>,
@ -144,6 +146,9 @@ pub fn upgrade_guardian_set(
accs: &mut UpgradeGuardianSet,
_data: UpgradeGuardianSetData,
) -> Result<()> {
verify_governance(&accs.vaa)?;
claim::consume(ctx, &accs.payer.key, &mut accs.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());
@ -154,7 +159,6 @@ pub fn upgrade_guardian_set(
return Err(InvalidGuardianSetUpgrade.into());
}
verify_governance(&accs.vaa)?;
accs.guardian_set_old.verify_derivation(
ctx.program_id,
&GuardianSetDerivationData {
@ -168,8 +172,6 @@ pub fn upgrade_guardian_set(
},
)?;
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
// Set expiration time for the old set
accs.guardian_set_old.expiration_time =
accs.vaa.meta().vaa_time + accs.bridge.config.guardian_set_expiration_time;
@ -207,8 +209,8 @@ pub struct SetFees<'b> {
/// Governance VAA
pub vaa: PayloadMessage<'b, GovernancePayloadSetMessageFee>,
/// Claim account representing whether the vaa has already been consumed.
pub vaa_claim: ClaimableVAA<'b>,
/// An Uninitialized Claim account to consume the VAA.
pub claim: Mut<Claim<'b>>,
}
#[derive(BorshDeserialize, BorshSerialize, Default)]
@ -216,9 +218,8 @@ pub struct SetFeesData {}
pub fn set_fees(ctx: &ExecutionContext, accs: &mut SetFees, _data: SetFeesData) -> Result<()> {
verify_governance(&accs.vaa)?;
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, &accs.payer.key, &mut accs.claim, &accs.vaa)?;
accs.bridge.config.fee = accs.vaa.fee.as_u64();
Ok(())
}
@ -233,8 +234,8 @@ pub struct TransferFees<'b> {
/// Governance VAA
pub vaa: PayloadMessage<'b, GovernancePayloadTransferFees>,
/// Claim account representing whether the vaa has already been consumed.
pub vaa_claim: ClaimableVAA<'b>,
/// An Uninitialized Claim account to consume the VAA.
pub claim: Mut<Claim<'b>>,
/// Account collecting tx fees
pub fee_collector: Mut<Derive<Info<'b>, "fee_collector">>,
@ -254,14 +255,14 @@ pub fn transfer_fees(
accs: &mut TransferFees,
_data: TransferFeesData,
) -> Result<()> {
verify_governance(&accs.vaa)?;
claim::consume(ctx, &accs.payer.key, &mut accs.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());
}
verify_governance(&accs.vaa)?;
accs.vaa.verify(ctx.program_id)?;
let new_balance = accs
.fee_collector
.lamports()
@ -272,10 +273,6 @@ pub fn transfer_fees(
}
accs.bridge.last_lamports = new_balance;
verify_governance(&accs.vaa)?;
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
// Transfer fees
let transfer_ix = solana_program::system_instruction::transfer(
accs.fee_collector.key,

View File

@ -251,7 +251,7 @@ pub fn upgrade_contract(
sequence: u64,
) -> Instruction {
let bridge = Bridge::<'_, { AccountState::Initialized }>::key(None, &program_id);
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
let claim = Claim::<'_>::key(
&ClaimDerivationData {
emitter_address: emitter.to_bytes(),
emitter_chain: CHAIN_ID_SOLANA,
@ -305,7 +305,7 @@ pub fn upgrade_guardian_set(
sequence: u64,
) -> Instruction {
let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
let claim = Claim::<'_>::key(
&ClaimDerivationData {
emitter_address: emitter.to_bytes(),
emitter_chain: CHAIN_ID_SOLANA,
@ -354,7 +354,7 @@ pub fn set_fees(
sequence: u64,
) -> Instruction {
let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
let claim = Claim::<'_>::key(
&ClaimDerivationData {
emitter_address: emitter.to_bytes(),
emitter_chain: CHAIN_ID_SOLANA,
@ -389,7 +389,7 @@ pub fn transfer_fees(
recipient: Pubkey,
) -> Instruction {
let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
let claim = Claim::<'_>::key(
&ClaimDerivationData {
emitter_address: emitter.to_bytes(),
emitter_chain: CHAIN_ID_SOLANA,

View File

@ -7,10 +7,7 @@ use crate::{
InvalidGovernanceAction,
InvalidGovernanceChain,
InvalidGovernanceModule,
VAAAlreadyExecuted,
},
Claim,
ClaimDerivationData,
PostedVAAData,
Result,
CHAIN_ID_SOLANA,
@ -28,12 +25,8 @@ use solana_program::{
pubkey::Pubkey,
};
use solitaire::{
processors::seeded::Seeded,
trace,
Context,
CreationLamports::Exempt,
Data,
ExecutionContext,
Peel,
SolitaireError,
*,
@ -148,78 +141,6 @@ impl<'b, T: DeserializePayload> PayloadMessage<'b, T> {
}
}
/// Claim account to prevent double spending.
pub struct ClaimableVAA<'b>(Mut<Claim<'b, { AccountState::Uninitialized }>>);
impl<'a, 'b: 'a> Peel<'a, 'b> for ClaimableVAA<'b> {
fn peel<I>(ctx: &mut Context<'a, 'b, I>) -> Result<Self> {
Mut::<Claim<'b, { AccountState::Uninitialized }>>::peel(ctx).map(|c| Self(c))
}
fn persist(&self, program_id: &Pubkey) -> Result<()> {
Mut::<Claim<'b, { AccountState::Uninitialized }>>::persist(&self.0, program_id)
}
}
impl<'b> ClaimableVAA<'b> {
pub fn verify<T>(&self, ctx: &ExecutionContext, message: &PayloadMessage<'b, T>) -> Result<()>
where
T: DeserializePayload,
{
trace!("Seq: {}", message.meta().sequence);
// Verify that the claim account is derived correctly
self.0.verify_derivation(
ctx.program_id,
&ClaimDerivationData {
emitter_address: message.meta().emitter_address,
emitter_chain: message.meta().emitter_chain,
sequence: message.meta().sequence,
},
)?;
Ok(())
}
pub fn is_claimed(&self) -> bool {
self.0.claimed
}
pub fn claim<T>(
&mut self,
ctx: &ExecutionContext,
payer: &Pubkey,
message: &PayloadMessage<'b, T>,
) -> Result<()>
where
T: DeserializePayload,
{
// Verify that the claim account is derived correctly before claiming.
self.verify(ctx, message)?;
// Exit if the claim has already been made.
if self.is_claimed() {
return Err(VAAAlreadyExecuted.into());
}
// Claim the account by initializing it with a true boolean.
self.0.create(
&ClaimDerivationData {
emitter_address: message.meta().emitter_address,
emitter_chain: message.meta().emitter_chain,
sequence: message.meta().sequence,
},
ctx,
payer,
Exempt,
)?;
self.0.claimed = true;
Ok(())
}
}
pub struct SignatureItem {
pub signature: Vec<u8>,
pub key: [u8; 20],

View File

@ -379,7 +379,7 @@ pub fn claim_address(program_id: String, vaa: Vec<u8>) -> Vec<u8> {
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
let vaa = VAA::deserialize(vaa.as_slice()).unwrap();
let claim_key = Claim::<'_, { AccountState::Initialized }>::key(
let claim_key = Claim::<'_>::key(
&ClaimDerivationData {
emitter_address: vaa.emitter_address,
emitter_chain: vaa.emitter_chain,
@ -392,7 +392,12 @@ pub fn claim_address(program_id: String, vaa: Vec<u8>) -> Vec<u8> {
#[wasm_bindgen]
pub fn parse_posted_message(data: Vec<u8>) -> JsValue {
JsValue::from_serde(&PostedVAAData::try_from_slice(data.as_slice()).unwrap().message).unwrap()
JsValue::from_serde(
&PostedVAAData::try_from_slice(data.as_slice())
.unwrap()
.message,
)
.unwrap()
}
#[wasm_bindgen]

View File

@ -19,7 +19,10 @@ use crate::{
TokenBridgeError::*,
};
use bridge::{
vaa::ClaimableVAA,
accounts::claim::{
self,
Claim,
},
PayloadMessage,
CHAIN_ID_SOLANA,
};
@ -45,7 +48,7 @@ pub struct CompleteNative<'b> {
pub config: ConfigAccount<'b, { AccountState::Initialized }>,
pub vaa: PayloadMessage<'b, PayloadTransfer>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
pub chain_registration: Endpoint<'b, { AccountState::Initialized }>,
pub to: Mut<Data<'b, SplAccount, { AccountState::MaybeInitialized }>>,
@ -120,7 +123,7 @@ pub fn complete_native(
}
// Prevent vaa double signing
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
if !accs.to.is_initialized() {
let associated_addr = spl_associated_token_account::get_associated_token_address(
@ -162,7 +165,7 @@ pub struct CompleteWrapped<'b> {
// Signed message for the transfer
pub vaa: PayloadMessage<'b, PayloadTransfer>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
pub chain_registration: Endpoint<'b, { AccountState::Initialized }>,
@ -227,7 +230,7 @@ pub fn complete_wrapped(
return Err(InvalidRecipient.into());
}
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
// Initialize the NFT if it doesn't already exist
if !accs.meta.is_initialized() {

View File

@ -14,10 +14,11 @@ use crate::{
},
};
use bridge::{
vaa::{
ClaimableVAA,
DeserializePayload,
accounts::claim::{
self,
Claim,
},
DeserializePayload,
PayloadMessage,
CHAIN_ID_SOLANA,
};
@ -60,7 +61,7 @@ pub struct UpgradeContract<'b> {
pub vaa: PayloadMessage<'b, GovernancePayloadUpgrade>,
/// Claim account representing whether the vaa has already been consumed.
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
/// PDA authority for the loader
pub upgrade_authority: Derive<Info<'b>, "upgrade">,
@ -93,7 +94,7 @@ pub fn upgrade_contract(
_data: UpgradeContractData,
) -> Result<()> {
verify_governance(&accs.vaa)?;
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
let upgrade_ix = solana_program::bpf_loader_upgradeable::upgrade(
ctx.program_id,
@ -118,7 +119,7 @@ pub struct RegisterChain<'b> {
pub config: ConfigAccount<'b, { AccountState::Initialized }>,
pub endpoint: Mut<Endpoint<'b, { AccountState::Uninitialized }>>,
pub vaa: PayloadMessage<'b, PayloadGovernanceRegisterChain>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
}
impl<'a> From<&RegisterChain<'a>> for EndpointDerivationData {
@ -144,7 +145,7 @@ pub fn register_chain(
// Claim VAA
verify_governance(&accs.vaa)?;
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
if accs.vaa.chain == CHAIN_ID_SOLANA {
return Err(InvalidChain.into());

View File

@ -298,7 +298,7 @@ fn claimable_vaa(
message_key: Pubkey,
vaa: PostVAAData,
) -> (AccountMeta, AccountMeta) {
let claim_key = Claim::<'_, { AccountState::Initialized }>::key(
let claim_key = Claim::<'_>::key(
&ClaimDerivationData {
emitter_address: vaa.emitter_address,
emitter_chain: vaa.emitter_chain,
@ -464,7 +464,7 @@ pub fn upgrade_contract(
spill: Pubkey,
sequence: u64,
) -> Instruction {
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
let claim = Claim::<'_>::key(
&ClaimDerivationData {
emitter_address: emitter.to_bytes(),
emitter_chain: CHAIN_ID_SOLANA,

View File

@ -18,7 +18,10 @@ use crate::{
INVALID_VAAS,
};
use bridge::{
vaa::ClaimableVAA,
accounts::claim::{
self,
Claim,
},
PayloadMessage,
CHAIN_ID_SOLANA,
};
@ -37,7 +40,7 @@ pub struct CompleteNative<'b> {
pub config: ConfigAccount<'b, { AccountState::Initialized }>,
pub vaa: PayloadMessage<'b, PayloadTransfer>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
pub chain_registration: Endpoint<'b, { AccountState::Initialized }>,
pub to: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
@ -115,7 +118,7 @@ pub fn complete_native(
}
// Prevent vaa double signing
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
let mut amount = accs.vaa.amount.as_u64();
let mut fee = accs.vaa.fee.as_u64();
@ -158,7 +161,7 @@ pub struct CompleteWrapped<'b> {
// Signed message for the transfer
pub vaa: PayloadMessage<'b, PayloadTransfer>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
pub chain_registration: Endpoint<'b, { AccountState::Initialized }>,
@ -233,7 +236,7 @@ pub fn complete_wrapped(
return Err(InvalidVAA.into());
}
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
// Mint tokens
let mint_ix = spl_token::instruction::mint_to(

View File

@ -17,7 +17,10 @@ use crate::{
TokenBridgeError::*,
};
use bridge::{
vaa::ClaimableVAA,
accounts::claim::{
self,
Claim,
},
PayloadMessage,
CHAIN_ID_SOLANA,
};
@ -38,8 +41,8 @@ use solana_program::pubkey::Pubkey;
#[repr(transparent)]
pub struct RedeemerAccount<'b>(pub MaybeMut<Signer<Info<'b>>>);
impl<'a, 'b: 'a, 'c> Peel<'a, 'b, 'c> for RedeemerAccount<'b> {
fn peel<I>(ctx: &'c mut Context<'a, 'b, 'c, I>) -> Result<Self>
impl<'a, 'b: 'a> Peel<'a, 'b> for RedeemerAccount<'b> {
fn peel<I>(ctx: &mut Context<'a, 'b, I>) -> Result<Self>
where
Self: Sized,
{
@ -96,7 +99,7 @@ pub struct CompleteNativeWithPayload<'b> {
pub config: ConfigAccount<'b, { AccountState::Initialized }>,
pub vaa: PayloadMessage<'b, PayloadTransferWithPayload>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
pub chain_registration: Endpoint<'b, { AccountState::Initialized }>,
pub to: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
@ -181,7 +184,7 @@ pub fn complete_native_with_payload(
}
// Prevent vaa double signing
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
let mut amount = accs.vaa.amount.as_u64();
@ -211,7 +214,7 @@ pub struct CompleteWrappedWithPayload<'b> {
/// Signed message for the transfer
pub vaa: PayloadMessage<'b, PayloadTransferWithPayload>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
pub chain_registration: Endpoint<'b, { AccountState::Initialized }>,
@ -293,7 +296,7 @@ pub fn complete_wrapped_with_payload(
return Err(InvalidRecipient.into());
}
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
// Mint tokens
let mint_ix = spl_token::instruction::mint_to(

View File

@ -20,7 +20,10 @@ use crate::{
INVALID_VAAS,
};
use bridge::{
vaa::ClaimableVAA,
accounts::claim::{
self,
Claim,
},
PayloadMessage,
CHAIN_ID_SOLANA,
};
@ -50,7 +53,7 @@ pub struct CreateWrapped<'b> {
pub chain_registration: Endpoint<'b, { AccountState::Initialized }>,
pub vaa: PayloadMessage<'b, PayloadAssetMeta>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
// New Wrapped
pub mint: Mut<WrappedMint<'b, { AccountState::MaybeInitialized }>>,
@ -117,7 +120,7 @@ pub fn create_wrapped(
return Err(InvalidVAA.into());
}
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
if accs.mint.is_initialized() {
update_accounts(ctx, accs, data)

View File

@ -15,10 +15,11 @@ use crate::{
INVALID_VAAS,
};
use bridge::{
vaa::{
ClaimableVAA,
DeserializePayload,
accounts::claim::{
self,
Claim,
},
DeserializePayload,
PayloadMessage,
CHAIN_ID_SOLANA,
};
@ -59,7 +60,7 @@ pub struct UpgradeContract<'b> {
/// GuardianSet change VAA
pub vaa: PayloadMessage<'b, GovernancePayloadUpgrade>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
/// PDA authority for the loader
pub upgrade_authority: Derive<Info<'b>, "upgrade">,
@ -96,7 +97,7 @@ pub fn upgrade_contract(
}
verify_governance(&accs.vaa)?;
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
let upgrade_ix = solana_program::bpf_loader_upgradeable::upgrade(
ctx.program_id,
@ -123,7 +124,7 @@ pub struct RegisterChain<'b> {
pub endpoint: Mut<Endpoint<'b, { AccountState::Uninitialized }>>,
pub vaa: PayloadMessage<'b, PayloadGovernanceRegisterChain>,
pub vaa_claim: ClaimableVAA<'b>,
pub claim: Mut<Claim<'b>>,
}
impl<'a> From<&RegisterChain<'a>> for EndpointDerivationData {
@ -153,7 +154,7 @@ pub fn register_chain(
// Claim VAA
verify_governance(&accs.vaa)?;
accs.vaa_claim.claim(ctx, accs.payer.key, &accs.vaa)?;
claim::consume(ctx, accs.payer.key, &mut accs.claim, &accs.vaa)?;
// Create endpoint
accs.endpoint

View File

@ -48,8 +48,8 @@ use super::{
#[repr(transparent)]
pub struct SenderAccount<'b>(pub MaybeMut<Signer<Info<'b>>>);
impl<'a, 'b: 'a, 'c> Peel<'a, 'b, 'c> for SenderAccount<'b> {
fn peel<I>(ctx: &'c mut Context<'a, 'b, 'c, I>) -> Result<Self>
impl<'a, 'b: 'a> Peel<'a, 'b> for SenderAccount<'b> {
fn peel<I>(ctx: &mut Context<'a, 'b, I>) -> Result<Self>
where
Self: Sized,
{

View File

@ -433,7 +433,7 @@ fn claimable_vaa(
message_key: Pubkey,
vaa: PostVAAData,
) -> (AccountMeta, AccountMeta) {
let claim_key = Claim::<'_, { AccountState::Initialized }>::key(
let claim_key = Claim::<'_>::key(
&ClaimDerivationData {
emitter_address: vaa.emitter_address,
emitter_chain: vaa.emitter_chain,
@ -872,7 +872,7 @@ pub fn upgrade_contract(
spill: Pubkey,
sequence: u64,
) -> Instruction {
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
let claim = Claim::<'_>::key(
&ClaimDerivationData {
emitter_address: emitter.to_bytes(),
emitter_chain: CHAIN_ID_SOLANA,

View File

@ -54,8 +54,7 @@ pub use crate::{
};
/// Library name and version to print in entrypoint. Must be evaluated in this crate in order to do the right thing
pub const PKG_NAME_VERSION: &str =
concat!(env!("CARGO_PKG_NAME"), " ", env!("CARGO_PKG_VERSION"));
pub const PKG_NAME_VERSION: &str = concat!(env!("CARGO_PKG_NAME"), " ", env!("CARGO_PKG_VERSION"));
pub struct ExecutionContext<'a, 'b: 'a> {
/// A reference to the program_id of the current program.