Fix Derivation issues for PostVAA accounts.
Change-Id: Ia08003dc8aadfe3963598c81745813e6e09e5d3a
This commit is contained in:
parent
a28540de0d
commit
16f7e156ae
|
@ -85,7 +85,6 @@ impl<'b, const State: AccountState> Seeded<&MessageDerivationData> for Message<'
|
|||
data.nonce.to_be_bytes().to_vec(),
|
||||
];
|
||||
seeds.append(&mut data.payload.chunks(32).map(|v| v.to_vec()).collect());
|
||||
|
||||
seeds
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
use solitaire::*;
|
||||
|
||||
use solana_program::{self,};
|
||||
|
||||
use crate::types::{
|
||||
self,
|
||||
GovernancePayloadSetMessageFee,
|
||||
|
|
|
@ -114,7 +114,6 @@ pub struct PostVAAData {
|
|||
}
|
||||
|
||||
pub fn post_vaa(ctx: &ExecutionContext, accs: &mut PostVAA, vaa: PostVAAData) -> Result<()> {
|
||||
msg!("Post VAA Entered");
|
||||
let msg_derivation = MessageDerivationData {
|
||||
emitter_key: vaa.emitter_address,
|
||||
emitter_chain: vaa.emitter_chain,
|
||||
|
@ -135,11 +134,7 @@ pub fn post_vaa(ctx: &ExecutionContext, accs: &mut PostVAA, vaa: PostVAAData) ->
|
|||
.signature_set
|
||||
.signatures
|
||||
.iter()
|
||||
.filter(|v|
|
||||
v.0.iter().filter(|v| **v != 0).count() != 0 ||
|
||||
v.1.iter().filter(|v| **v != 0).count() != 0 ||
|
||||
v.2 != 0
|
||||
)
|
||||
.filter(|v| v.iter().filter(|v| **v != 0).count() != 0)
|
||||
.count();
|
||||
|
||||
// Calculate how many signatures are required to reach consensus. This calculation is in
|
||||
|
|
|
@ -200,6 +200,7 @@ pub fn verify_signatures(
|
|||
// Track whether the account needs initialization
|
||||
// Prepare message/payload-specific sig_info account
|
||||
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;
|
||||
|
||||
|
@ -237,12 +238,8 @@ pub fn verify_signatures(
|
|||
}
|
||||
|
||||
// Overwritten content should be zeros except double signs by the signer or harmless replays
|
||||
accs.signature_set.signatures[s.signer_index as usize].0
|
||||
.copy_from_slice(&secp_ixs[s.sig_index as usize].signature[0..32]);
|
||||
accs.signature_set.signatures[s.signer_index as usize].1
|
||||
.copy_from_slice(&secp_ixs[s.sig_index as usize].signature[32..64]);
|
||||
accs.signature_set.signatures[s.signer_index as usize].2 =
|
||||
secp_ixs[s.sig_index as usize].signature[64];
|
||||
accs.signature_set.signatures[s.signer_index as usize]
|
||||
.copy_from_slice(&secp_ixs[s.sig_index as usize].signature);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -73,6 +73,7 @@ pub struct BridgeConfig {
|
|||
/// guarantees that VAAs issued by that set can still be submitted for a certain period. In
|
||||
/// this period we still trust the old guardian set.
|
||||
pub guardian_set_expiration_time: u32,
|
||||
|
||||
/// Amount of lamports that needs to be paid to the protocol to post a message
|
||||
pub fee: u64,
|
||||
}
|
||||
|
@ -95,18 +96,10 @@ impl Owned for BridgeData {
|
|||
}
|
||||
}
|
||||
|
||||
// Temporary work around the fact there is no Default for [u8; 64/65] and therefore no Borsh
|
||||
// implementation for the type. Cannot use Vec<> as we don't know the size to deserialize.
|
||||
type SplitSignature = (
|
||||
[u8; 32],
|
||||
[u8; 32],
|
||||
u8,
|
||||
);
|
||||
|
||||
#[derive(Default, BorshSerialize, BorshDeserialize)]
|
||||
pub struct SignatureSet {
|
||||
/// Signatures of validators
|
||||
pub signatures: [SplitSignature; 19],
|
||||
pub signatures: Vec<[u8; 65]>,
|
||||
|
||||
/// Hash of the data
|
||||
pub hash: [u8; 32],
|
||||
|
@ -126,6 +119,7 @@ pub struct PostedMessage(pub PostedMessageData);
|
|||
|
||||
impl BorshSerialize for PostedMessage {
|
||||
fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
// King of Flavour
|
||||
writer.write(&['m' as u8, 's' as u8, 'g' as u8]);
|
||||
BorshSerialize::serialize(&self.0, writer)
|
||||
}
|
||||
|
@ -133,8 +127,9 @@ impl BorshSerialize for PostedMessage {
|
|||
|
||||
impl BorshDeserialize for PostedMessage {
|
||||
fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
|
||||
*buf = &buf[3..];
|
||||
Ok(PostedMessage(
|
||||
<PostedMessageData as BorshDeserialize>::deserialize(&mut &buf[3..])?,
|
||||
<PostedMessageData as BorshDeserialize>::deserialize(buf)?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use secp256k1::SecretKey;
|
||||
use borsh::BorshSerialize;
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
use solana_client::rpc_config::RpcSendTransactionConfig;
|
||||
use solana_program::{
|
||||
borsh::try_from_slice_unchecked,
|
||||
hash,
|
||||
|
@ -29,6 +30,7 @@ use std::{
|
|||
};
|
||||
|
||||
use solana_sdk::{
|
||||
commitment_config::CommitmentConfig,
|
||||
secp256k1_instruction::new_secp256k1_instruction,
|
||||
signature::{
|
||||
read_keypair_file,
|
||||
|
@ -44,6 +46,7 @@ use bridge::{
|
|||
GuardianSetDerivationData,
|
||||
SignatureSet,
|
||||
SignaturesSetDerivationData,
|
||||
Message,
|
||||
MessageDerivationData,
|
||||
},
|
||||
instruction,
|
||||
|
@ -68,6 +71,18 @@ pub use instructions::*;
|
|||
mod helpers {
|
||||
use super::*;
|
||||
|
||||
fn rpc_send(client: &RpcClient, tx: Transaction) {
|
||||
client.send_and_confirm_transaction_with_spinner_and_config(
|
||||
&tx,
|
||||
CommitmentConfig::processed(),
|
||||
RpcSendTransactionConfig {
|
||||
skip_preflight: true,
|
||||
preflight_commitment: None,
|
||||
encoding: None,
|
||||
},
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
pub fn setup() -> (Keypair, RpcClient, Pubkey) {
|
||||
let payer = read_keypair_file(env::var("BRIDGE_PAYER").unwrap_or("./payer.json".to_string())).unwrap();
|
||||
let rpc = RpcClient::new(env::var("BRIDGE_RPC").unwrap_or("http://127.0.0.1:8899".to_string()));
|
||||
|
@ -75,7 +90,6 @@ mod helpers {
|
|||
.unwrap_or("6mFKdAtUBVbsQ5dgvBrUkn1Pixb7BMTUtVKj4dpwrmQs".to_string())
|
||||
.parse::<Pubkey>()
|
||||
.unwrap();
|
||||
|
||||
(payer, rpc, program)
|
||||
}
|
||||
|
||||
|
@ -85,7 +99,7 @@ mod helpers {
|
|||
let mut transaction = Transaction::new_with_payer(&instructions, Some(&from.pubkey()));
|
||||
let recent_blockhash = client.get_recent_blockhash().unwrap().0;
|
||||
transaction.sign(&signers, recent_blockhash);
|
||||
client.send_and_confirm_transaction(&transaction).unwrap();
|
||||
rpc_send(client, transaction);
|
||||
}
|
||||
|
||||
pub fn initialize(
|
||||
|
@ -112,7 +126,7 @@ mod helpers {
|
|||
let recent_blockhash = client.get_recent_blockhash().unwrap().0;
|
||||
|
||||
transaction.sign(&signers, recent_blockhash);
|
||||
client.send_and_confirm_transaction(&transaction).unwrap();
|
||||
rpc_send(client, transaction);
|
||||
}
|
||||
|
||||
pub fn post_message(
|
||||
|
@ -132,7 +146,7 @@ mod helpers {
|
|||
emitter_key: emitter.pubkey().to_bytes(),
|
||||
emitter_chain: message.emitter_chain,
|
||||
nonce: message.nonce,
|
||||
payload: message.payload,
|
||||
payload: message.payload.clone(),
|
||||
}, program);
|
||||
|
||||
println!("PostMessage: Derived Keys:");
|
||||
|
@ -160,7 +174,7 @@ mod helpers {
|
|||
let recent_blockhash = client.get_recent_blockhash().unwrap().0;
|
||||
|
||||
transaction.sign(&signers, recent_blockhash);
|
||||
client.send_and_confirm_transaction(&transaction).unwrap();
|
||||
rpc_send(client, transaction);
|
||||
}
|
||||
|
||||
pub fn verify_signatures(
|
||||
|
@ -208,23 +222,45 @@ mod helpers {
|
|||
let recent_blockhash = client.get_recent_blockhash().unwrap().0;
|
||||
|
||||
transaction.sign(&signers, recent_blockhash);
|
||||
client.send_and_confirm_transaction(&transaction).unwrap();
|
||||
rpc_send(client, transaction);
|
||||
}
|
||||
|
||||
pub fn post_vaa(
|
||||
client: &RpcClient,
|
||||
program: &Pubkey,
|
||||
payer: &Keypair,
|
||||
body_hash: [u8; 32],
|
||||
message: Vec<u8>,
|
||||
emitter: &Keypair,
|
||||
guardian_set: GuardianSetDerivationData,
|
||||
vaa: PostVAAData,
|
||||
) {
|
||||
let (bridge, _) = Pubkey::find_program_address(&["Bridge".as_ref()], program);
|
||||
let guardian_set = GuardianSet::<'_, { AccountState::Uninitialized }>::key(
|
||||
&guardian_set,
|
||||
&program,
|
||||
);
|
||||
let (bridge, _) = Pubkey::find_program_address(&["Bridge".as_ref()], program);
|
||||
let signature_set = Pubkey::new_unique();
|
||||
let message = Pubkey::new_unique();
|
||||
|
||||
let signatures = SignatureSet::<'_, { AccountState::Uninitialized }>::key(
|
||||
&SignaturesSetDerivationData {
|
||||
hash: body_hash,
|
||||
},
|
||||
&program,
|
||||
);
|
||||
|
||||
let message = Message::<'_, { AccountState::MaybeInitialized }>::key(
|
||||
&MessageDerivationData {
|
||||
emitter_key: emitter.pubkey().to_bytes(),
|
||||
emitter_chain: 1,
|
||||
nonce: 0,
|
||||
payload: message,
|
||||
},
|
||||
&program,
|
||||
);
|
||||
|
||||
println!("PostVAA: Derived Key:");
|
||||
println!("GuardianSet: {}", guardian_set);
|
||||
println!("Signatures: {}", signatures);
|
||||
|
||||
let signers = vec![payer];
|
||||
let instructions = [instructions::create_post_vaa(
|
||||
|
@ -232,7 +268,7 @@ mod helpers {
|
|||
payer.pubkey(),
|
||||
guardian_set,
|
||||
bridge,
|
||||
signature_set,
|
||||
signatures,
|
||||
message,
|
||||
vaa,
|
||||
)];
|
||||
|
@ -241,7 +277,7 @@ mod helpers {
|
|||
let recent_blockhash = client.get_recent_blockhash().unwrap().0;
|
||||
|
||||
transaction.sign(&signers, recent_blockhash);
|
||||
client.send_and_confirm_transaction(&transaction).unwrap();
|
||||
rpc_send(client, transaction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ use bridge::{
|
|||
types::{
|
||||
BridgeConfig,
|
||||
PostedMessage,
|
||||
PostedMessageData,
|
||||
SequenceTracker,
|
||||
SignatureSet,
|
||||
},
|
||||
|
@ -94,7 +95,7 @@ fn test_bridge_messages() {
|
|||
// Guardians sign, verify, and we produce VAA data here.
|
||||
let (vaa, body, body_hash, secret_key) = guardian_sign_round(
|
||||
&emitter,
|
||||
data,
|
||||
data.clone(),
|
||||
);
|
||||
|
||||
common::verify_signatures(
|
||||
|
@ -112,12 +113,14 @@ fn test_bridge_messages() {
|
|||
client,
|
||||
program,
|
||||
payer,
|
||||
body_hash,
|
||||
data,
|
||||
&emitter,
|
||||
GuardianSetDerivationData { index: 0 },
|
||||
vaa,
|
||||
);
|
||||
|
||||
// // Verify a Signature
|
||||
// common::verify_signature(client, program, payer);
|
||||
// Did it actually work?
|
||||
}
|
||||
|
||||
/// A utility function for emulating what the guardians should be doing, I.E, detecting a message
|
||||
|
@ -172,8 +175,6 @@ fn guardian_sign_round(
|
|||
h.finalize().into()
|
||||
};
|
||||
|
||||
println!("Ahs: {:?}", body_hash);
|
||||
|
||||
// Sign the body hash of the VAA.
|
||||
let sig = secp256k1::sign(
|
||||
&Message::parse(&body_hash),
|
||||
|
@ -193,7 +194,7 @@ fn guardian_sign_round(
|
|||
}
|
||||
|
||||
fn create_message(data: Vec<u8>) -> PostedMessage {
|
||||
PostedMessage {
|
||||
PostedMessage(PostedMessageData {
|
||||
vaa_version: 0,
|
||||
vaa_time: 0,
|
||||
vaa_signature_account: Pubkey::new_unique(),
|
||||
|
@ -207,5 +208,5 @@ fn create_message(data: Vec<u8>) -> PostedMessage {
|
|||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs() as u32,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -19,8 +19,9 @@ macro_rules! solitaire {
|
|||
use solana_program::{
|
||||
account_info::AccountInfo,
|
||||
entrypoint::ProgramResult,
|
||||
program_error::ProgramError,
|
||||
program_error::ProgramError,
|
||||
pubkey::Pubkey,
|
||||
msg,
|
||||
};
|
||||
use solitaire::{FromAccounts, Persist, Result};
|
||||
|
||||
|
@ -39,6 +40,7 @@ macro_rules! solitaire {
|
|||
match Instruction::try_from_slice(d).map_err(|e| SolitaireError::InstructionDeserializeFailed(e))? {
|
||||
$(
|
||||
Instruction::$row(ix_data) => {
|
||||
msg!("Dispatch: {}", stringify!($row));
|
||||
let (mut accounts): ($row) = FromAccounts::from(p, &mut a.iter(), &())?;
|
||||
$fn(&ExecutionContext{program_id: p, accounts: a}, &mut accounts, ix_data)?;
|
||||
Persist::persist(&accounts, p)?;
|
||||
|
|
|
@ -158,7 +158,7 @@ impl<
|
|||
}
|
||||
AccountState::Initialized => {
|
||||
initialized = true;
|
||||
T::try_from_slice(&mut *ctx.info().data.borrow_mut())?
|
||||
T::try_from_slice(&mut *ctx.info().data.borrow_mut()).expect("Blew up in Initialized")
|
||||
}
|
||||
AccountState::MaybeInitialized => {
|
||||
if **ctx.info().lamports.borrow() == 0 {
|
||||
|
|
|
@ -45,7 +45,7 @@ pub enum AccountState {
|
|||
///
|
||||
/// Data<(), { AccountState::Uninitialized }>
|
||||
#[rustfmt::skip]
|
||||
pub struct Data<'r, T: Owned + Default + Default, const IsInitialized: AccountState> (
|
||||
pub struct Data<'r, T: Owned + Default, const IsInitialized: AccountState> (
|
||||
pub Info<'r>,
|
||||
pub T,
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue