diff --git a/solana/bridge/agent/src/socket.rs b/solana/bridge/agent/src/socket.rs index d84a9656..4ac007c8 100644 --- a/solana/bridge/agent/src/socket.rs +++ b/solana/bridge/agent/src/socket.rs @@ -3,16 +3,23 @@ use std::{ pin::Pin, - task::{Context, Poll}, + task::{ + Context, + Poll, + }, }; -use tokio::io::{AsyncRead, AsyncWrite}; +use tokio::io::{ + AsyncRead, + AsyncWrite, +}; use tonic::transport::server::Connected; #[derive(Debug)] pub struct UnixStream(pub tokio::net::UnixStream); -impl Connected for UnixStream {} +impl Connected for UnixStream { +} impl AsyncRead for UnixStream { fn poll_read( @@ -37,10 +44,7 @@ impl AsyncWrite for UnixStream { Pin::new(&mut self.0).poll_flush(cx) } - fn poll_shutdown( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut self.0).poll_shutdown(cx) } } diff --git a/solana/bridge/client/src/main.rs b/solana/bridge/client/src/main.rs index 56cff290..0d895850 100644 --- a/solana/bridge/client/src/main.rs +++ b/solana/bridge/client/src/main.rs @@ -76,7 +76,7 @@ type CommmandResult = Result, Error>; fn command_deploy_bridge( config: &Config, bridge: &Pubkey, - _initial_guardian: Vec<[u8; 20]>, + initial_guardians: Vec<[u8; 20]>, guardian_expiration: u32, message_fee: u64, ) -> CommmandResult { @@ -86,11 +86,12 @@ fn command_deploy_bridge( .rpc_client .get_minimum_balance_for_rent_exemption(size_of::())?; - let ix = bridge::client_instructions::initialize( + let ix = bridge::instructions::initialize( *bridge, config.owner.pubkey(), message_fee, guardian_expiration, + initial_guardians.as_slice(), ) .unwrap(); println!("config account: {}, ", ix.accounts[0].pubkey.to_string()); @@ -127,7 +128,7 @@ fn command_post_message( &FeeCollector::key(None, bridge), bridge_config.config.fee, ); - let ix = bridge::client_instructions::post_message( + let (_, ix) = bridge::instructions::post_message( *bridge, config.owner.pubkey(), config.fee_payer.pubkey(), diff --git a/solana/bridge/program/src/accounts.rs b/solana/bridge/program/src/accounts.rs index c65de789..8294a874 100644 --- a/solana/bridge/program/src/accounts.rs +++ b/solana/bridge/program/src/accounts.rs @@ -30,7 +30,7 @@ impl<'b, const State: AccountState> Seeded<&GuardianSetDerivationData> fn seeds(data: &GuardianSetDerivationData) -> Vec> { vec![ "GuardianSet".as_bytes().to_vec(), - data.index.to_be_bytes().to_vec() + data.index.to_be_bytes().to_vec(), ] } } diff --git a/solana/bridge/program/src/api/initialize.rs b/solana/bridge/program/src/api/initialize.rs index f582aa7f..4147e351 100644 --- a/solana/bridge/program/src/api/initialize.rs +++ b/solana/bridge/program/src/api/initialize.rs @@ -6,6 +6,7 @@ use crate::{ GuardianSetDerivationData, }, types::*, + Error::TooManyGuardians, MAX_LEN_GUARDIAN_KEYS, }; use solitaire::{ @@ -47,6 +48,10 @@ pub fn initialize( ) -> Result<()> { let index = 0; + if data.initial_guardians.len() > MAX_LEN_GUARDIAN_KEYS { + return Err(TooManyGuardians.into()); + } + // Allocate a default guardian set, with zeroed keys. accs.guardian_set.index = index; accs.guardian_set.creation_time = 0; diff --git a/solana/bridge/program/src/api/post_vaa.rs b/solana/bridge/program/src/api/post_vaa.rs index 5e9c03c5..fd3c313f 100644 --- a/solana/bridge/program/src/api/post_vaa.rs +++ b/solana/bridge/program/src/api/post_vaa.rs @@ -118,8 +118,10 @@ pub fn post_vaa(ctx: &ExecutionContext, accs: &mut PostVAA, vaa: PostVAAData) -> payload: vaa.payload.clone(), }; - accs.message.verify_derivation(ctx.program_id, &msg_derivation)?; - accs.guardian_set.verify_derivation(ctx.program_id, &(&vaa).into())?; + accs.message + .verify_derivation(ctx.program_id, &msg_derivation)?; + accs.guardian_set + .verify_derivation(ctx.program_id, &(&vaa).into())?; // Verify any required invariants before we process the instruction. check_active(&accs.guardian_set, &accs.clock)?; diff --git a/solana/bridge/program/src/api/verify_signature.rs b/solana/bridge/program/src/api/verify_signature.rs index a1708243..4944b3c1 100644 --- a/solana/bridge/program/src/api/verify_signature.rs +++ b/solana/bridge/program/src/api/verify_signature.rs @@ -52,9 +52,7 @@ impl From<&VerifySignatures<'_>> for GuardianSetDerivationData { impl From<[u8; 32]> for SignatureSetDerivationData { fn from(hash: [u8; 32]) -> Self { - SignatureSetDerivationData { - hash - } + SignatureSetDerivationData { hash } } } @@ -196,16 +194,15 @@ pub fn verify_signatures( // 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(), - )?; + accs.signature_set + .verify_derivation(ctx.program_id, &msg_hash.into())?; if !accs.signature_set.is_initialized() { accs.signature_set.signatures = vec![[0u8; 65]; 19]; accs.signature_set.guardian_set_index = accs.guardian_set.index; accs.signature_set.hash = data.hash; - accs.signature_set.create(&msg_hash.into(), ctx, accs.payer.key, Exempt)?; + accs.signature_set + .create(&msg_hash.into(), ctx, accs.payer.key, Exempt)?; } else { // If the account already existed, check that the parameters match if accs.signature_set.guardian_set_index != accs.guardian_set.index { diff --git a/solana/bridge/program/src/instructions.rs b/solana/bridge/program/src/instructions.rs index a412233a..1b24b657 100644 --- a/solana/bridge/program/src/instructions.rs +++ b/solana/bridge/program/src/instructions.rs @@ -32,7 +32,6 @@ use crate::{ GovernancePayloadUpgrade, PostedMessage, }, - BridgeConfig, InitializeData, PayloadMessage, PostMessageData, @@ -104,27 +103,30 @@ pub fn post_message( &program_id, ); - Ok((message, Instruction { - program_id, + Ok(( + message, + Instruction { + program_id, - accounts: vec![ - AccountMeta::new(bridge, false), - AccountMeta::new(message, false), - AccountMeta::new(emitter, true), - AccountMeta::new(sequence, false), - AccountMeta::new(payer, true), - AccountMeta::new(fee_collector, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::rent::id(), false), - AccountMeta::new_readonly(solana_program::system_program::id(), false), - ], + accounts: vec![ + AccountMeta::new(bridge, false), + AccountMeta::new(message, false), + AccountMeta::new(emitter, true), + AccountMeta::new(sequence, false), + AccountMeta::new(payer, true), + AccountMeta::new(fee_collector, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + AccountMeta::new_readonly(solana_program::system_program::id(), false), + ], - data: crate::instruction::Instruction::PostMessage(PostMessageData { - nonce, - payload: payload.clone(), - }) - .try_to_vec()?, - })) + data: crate::instruction::Instruction::PostMessage(PostMessageData { + nonce, + payload: payload.clone(), + }) + .try_to_vec()?, + }, + )) } pub fn verify_signatures( diff --git a/solana/bridge/program/src/lib.rs b/solana/bridge/program/src/lib.rs index f4028086..af497da3 100644 --- a/solana/bridge/program/src/lib.rs +++ b/solana/bridge/program/src/lib.rs @@ -49,9 +49,6 @@ pub use vaa::{ SerializePayload, }; -// BridgeConfig is the type of the main state the program maintains for itself. -use types::BridgeConfig; - const MAX_LEN_GUARDIAN_KEYS: usize = 19; #[derive(Debug)] @@ -70,6 +67,7 @@ enum Error { PostVAAConsensusFailed, PostVAAGuardianSetExpired, VAAAlreadyExecuted, + TooManyGuardians, } /// Translate from program specific errors to Solitaire framework errors. Log the error on the way diff --git a/solana/bridge/program/tests/integration.rs b/solana/bridge/program/tests/integration.rs index c8aadfcd..ff54664f 100644 --- a/solana/bridge/program/tests/integration.rs +++ b/solana/bridge/program/tests/integration.rs @@ -47,12 +47,12 @@ use std::time::{ SystemTime, }; -use sha3::Digest; use hex_literal::hex; use secp256k1::{ PublicKey, SecretKey, }; +use sha3::Digest; use bridge::{ accounts::GuardianSetDerivationData, @@ -67,8 +67,8 @@ use bridge::{ }, Initialize, PostVAAData, - Signature, SerializePayload, + Signature, }; mod common; @@ -134,21 +134,10 @@ fn test_bridge_messages() { let data = update_guardian_set(1, &public_keys); let message_key = common::post_message(client, program, payer, &emitter, nonce, data.clone()); - common::upgrade_guardian_set( - client, - program, - payer, - message_key, - emitter.pubkey(), - 0, - 1, - ); + common::upgrade_guardian_set(client, program, payer, message_key, emitter.pubkey(), 0, 1); } -fn update_guardian_set( - index: u32, - keys: &[[u8; 20]], -) -> Vec { +fn update_guardian_set(index: u32, keys: &[[u8; 20]]) -> Vec { let mut v = Cursor::new(Vec::new()); v.write_u32::(index).unwrap(); v.write_u8(keys.len() as u8).unwrap(); diff --git a/solana/solitaire/program/src/macros.rs b/solana/solitaire/program/src/macros.rs index ab1b46fd..0c04e022 100644 --- a/solana/solitaire/program/src/macros.rs +++ b/solana/solitaire/program/src/macros.rs @@ -19,7 +19,7 @@ macro_rules! trace_impl { #[cfg(not(feature = "trace"))] #[macro_export] macro_rules! trace_impl { - ( $($arg:tt)* ) => {} + ( $($arg:tt)* ) => {}; } /// This is our main codegen macro. It takes as input a list of enum-like variants mapping field diff --git a/solana/solitaire/program/src/processors/seeded.rs b/solana/solitaire/program/src/processors/seeded.rs index 6470e7d2..a10bb879 100644 --- a/solana/solitaire/program/src/processors/seeded.rs +++ b/solana/solitaire/program/src/processors/seeded.rs @@ -24,9 +24,9 @@ use borsh::{ use solana_program::{ entrypoint::ProgramResult, instruction::Instruction, + msg, program::invoke_signed, pubkey::Pubkey, - msg, }; pub trait AccountSize { diff --git a/solana/solitaire/program/src/types/context.rs b/solana/solitaire/program/src/types/context.rs index 965b012a..1bd55689 100644 --- a/solana/solitaire/program/src/types/context.rs +++ b/solana/solitaire/program/src/types/context.rs @@ -1,3 +1,4 @@ +use crate::trace; use solana_program::{ account_info::{ next_account_info, @@ -6,7 +7,6 @@ use solana_program::{ pubkey::Pubkey, }; use std::slice::Iter; -use crate::trace; /// The context is threaded through each check. Include anything within this structure that you /// would like to have access to as each layer of dependency is peeled off.