use sequence as seed for persisted VAAs from foreign chains
Without the additional seed, messages with identical (emitter_chain, emitter_address, nonce, payload) but different sequence could fail to be persisted. Change-Id: I6786f7be33bcc6da7289f54fc62c7a5b10821594
This commit is contained in:
parent
b85cbacd3b
commit
049177db37
|
@ -74,6 +74,8 @@ pub struct MessageDerivationData {
|
||||||
pub emitter_chain: u16,
|
pub emitter_chain: u16,
|
||||||
pub nonce: u32,
|
pub nonce: u32,
|
||||||
pub payload: Vec<u8>,
|
pub payload: Vec<u8>,
|
||||||
|
// This field is only used when a VAA from a foreign chain is posted
|
||||||
|
pub sequence: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, const State: AccountState> Seeded<&MessageDerivationData> for Message<'b, { State }> {
|
impl<'b, const State: AccountState> Seeded<&MessageDerivationData> for Message<'b, { State }> {
|
||||||
|
@ -83,6 +85,9 @@ impl<'b, const State: AccountState> Seeded<&MessageDerivationData> for Message<'
|
||||||
data.emitter_chain.to_be_bytes().to_vec(),
|
data.emitter_chain.to_be_bytes().to_vec(),
|
||||||
data.nonce.to_be_bytes().to_vec(),
|
data.nonce.to_be_bytes().to_vec(),
|
||||||
];
|
];
|
||||||
|
if let Some(seq) = data.sequence {
|
||||||
|
seeds.push(seq.to_be_bytes().to_vec())
|
||||||
|
}
|
||||||
seeds.append(&mut data.payload.chunks(32).map(|v| v.to_vec()).collect());
|
seeds.append(&mut data.payload.chunks(32).map(|v| v.to_vec()).collect());
|
||||||
seeds
|
seeds
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::{
|
||||||
InsufficientFees,
|
InsufficientFees,
|
||||||
MathOverflow,
|
MathOverflow,
|
||||||
},
|
},
|
||||||
|
CHAIN_ID_SOLANA,
|
||||||
};
|
};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
|
@ -80,9 +81,10 @@ pub fn post_message(
|
||||||
|
|
||||||
let msg_derivation = MessageDerivationData {
|
let msg_derivation = MessageDerivationData {
|
||||||
emitter_key: accs.emitter.key.to_bytes(),
|
emitter_key: accs.emitter.key.to_bytes(),
|
||||||
emitter_chain: 1,
|
emitter_chain: CHAIN_ID_SOLANA,
|
||||||
nonce: data.nonce,
|
nonce: data.nonce,
|
||||||
payload: data.payload.clone(),
|
payload: data.payload.clone(),
|
||||||
|
sequence: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("Verifying Message: {}, {}", accs.emitter.key, data.nonce);
|
trace!("Verifying Message: {}, {}", accs.emitter.key, data.nonce);
|
||||||
|
@ -118,7 +120,7 @@ pub fn post_message(
|
||||||
// Initialize transfer
|
// Initialize transfer
|
||||||
trace!("Setting Message Details");
|
trace!("Setting Message Details");
|
||||||
accs.message.submission_time = accs.clock.unix_timestamp as u32;
|
accs.message.submission_time = accs.clock.unix_timestamp as u32;
|
||||||
accs.message.emitter_chain = 1;
|
accs.message.emitter_chain = CHAIN_ID_SOLANA;
|
||||||
accs.message.emitter_address = accs.emitter.key.to_bytes();
|
accs.message.emitter_address = accs.emitter.key.to_bytes();
|
||||||
accs.message.nonce = data.nonce;
|
accs.message.nonce = data.nonce;
|
||||||
accs.message.payload = data.payload;
|
accs.message.payload = data.payload;
|
||||||
|
|
|
@ -21,6 +21,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
Error::GuardianSetMismatch,
|
Error::GuardianSetMismatch,
|
||||||
|
CHAIN_ID_SOLANA,
|
||||||
};
|
};
|
||||||
use byteorder::{
|
use byteorder::{
|
||||||
BigEndian,
|
BigEndian,
|
||||||
|
@ -111,12 +112,16 @@ pub struct PostVAAData {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn post_vaa(ctx: &ExecutionContext, accs: &mut PostVAA, vaa: PostVAAData) -> Result<()> {
|
pub fn post_vaa(ctx: &ExecutionContext, accs: &mut PostVAA, vaa: PostVAAData) -> Result<()> {
|
||||||
let msg_derivation = MessageDerivationData {
|
let mut msg_derivation = MessageDerivationData {
|
||||||
emitter_key: vaa.emitter_address,
|
emitter_key: vaa.emitter_address,
|
||||||
emitter_chain: vaa.emitter_chain,
|
emitter_chain: vaa.emitter_chain,
|
||||||
nonce: vaa.nonce,
|
nonce: vaa.nonce,
|
||||||
payload: vaa.payload.clone(),
|
payload: vaa.payload.clone(),
|
||||||
|
sequence: None,
|
||||||
};
|
};
|
||||||
|
if vaa.emitter_chain != CHAIN_ID_SOLANA {
|
||||||
|
msg_derivation.sequence = Some(vaa.sequence)
|
||||||
|
}
|
||||||
|
|
||||||
accs.message
|
accs.message
|
||||||
.verify_derivation(ctx.program_id, &msg_derivation)?;
|
.verify_derivation(ctx.program_id, &msg_derivation)?;
|
||||||
|
@ -153,7 +158,7 @@ pub fn post_vaa(ctx: &ExecutionContext, accs: &mut PostVAA, vaa: PostVAAData) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the VAA originates from another chain we need to create the account and populate all fields
|
// If the VAA originates from another chain we need to create the account and populate all fields
|
||||||
if vaa.emitter_chain != 1 {
|
if vaa.emitter_chain != CHAIN_ID_SOLANA {
|
||||||
accs.message.nonce = vaa.nonce;
|
accs.message.nonce = vaa.nonce;
|
||||||
accs.message.emitter_chain = vaa.emitter_chain;
|
accs.message.emitter_chain = vaa.emitter_chain;
|
||||||
accs.message.emitter_address = vaa.emitter_address;
|
accs.message.emitter_address = vaa.emitter_address;
|
||||||
|
|
|
@ -28,21 +28,16 @@ use crate::{
|
||||||
SignatureSet,
|
SignatureSet,
|
||||||
SignatureSetDerivationData,
|
SignatureSetDerivationData,
|
||||||
},
|
},
|
||||||
types::{
|
|
||||||
GovernancePayloadUpgrade,
|
|
||||||
PostedMessage,
|
|
||||||
},
|
|
||||||
InitializeData,
|
InitializeData,
|
||||||
PayloadMessage,
|
PayloadMessage,
|
||||||
PostMessageData,
|
PostMessageData,
|
||||||
PostVAAData,
|
PostVAAData,
|
||||||
SetFees,
|
|
||||||
SetFeesData,
|
SetFeesData,
|
||||||
TransferFees,
|
|
||||||
TransferFeesData,
|
TransferFeesData,
|
||||||
UpgradeContractData,
|
UpgradeContractData,
|
||||||
UpgradeGuardianSetData,
|
UpgradeGuardianSetData,
|
||||||
VerifySignaturesData,
|
VerifySignaturesData,
|
||||||
|
CHAIN_ID_SOLANA,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn initialize(
|
pub fn initialize(
|
||||||
|
@ -96,8 +91,9 @@ pub fn post_message(
|
||||||
let message = Message::<'_, { AccountState::MaybeInitialized }>::key(
|
let message = Message::<'_, { AccountState::MaybeInitialized }>::key(
|
||||||
&MessageDerivationData {
|
&MessageDerivationData {
|
||||||
emitter_key: emitter.to_bytes(),
|
emitter_key: emitter.to_bytes(),
|
||||||
emitter_chain: 1,
|
emitter_chain: CHAIN_ID_SOLANA,
|
||||||
nonce,
|
nonce,
|
||||||
|
sequence: None,
|
||||||
payload: payload.clone(),
|
payload: payload.clone(),
|
||||||
},
|
},
|
||||||
&program_id,
|
&program_id,
|
||||||
|
@ -179,15 +175,19 @@ pub fn post_vaa(program_id: Pubkey, payer: Pubkey, vaa: PostVAAData) -> Instruct
|
||||||
&program_id,
|
&program_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
let message = Message::<'_, { AccountState::MaybeInitialized }>::key(
|
let mut msg_derivation_data = MessageDerivationData {
|
||||||
&MessageDerivationData {
|
emitter_key: vaa.emitter_address,
|
||||||
emitter_key: vaa.emitter_address,
|
emitter_chain: vaa.emitter_chain,
|
||||||
emitter_chain: vaa.emitter_chain,
|
nonce: vaa.nonce,
|
||||||
nonce: vaa.nonce,
|
sequence: None,
|
||||||
payload: vaa.payload.clone(),
|
payload: vaa.payload.clone(),
|
||||||
},
|
};
|
||||||
&program_id,
|
if vaa.emitter_chain != CHAIN_ID_SOLANA {
|
||||||
);
|
msg_derivation_data.sequence = Some(vaa.sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
let message =
|
||||||
|
Message::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &program_id);
|
||||||
|
|
||||||
Instruction {
|
Instruction {
|
||||||
program_id,
|
program_id,
|
||||||
|
@ -218,7 +218,7 @@ pub fn upgrade_contract(
|
||||||
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
|
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
|
||||||
&ClaimDerivationData {
|
&ClaimDerivationData {
|
||||||
emitter_address: [0u8; 32],
|
emitter_address: [0u8; 32],
|
||||||
emitter_chain: 1,
|
emitter_chain: CHAIN_ID_SOLANA,
|
||||||
sequence: 0,
|
sequence: 0,
|
||||||
},
|
},
|
||||||
&program_id,
|
&program_id,
|
||||||
|
@ -256,7 +256,7 @@ pub fn upgrade_guardian_set(
|
||||||
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
|
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
|
||||||
&ClaimDerivationData {
|
&ClaimDerivationData {
|
||||||
emitter_address: emitter.to_bytes(),
|
emitter_address: emitter.to_bytes(),
|
||||||
emitter_chain: 1,
|
emitter_chain: CHAIN_ID_SOLANA,
|
||||||
sequence: 1,
|
sequence: 1,
|
||||||
},
|
},
|
||||||
&program_id,
|
&program_id,
|
||||||
|
@ -297,7 +297,7 @@ pub fn set_fees(program_id: Pubkey, payer: Pubkey, fee: u32) -> Instruction {
|
||||||
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
|
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
|
||||||
&ClaimDerivationData {
|
&ClaimDerivationData {
|
||||||
emitter_address: [0u8; 32],
|
emitter_address: [0u8; 32],
|
||||||
emitter_chain: 1,
|
emitter_chain: CHAIN_ID_SOLANA,
|
||||||
sequence: 0,
|
sequence: 0,
|
||||||
},
|
},
|
||||||
&program_id,
|
&program_id,
|
||||||
|
@ -326,7 +326,7 @@ pub fn transfer_fees(program_id: Pubkey, payer: Pubkey, recipient: Pubkey) -> In
|
||||||
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
|
let claim = Claim::<'_, { AccountState::Uninitialized }>::key(
|
||||||
&ClaimDerivationData {
|
&ClaimDerivationData {
|
||||||
emitter_address: [0u8; 32],
|
emitter_address: [0u8; 32],
|
||||||
emitter_chain: 1,
|
emitter_chain: CHAIN_ID_SOLANA,
|
||||||
sequence: 0,
|
sequence: 0,
|
||||||
},
|
},
|
||||||
&program_id,
|
&program_id,
|
||||||
|
|
|
@ -51,6 +51,8 @@ pub use vaa::{
|
||||||
|
|
||||||
const MAX_LEN_GUARDIAN_KEYS: usize = 19;
|
const MAX_LEN_GUARDIAN_KEYS: usize = 19;
|
||||||
|
|
||||||
|
const CHAIN_ID_SOLANA: u16 = 1;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Error {
|
enum Error {
|
||||||
GuardianSetMismatch,
|
GuardianSetMismatch,
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::{
|
||||||
VAAAlreadyExecuted,
|
VAAAlreadyExecuted,
|
||||||
},
|
},
|
||||||
Result,
|
Result,
|
||||||
|
CHAIN_ID_SOLANA,
|
||||||
};
|
};
|
||||||
use byteorder::{
|
use byteorder::{
|
||||||
BigEndian,
|
BigEndian,
|
||||||
|
@ -69,7 +70,7 @@ pub trait DeserializeGovernancePayload {
|
||||||
}
|
}
|
||||||
|
|
||||||
let chain = c.read_u16::<BigEndian>()?;
|
let chain = c.read_u16::<BigEndian>()?;
|
||||||
if chain != 1 && chain != 0 {
|
if chain != CHAIN_ID_SOLANA && chain != 0 {
|
||||||
return Err(InvalidGovernanceChain.into());
|
return Err(InvalidGovernanceChain.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -327,6 +327,7 @@ pub fn transfer_native(
|
||||||
emitter_chain: 1,
|
emitter_chain: 1,
|
||||||
nonce: data.nonce,
|
nonce: data.nonce,
|
||||||
payload: payload.try_to_vec().unwrap(),
|
payload: payload.try_to_vec().unwrap(),
|
||||||
|
sequence: None,
|
||||||
},
|
},
|
||||||
&bridge_id,
|
&bridge_id,
|
||||||
);
|
);
|
||||||
|
@ -412,6 +413,7 @@ pub fn transfer_wrapped(
|
||||||
emitter_chain: 1,
|
emitter_chain: 1,
|
||||||
nonce: data.nonce,
|
nonce: data.nonce,
|
||||||
payload: payload.try_to_vec().unwrap(),
|
payload: payload.try_to_vec().unwrap(),
|
||||||
|
sequence: None,
|
||||||
},
|
},
|
||||||
&bridge_id,
|
&bridge_id,
|
||||||
);
|
);
|
||||||
|
@ -476,6 +478,7 @@ pub fn attest(
|
||||||
emitter_key: emitter_key.to_bytes(),
|
emitter_key: emitter_key.to_bytes(),
|
||||||
emitter_chain: 1,
|
emitter_chain: 1,
|
||||||
nonce,
|
nonce,
|
||||||
|
sequence: None,
|
||||||
payload: payload.try_to_vec().unwrap(),
|
payload: payload.try_to_vec().unwrap(),
|
||||||
},
|
},
|
||||||
&bridge_id,
|
&bridge_id,
|
||||||
|
|
Loading…
Reference in New Issue