Allow user provided signature set accounts to prevent DoS

With derived signature set accounts, an old guardian set could frontrun the creation of the account. Since the hash is persisted in the account, we don't need to encode it in the account address.

Change-Id: I49ca46611eb587c8234ac9b2c459263a2ace4219
This commit is contained in:
Hendrik Hofstadt 2021-07-26 19:40:04 +02:00
parent 1135fdacd1
commit 42c3040de1
9 changed files with 99 additions and 161 deletions

View File

@ -130,11 +130,11 @@ impl Agent for AgentImpl {
payload: vaa.payload.clone(), payload: vaa.payload.clone(),
}; };
let verify_txs = let (verify_txs, signature_set) =
pack_sig_verification_txs(&rpc, &bridge, &post_data, &vaa.signatures, &key)?; pack_sig_verification_txs(&rpc, &bridge, &post_data, &vaa.signatures, &key)?;
// Strip signatures // Strip signatures
let ix = post_vaa(bridge, key.pubkey(), post_data); let ix = post_vaa(bridge, key.pubkey(), signature_set, post_data);
for mut tx in verify_txs { for mut tx in verify_txs {
match sign_and_send(&rpc, &mut tx, vec![&key], request.get_ref().skip_preflight) { match sign_and_send(&rpc, &mut tx, vec![&key], request.get_ref().skip_preflight) {
@ -204,7 +204,8 @@ fn pack_sig_verification_txs<'a>(
vaa: &PostVAAData, vaa: &PostVAAData,
signatures: &Vec<service::Signature>, signatures: &Vec<service::Signature>,
sender_keypair: &'a Keypair, sender_keypair: &'a Keypair,
) -> Result<Vec<Transaction>, Status> { ) -> Result<(Vec<Transaction>, Pubkey), Status> {
let signature_set = Keypair::new();
// Load guardian set // Load guardian set
let guardian_key = GuardianSet::<'_, { AccountState::Initialized }>::key( let guardian_key = GuardianSet::<'_, { AccountState::Initialized }>::key(
&GuardianSetDerivationData { &GuardianSetDerivationData {
@ -293,7 +294,7 @@ fn pack_sig_verification_txs<'a>(
*bridge, *bridge,
sender_keypair.pubkey(), sender_keypair.pubkey(),
vaa.guardian_set_index, vaa.guardian_set_index,
body_hash, signature_set.pubkey(),
payload, payload,
) { ) {
Ok(v) => v, Ok(v) => v,
@ -311,7 +312,7 @@ fn pack_sig_verification_txs<'a>(
)) ))
} }
Ok(verify_txs) Ok((verify_txs, signature_set.pubkey()))
} }
fn sign_and_send( fn sign_and_send(

View File

@ -55,18 +55,6 @@ impl<'b, const State: AccountState> Seeded<&ClaimDerivationData> for Claim<'b, {
pub type SignatureSet<'b, const State: AccountState> = Data<'b, types::SignatureSet, { State }>; pub type SignatureSet<'b, const State: AccountState> = Data<'b, types::SignatureSet, { State }>;
pub struct SignatureSetDerivationData {
pub hash: [u8; 32],
}
impl<'b, const State: AccountState> Seeded<&SignatureSetDerivationData>
for SignatureSet<'b, { State }>
{
fn seeds(data: &SignatureSetDerivationData) -> Vec<Vec<u8>> {
vec![data.hash.to_vec()]
}
}
pub type Message<'b, const State: AccountState> = Data<'b, PostedMessage, { State }>; pub type Message<'b, const State: AccountState> = Data<'b, PostedMessage, { State }>;
pub struct MessageDerivationData { pub struct MessageDerivationData {

View File

@ -3,8 +3,10 @@ use solitaire::*;
use solana_program::{ use solana_program::{
program::invoke_signed, program::invoke_signed,
pubkey::Pubkey, pubkey::Pubkey,
sysvar::rent::Rent, sysvar::{
sysvar::clock::Clock, clock::Clock,
rent::Rent,
},
}; };
use solitaire::{ use solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,

View File

@ -17,7 +17,6 @@ use crate::{
Message, Message,
MessageDerivationData, MessageDerivationData,
SignatureSet, SignatureSet,
SignatureSetDerivationData,
}, },
error::Error::{ error::Error::{
GuardianSetMismatch, GuardianSetMismatch,
@ -44,14 +43,6 @@ use std::io::{
Write, Write,
}; };
impl<'a> From<&PostVAA<'a>> for SignatureSetDerivationData {
fn from(accs: &PostVAA<'a>) -> Self {
SignatureSetDerivationData {
hash: accs.signature_set.hash,
}
}
}
impl From<&PostVAAData> for GuardianSetDerivationData { impl From<&PostVAAData> for GuardianSetDerivationData {
fn from(data: &PostVAAData) -> Self { fn from(data: &PostVAAData) -> Self {
GuardianSetDerivationData { GuardianSetDerivationData {
@ -82,9 +73,7 @@ pub struct PostVAA<'b> {
} }
impl<'b> InstructionContext<'b> for PostVAA<'b> { impl<'b> InstructionContext<'b> for PostVAA<'b> {
fn verify(&self, program_id: &Pubkey) -> Result<()> { fn verify(&self, _program_id: &Pubkey) -> Result<()> {
self.signature_set
.verify_derivation(program_id, &self.into())?;
Ok(()) Ok(())
} }
} }

View File

@ -5,7 +5,6 @@ use crate::{
GuardianSet, GuardianSet,
GuardianSetDerivationData, GuardianSetDerivationData,
SignatureSet, SignatureSet,
SignatureSetDerivationData,
}, },
error::Error::{ error::Error::{
GuardianSetMismatch, GuardianSetMismatch,
@ -31,7 +30,7 @@ pub struct VerifySignatures<'b> {
pub guardian_set: GuardianSet<'b, { AccountState::Initialized }>, pub guardian_set: GuardianSet<'b, { AccountState::Initialized }>,
/// Signature Account /// Signature Account
pub signature_set: Mut<SignatureSet<'b, { AccountState::MaybeInitialized }>>, pub signature_set: Mut<Signer<SignatureSet<'b, { AccountState::MaybeInitialized }>>>,
/// Instruction reflection account (special sysvar) /// Instruction reflection account (special sysvar)
pub instruction_acc: Info<'b>, pub instruction_acc: Info<'b>,
@ -48,12 +47,6 @@ impl From<&VerifySignatures<'_>> for GuardianSetDerivationData {
} }
} }
impl From<[u8; 32]> for SignatureSetDerivationData {
fn from(hash: [u8; 32]) -> Self {
SignatureSetDerivationData { hash }
}
}
#[derive(Default, BorshSerialize, BorshDeserialize)] #[derive(Default, BorshSerialize, BorshDeserialize)]
pub struct VerifySignaturesData { pub struct VerifySignaturesData {
/// instruction indices of signers (-1 for missing) /// instruction indices of signers (-1 for missing)
@ -182,17 +175,20 @@ pub fn verify_signatures(
let mut msg_hash: [u8; 32] = [0u8; 32]; let mut msg_hash: [u8; 32] = [0u8; 32];
msg_hash.copy_from_slice(message); msg_hash.copy_from_slice(message);
// Confirm at this point that the derivation succeeds, we didn't have a signature set with the
// correct hash until this point.
accs.signature_set
.verify_derivation(ctx.program_id, &msg_hash.into())?;
if !accs.signature_set.is_initialized() { if !accs.signature_set.is_initialized() {
accs.signature_set.signatures = vec![[0u8; 65]; 19]; accs.signature_set.signatures = vec![[0u8; 65]; 19];
accs.signature_set.guardian_set_index = accs.guardian_set.index; accs.signature_set.guardian_set_index = accs.guardian_set.index;
accs.signature_set.hash = msg_hash; accs.signature_set.hash = msg_hash;
accs.signature_set
.create(&msg_hash.into(), ctx, accs.payer.key, Exempt)?; let size = accs.signature_set.size();
let ix = solana_program::system_instruction::create_account(
accs.payer.key,
accs.signature_set.info().key,
Exempt.amount(size),
size as u64,
ctx.program_id,
);
solana_program::program::invoke(&ix, ctx.accounts)?;
} else { } else {
// If the account already existed, check that the parameters match // If the account already existed, check that the parameters match
if accs.signature_set.guardian_set_index != accs.guardian_set.index { if accs.signature_set.guardian_set_index != accs.guardian_set.index {

View File

@ -1,4 +1,3 @@
use std::str::FromStr;
use borsh::BorshSerialize; use borsh::BorshSerialize;
use solana_program::{ use solana_program::{
instruction::{ instruction::{
@ -8,6 +7,7 @@ use solana_program::{
pubkey::Pubkey, pubkey::Pubkey,
sysvar, sysvar,
}; };
use std::str::FromStr;
use solitaire::{ use solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,
@ -27,7 +27,6 @@ use crate::{
Sequence, Sequence,
SequenceDerivationData, SequenceDerivationData,
SignatureSet, SignatureSet,
SignatureSetDerivationData,
}, },
types::ConsistencyLevel, types::ConsistencyLevel,
InitializeData, InitializeData,
@ -140,7 +139,7 @@ pub fn verify_signatures(
program_id: Pubkey, program_id: Pubkey,
payer: Pubkey, payer: Pubkey,
guardian_set_index: u32, guardian_set_index: u32,
hash: [u8; 32], signature_set: Pubkey,
data: VerifySignaturesData, data: VerifySignaturesData,
) -> solitaire::Result<Instruction> { ) -> solitaire::Result<Instruction> {
let guardian_set = GuardianSet::<'_, { AccountState::Uninitialized }>::key( let guardian_set = GuardianSet::<'_, { AccountState::Uninitialized }>::key(
@ -150,18 +149,13 @@ pub fn verify_signatures(
&program_id, &program_id,
); );
let signature_set = SignatureSet::<'_, { AccountState::Uninitialized }>::key(
&SignatureSetDerivationData { hash },
&program_id,
);
Ok(Instruction { Ok(Instruction {
program_id, program_id,
accounts: vec![ accounts: vec![
AccountMeta::new(payer, true), AccountMeta::new(payer, true),
AccountMeta::new_readonly(guardian_set, false), AccountMeta::new_readonly(guardian_set, false),
AccountMeta::new(signature_set, false), AccountMeta::new(signature_set, true),
AccountMeta::new_readonly(sysvar::instructions::id(), false), AccountMeta::new_readonly(sysvar::instructions::id(), false),
AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::rent::id(), false),
AccountMeta::new_readonly(solana_program::system_program::id(), false), AccountMeta::new_readonly(solana_program::system_program::id(), false),
@ -171,7 +165,12 @@ pub fn verify_signatures(
}) })
} }
pub fn post_vaa(program_id: Pubkey, payer: Pubkey, vaa: PostVAAData) -> Instruction { pub fn post_vaa(
program_id: Pubkey,
payer: Pubkey,
signature_set: Pubkey,
vaa: PostVAAData,
) -> Instruction {
let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id); let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
let guardian_set = GuardianSet::<'_, { AccountState::Uninitialized }>::key( let guardian_set = GuardianSet::<'_, { AccountState::Uninitialized }>::key(
&GuardianSetDerivationData { &GuardianSetDerivationData {
@ -180,13 +179,6 @@ pub fn post_vaa(program_id: Pubkey, payer: Pubkey, vaa: PostVAAData) -> Instruct
&program_id, &program_id,
); );
let signature_set = SignatureSet::<'_, { AccountState::Uninitialized }>::key(
&SignatureSetDerivationData {
hash: hash_vaa(&vaa),
},
&program_id,
);
let mut msg_derivation_data = MessageDerivationData { let mut msg_derivation_data = MessageDerivationData {
emitter_key: vaa.emitter_address, emitter_key: vaa.emitter_address,
emitter_chain: vaa.emitter_chain, emitter_chain: vaa.emitter_chain,

View File

@ -1,9 +1,9 @@
use crate::{ use crate::{
api::ForeignAddress, api::ForeignAddress,
vaa::{ vaa::{
SerializeGovernancePayload,
DeserializeGovernancePayload, DeserializeGovernancePayload,
DeserializePayload, DeserializePayload,
SerializeGovernancePayload,
SerializePayload, SerializePayload,
}, },
}; };

View File

@ -69,7 +69,6 @@ use bridge::{
Sequence, Sequence,
SequenceDerivationData, SequenceDerivationData,
SignatureSet, SignatureSet,
SignatureSetDerivationData,
}, },
instruction, instruction,
instructions, instructions,
@ -323,7 +322,9 @@ mod helpers {
body: [u8; 32], body: [u8; 32],
secret_keys: &[SecretKey], secret_keys: &[SecretKey],
guardian_set_version: u32, guardian_set_version: u32,
) -> Result<(), ClientError> { ) -> Result<Pubkey, ClientError> {
let signature_set = Keypair::new();
let tx_signers = &[payer, &signature_set];
// Push Secp256k1 instructions for each signature we want to verify. // Push Secp256k1 instructions for each signature we want to verify.
for (i, key) in secret_keys.iter().enumerate() { for (i, key) in secret_keys.iter().enumerate() {
// Set this signers signature position as present at 0. // Set this signers signature position as present at 0.
@ -333,14 +334,14 @@ mod helpers {
execute( execute(
client, client,
payer, payer,
&[payer], tx_signers,
&vec![ &vec![
new_secp256k1_instruction(&key, &body), new_secp256k1_instruction(&key, &body),
instructions::verify_signatures( instructions::verify_signatures(
*program, *program,
payer.pubkey(), payer.pubkey(),
guardian_set_version, guardian_set_version,
body, signature_set.pubkey(),
VerifySignaturesData { signers }, VerifySignaturesData { signers },
) )
.unwrap(), .unwrap(),
@ -348,20 +349,26 @@ mod helpers {
CommitmentConfig::processed(), CommitmentConfig::processed(),
)?; )?;
} }
Ok(()) Ok(signature_set.pubkey())
} }
pub fn post_vaa( pub fn post_vaa(
client: &RpcClient, client: &RpcClient,
program: &Pubkey, program: &Pubkey,
payer: &Keypair, payer: &Keypair,
signature_set: Pubkey,
vaa: PostVAAData, vaa: PostVAAData,
) -> Result<Signature, ClientError> { ) -> Result<Signature, ClientError> {
execute( execute(
client, client,
payer, payer,
&[payer], &[payer],
&[instructions::post_vaa(*program, payer.pubkey(), vaa)], &[instructions::post_vaa(
*program,
payer.pubkey(),
signature_set,
vaa,
)],
CommitmentConfig::processed(), CommitmentConfig::processed(),
) )
} }

View File

@ -63,7 +63,6 @@ use bridge::{
Message, Message,
MessageDerivationData, MessageDerivationData,
SignatureSet, SignatureSet,
SignatureSetDerivationData,
}, },
instruction, instruction,
types::{ types::{
@ -213,16 +212,11 @@ fn test_bridge_messages(context: &mut Context) {
// Emulate Guardian behaviour, verifying the data and publishing signatures/VAA. // Emulate Guardian behaviour, verifying the data and publishing signatures/VAA.
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::sync(client, payer); common::sync(client, payer);
// Derive where we expect created accounts to be.
let signature_set = SignatureSet::<'_, { AccountState::Uninitialized }>::key(
&SignatureSetDerivationData { hash: body },
&program,
);
// Fetch chain accounts to verify state. // Fetch chain accounts to verify state.
let posted_message: PostedMessage = common::get_account_data(client, &message_key); let posted_message: PostedMessage = common::get_account_data(client, &message_key);
let signatures: SignatureSetData = common::get_account_data(client, &signature_set); let signatures: SignatureSetData = common::get_account_data(client, &signature_set);
@ -277,16 +271,11 @@ fn test_bridge_messages(context: &mut Context) {
// Emulate Guardian behaviour, verifying the data and publishing signatures/VAA. // Emulate Guardian behaviour, verifying the data and publishing signatures/VAA.
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::sync(client, payer); common::sync(client, payer);
// Derive where we expect created accounts to be.
let signature_set = SignatureSet::<'_, { AccountState::Uninitialized }>::key(
&SignatureSetDerivationData { hash: body },
&program,
);
// Fetch chain accounts to verify state. // Fetch chain accounts to verify state.
let posted_message: PostedMessage = common::get_account_data(client, &message_key); let posted_message: PostedMessage = common::get_account_data(client, &message_key);
let signatures: SignatureSetData = common::get_account_data(client, &signature_set); let signatures: SignatureSetData = common::get_account_data(client, &signature_set);
@ -412,6 +401,7 @@ fn test_guardian_set_change(context: &mut Context) {
let nonce = rand::thread_rng().gen(); let nonce = rand::thread_rng().gen();
let emitter = Keypair::from_bytes(&GOVERNANCE_KEY).unwrap(); let emitter = Keypair::from_bytes(&GOVERNANCE_KEY).unwrap();
println!("{}", emitter.pubkey().to_string());
let sequence = context.seq.next(emitter.pubkey().to_bytes()); let sequence = context.seq.next(emitter.pubkey().to_bytes());
let message = GovernancePayloadGuardianSetChange { let message = GovernancePayloadGuardianSetChange {
new_guardian_set_index: 1, new_guardian_set_index: 1,
@ -432,8 +422,9 @@ fn test_guardian_set_change(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::upgrade_guardian_set( common::upgrade_guardian_set(
client, client,
program, program,
@ -487,16 +478,11 @@ fn test_guardian_set_change(context: &mut Context) {
// Emulate Guardian behaviour, verifying the data and publishing signatures/VAA. // Emulate Guardian behaviour, verifying the data and publishing signatures/VAA.
let sequence = context.seq.next(emitter.pubkey().to_bytes()); let sequence = context.seq.next(emitter.pubkey().to_bytes());
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::sync(client, payer); common::sync(client, payer);
// Derive where we expect created accounts to be.
let signature_set = SignatureSet::<'_, { AccountState::Uninitialized }>::key(
&SignatureSetDerivationData { hash: body },
&program,
);
// Fetch chain accounts to verify state. // Fetch chain accounts to verify state.
let posted_message: PostedMessage = common::get_account_data(client, &message_key); let posted_message: PostedMessage = common::get_account_data(client, &message_key);
let signatures: SignatureSetData = common::get_account_data(client, &signature_set); let signatures: SignatureSetData = common::get_account_data(client, &signature_set);
@ -600,8 +586,9 @@ fn test_set_fees(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::set_fees( common::set_fees(
client, client,
program, program,
@ -624,16 +611,9 @@ fn test_set_fees(context: &mut Context) {
let emitter = Keypair::new(); let emitter = Keypair::new();
let nonce = rand::thread_rng().gen(); let nonce = rand::thread_rng().gen();
let message = [0u8; 32].to_vec(); let message = [0u8; 32].to_vec();
assert!(common::post_message( assert!(
client, common::post_message(client, program, payer, &emitter, nonce, message.clone(), 50).is_err()
program, );
payer,
&emitter,
nonce,
message.clone(),
50,
)
.is_err());
common::sync(client, payer); common::sync(client, payer);
assert_eq!( assert_eq!(
@ -658,8 +638,9 @@ fn test_set_fees(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::sync(client, payer); common::sync(client, payer);
// Verify that the fee collector was paid. // Verify that the fee collector was paid.
@ -668,12 +649,6 @@ fn test_set_fees(context: &mut Context) {
account_balance + 100, account_balance + 100,
); );
// Derive where we expect created accounts to be.
let signature_set = SignatureSet::<'_, { AccountState::Uninitialized }>::key(
&SignatureSetDerivationData { hash: body },
&program,
);
// And that the new message is on chain. // And that the new message is on chain.
let posted_message: PostedMessage = common::get_account_data(client, &message_key); let posted_message: PostedMessage = common::get_account_data(client, &message_key);
let signatures: SignatureSetData = common::get_account_data(client, &signature_set); let signatures: SignatureSetData = common::get_account_data(client, &signature_set);
@ -736,8 +711,9 @@ fn test_set_fees_fails(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
assert!(common::set_fees( assert!(common::set_fees(
client, client,
program, program,
@ -758,11 +734,9 @@ fn test_free_fees(context: &mut Context) {
// Set Fees to 0. // Set Fees to 0.
let nonce = rand::thread_rng().gen(); let nonce = rand::thread_rng().gen();
let message = GovernancePayloadSetMessageFee { let message = GovernancePayloadSetMessageFee { fee: U256::from(0) }
fee: U256::from(0), .try_to_vec()
} .unwrap();
.try_to_vec()
.unwrap();
let message_key = common::post_message( let message_key = common::post_message(
client, client,
@ -776,8 +750,9 @@ fn test_free_fees(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::set_fees( common::set_fees(
client, client,
program, program,
@ -801,20 +776,13 @@ fn test_free_fees(context: &mut Context) {
let sequence = context.seq.next(emitter.pubkey().to_bytes()); let sequence = context.seq.next(emitter.pubkey().to_bytes());
let nonce = rand::thread_rng().gen(); let nonce = rand::thread_rng().gen();
let message = [0u8; 32].to_vec(); let message = [0u8; 32].to_vec();
let message_key = common::post_message( let message_key =
client, common::post_message(client, program, payer, &emitter, nonce, message.clone(), 0).unwrap();
program,
payer,
&emitter,
nonce,
message.clone(),
0,
)
.unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::sync(client, payer); common::sync(client, payer);
// Verify that the fee collector was paid. // Verify that the fee collector was paid.
@ -823,12 +791,6 @@ fn test_free_fees(context: &mut Context) {
account_balance, account_balance,
); );
// Derive where we expect created accounts to be.
let signature_set = SignatureSet::<'_, { AccountState::Uninitialized }>::key(
&SignatureSetDerivationData { hash: body },
&program,
);
// And that the new message is on chain. // And that the new message is on chain.
let posted_message: PostedMessage = common::get_account_data(client, &message_key); let posted_message: PostedMessage = common::get_account_data(client, &message_key);
let signatures: SignatureSetData = common::get_account_data(client, &signature_set); let signatures: SignatureSetData = common::get_account_data(client, &signature_set);
@ -895,8 +857,9 @@ fn test_transfer_fees(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::transfer_fees( common::transfer_fees(
client, client,
program, program,
@ -943,8 +906,9 @@ fn test_transfer_fees_fails(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
assert!(common::transfer_fees( assert!(common::transfer_fees(
client, client,
@ -989,8 +953,9 @@ fn test_transfer_too_much(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
// Should fail to transfer. // Should fail to transfer.
assert!(common::transfer_fees( assert!(common::transfer_fees(
@ -1028,15 +993,11 @@ fn test_foreign_bridge_messages(context: &mut Context) {
&program, &program,
); );
common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::sync(client, payer); common::sync(client, payer);
let signature_set = SignatureSet::<'_, { AccountState::Uninitialized }>::key(
&SignatureSetDerivationData { hash: body },
&program,
);
// Fetch chain accounts to verify state. // Fetch chain accounts to verify state.
let posted_message: PostedMessage = common::get_account_data(client, &message_key); let posted_message: PostedMessage = common::get_account_data(client, &message_key);
let signatures: SignatureSetData = common::get_account_data(client, &signature_set); let signatures: SignatureSetData = common::get_account_data(client, &signature_set);
@ -1105,8 +1066,9 @@ fn test_transfer_total_fails(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 1).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
// Transferring total fees should fail, to prevent the account being de-allocated. // Transferring total fees should fail, to prevent the account being de-allocated.
assert!(common::transfer_fees( assert!(common::transfer_fees(
@ -1160,8 +1122,9 @@ fn test_upgrade_contract(context: &mut Context) {
.unwrap(); .unwrap();
let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0, 1); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0, 1);
common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap(); let signature_set =
common::post_vaa(client, program, payer, vaa).unwrap(); common::verify_signatures(client, program, payer, body, &context.secret, 0).unwrap();
common::post_vaa(client, program, payer, signature_set, vaa).unwrap();
common::upgrade_contract( common::upgrade_contract(
client, client,
program, program,