Update tests to use initial guardian set.
Change-Id: I11cd5d5bc518ce69e12a289211f21b992eef9ffe
This commit is contained in:
parent
44384e635f
commit
30e8419f93
|
@ -18,7 +18,6 @@ use solitaire::{
|
|||
pub type FeeCollector<'a> = Derive<Info<'a>, "fee_collector">;
|
||||
pub type Bridge<'a, const State: AccountState> = Derive<Data<'a, BridgeData, { State }>, "Bridge">;
|
||||
|
||||
|
||||
pub type GuardianSet<'b, const State: AccountState> = Data<'b, types::GuardianSetData, { State }>;
|
||||
|
||||
pub struct GuardianSetDerivationData {
|
||||
|
|
|
@ -85,7 +85,7 @@ pub fn post_message(
|
|||
emitter: Pubkey,
|
||||
nonce: u32,
|
||||
payload: Vec<u8>,
|
||||
) -> solitaire::Result<Instruction> {
|
||||
) -> solitaire::Result<(Pubkey, Instruction)> {
|
||||
let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
|
||||
let fee_collector = FeeCollector::<'_>::key(None, &program_id);
|
||||
let sequence = Sequence::<'_>::key(
|
||||
|
@ -104,7 +104,7 @@ pub fn post_message(
|
|||
&program_id,
|
||||
);
|
||||
|
||||
Ok(Instruction {
|
||||
Ok((message, Instruction {
|
||||
program_id,
|
||||
|
||||
accounts: vec![
|
||||
|
@ -124,7 +124,7 @@ pub fn post_message(
|
|||
payload: payload.clone(),
|
||||
})
|
||||
.try_to_vec()?,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn verify_signatures(
|
||||
|
@ -255,7 +255,7 @@ pub fn upgrade_guardian_set(
|
|||
&ClaimDerivationData {
|
||||
emitter_address: emitter.to_bytes(),
|
||||
emitter_chain: 1,
|
||||
sequence: 0,
|
||||
sequence: 1,
|
||||
},
|
||||
&program_id,
|
||||
);
|
||||
|
|
|
@ -121,12 +121,24 @@ mod helpers {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn initialize(client: &RpcClient, program: &Pubkey, payer: &Keypair) {
|
||||
pub fn initialize(
|
||||
client: &RpcClient,
|
||||
program: &Pubkey,
|
||||
payer: &Keypair,
|
||||
initial_guardians: &[[u8; 20]],
|
||||
) {
|
||||
execute(
|
||||
client,
|
||||
payer,
|
||||
&[payer],
|
||||
&[instructions::initialize(*program, payer.pubkey(), 500, 2_000_000_000).unwrap()],
|
||||
&[instructions::initialize(
|
||||
*program,
|
||||
payer.pubkey(),
|
||||
500,
|
||||
2_000_000_000,
|
||||
initial_guardians,
|
||||
)
|
||||
.unwrap()],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -135,26 +147,24 @@ mod helpers {
|
|||
program: &Pubkey,
|
||||
payer: &Keypair,
|
||||
emitter: &Keypair,
|
||||
sequence: u64,
|
||||
nonce: u32,
|
||||
data: Vec<u8>,
|
||||
) {
|
||||
) -> Pubkey {
|
||||
// Transfer money into the fee collector as it needs a balance/must exist.
|
||||
let fee_collector = FeeCollector::<'_>::key(None, program);
|
||||
transfer(client, payer, &fee_collector, 1000000);
|
||||
transfer(client, payer, &fee_collector, 100_000_000_000);
|
||||
|
||||
let (message_key, instruction) = instructions::post_message(*program, payer.pubkey(), emitter.pubkey(), nonce, data)
|
||||
.unwrap();
|
||||
|
||||
execute(
|
||||
client,
|
||||
payer,
|
||||
&[payer, emitter],
|
||||
&[instructions::post_message(
|
||||
*program,
|
||||
payer.pubkey(),
|
||||
emitter.pubkey(),
|
||||
0,
|
||||
data,
|
||||
)
|
||||
.unwrap()],
|
||||
&[instruction],
|
||||
);
|
||||
|
||||
message_key
|
||||
}
|
||||
|
||||
pub fn verify_signatures(
|
||||
|
@ -188,6 +198,7 @@ mod helpers {
|
|||
program: &Pubkey,
|
||||
payer: &Keypair,
|
||||
vaa: PostVAAData,
|
||||
guardian_set_index: u32,
|
||||
) {
|
||||
execute(
|
||||
client,
|
||||
|
@ -196,8 +207,90 @@ mod helpers {
|
|||
&[instructions::post_vaa(
|
||||
*program,
|
||||
payer.pubkey(),
|
||||
*emitter,
|
||||
guardian_set_index,
|
||||
vaa,
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
pub fn upgrade_contract(
|
||||
client: &RpcClient,
|
||||
program: &Pubkey,
|
||||
payer: &Keypair,
|
||||
payload_message: Pubkey,
|
||||
spill: Pubkey,
|
||||
) {
|
||||
execute(
|
||||
client,
|
||||
payer,
|
||||
&[payer],
|
||||
&[instructions::upgrade_contract(
|
||||
*program,
|
||||
payer.pubkey(),
|
||||
payload_message,
|
||||
spill,
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
pub fn upgrade_guardian_set(
|
||||
client: &RpcClient,
|
||||
program: &Pubkey,
|
||||
payer: &Keypair,
|
||||
payload_message: Pubkey,
|
||||
emitter: Pubkey,
|
||||
old_index: u32,
|
||||
new_index: u32,
|
||||
) {
|
||||
execute(
|
||||
client,
|
||||
payer,
|
||||
&[payer],
|
||||
&[instructions::upgrade_guardian_set(
|
||||
*program,
|
||||
payer.pubkey(),
|
||||
payload_message,
|
||||
emitter,
|
||||
old_index,
|
||||
new_index,
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
pub fn set_fees(
|
||||
client: &RpcClient,
|
||||
program: &Pubkey,
|
||||
payer: &Keypair,
|
||||
fee: u32,
|
||||
) {
|
||||
execute(
|
||||
client,
|
||||
payer,
|
||||
&[payer],
|
||||
&[instructions::set_fees(
|
||||
*program,
|
||||
payer.pubkey(),
|
||||
fee,
|
||||
)],
|
||||
);
|
||||
}
|
||||
|
||||
pub fn transfer_fees(
|
||||
client: &RpcClient,
|
||||
program: &Pubkey,
|
||||
payer: &Keypair,
|
||||
recipient: &Pubkey,
|
||||
) {
|
||||
execute(
|
||||
client,
|
||||
payer,
|
||||
&[payer],
|
||||
&[instructions::transfer_fees(
|
||||
*program,
|
||||
payer.pubkey(),
|
||||
*recipient,
|
||||
)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(warnings)]
|
||||
|
||||
use borsh::BorshSerialize;
|
||||
use secp256k1::{Message};
|
||||
use secp256k1::Message;
|
||||
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
use solana_program::{
|
||||
|
@ -34,10 +34,12 @@ use byteorder::{
|
|||
WriteBytesExt,
|
||||
};
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::io::{
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
io::{
|
||||
Cursor,
|
||||
Write,
|
||||
},
|
||||
};
|
||||
|
||||
use std::time::{
|
||||
|
@ -52,6 +54,7 @@ use bridge::{
|
|||
instruction,
|
||||
types::{
|
||||
BridgeConfig,
|
||||
GovernancePayloadGuardianSetChange,
|
||||
PostedMessage,
|
||||
PostedMessageData,
|
||||
SequenceTracker,
|
||||
|
@ -60,62 +63,76 @@ use bridge::{
|
|||
Initialize,
|
||||
PostVAAData,
|
||||
Signature,
|
||||
SerializePayload,
|
||||
};
|
||||
|
||||
mod common;
|
||||
|
||||
/// Test messages coming from another chain other than Solana.
|
||||
#[test]
|
||||
fn test_alien_chain_messages() {
|
||||
}
|
||||
|
||||
/// Ethereum Address (Keccak hashed Public Key)
|
||||
const INITIAL_PUBLIC: [u8; 20] = [
|
||||
0x1d, 0x72, 0x87, 0x7e, 0xb2, 0xd8, 0x98, 0x73, 0x8a, 0xfe, 0x94, 0xc6, 0x10, 0x11, 0x52, 0xed,
|
||||
0xe0, 0x43, 0x5d, 0xe9,
|
||||
];
|
||||
|
||||
/// Secp256k1 Secret Key, used as the single initial guardian for testing.
|
||||
const INITIAL_SECRET: [u8; 32] = [
|
||||
0x99, 0x70, 0x1c, 0x80, 0x5e, 0xf9, 0x38, 0xe1, 0x3f, 0x0e, 0x48, 0xf0, 0x9e, 0x2c, 0x32, 0x78,
|
||||
0x91, 0xc1, 0xd8, 0x47, 0x29, 0xd1, 0x52, 0xf3, 0x01, 0xe7, 0xe6, 0x2c, 0xbf, 0x1f, 0x91, 0xc9,
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_bridge_messages() {
|
||||
// Data we want to verify exists, wrapped in a message the guardians can process.
|
||||
let nonce = 12397;
|
||||
let data = b"Prove Me".to_vec();
|
||||
|
||||
// Initialize a wormhole bridge on Solana to test with.
|
||||
let (ref payer, ref client, ref program) = common::setup();
|
||||
|
||||
// Emitting Entity needs a keypair for signing.
|
||||
// Keypair representing the emitting entity for our messages.
|
||||
let emitter = Keypair::new();
|
||||
|
||||
// Data we want to verify exists.
|
||||
let data = vec![];
|
||||
let message = create_message(data.clone());
|
||||
// Initialize the Bridge.
|
||||
common::initialize(client, program, payer, &[INITIAL_PUBLIC]);
|
||||
|
||||
// Initialize the Bridge
|
||||
common::initialize(
|
||||
// Post the message, publishing the data for guardian consumption.
|
||||
common::post_message(client, program, payer, &emitter, nonce, data.clone());
|
||||
|
||||
// Emulate Guardian behaviour, verifying the data and publishing signatures/VAA.
|
||||
let (vaa, body, body_hash, secret_key) = guardian_sign_round(&emitter, data.clone(), nonce);
|
||||
common::verify_signatures(client, program, payer, body, body_hash, secret_key);
|
||||
common::post_vaa(client, program, payer, &emitter.pubkey(), vaa, 0);
|
||||
|
||||
// Upgrade the guardian set with a new set of guardians.
|
||||
let nonce = 12398;
|
||||
let data = update_guardian_set(1, &[INITIAL_PUBLIC]);
|
||||
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,
|
||||
);
|
||||
}
|
||||
|
||||
// Post a Message
|
||||
common::post_message(
|
||||
client,
|
||||
program,
|
||||
payer,
|
||||
&emitter,
|
||||
message.0.sequence,
|
||||
message.0.payload,
|
||||
);
|
||||
|
||||
// Guardians sign, verify, and we produce VAA data here.
|
||||
let (vaa, body, body_hash, secret_key) = guardian_sign_round(
|
||||
&emitter,
|
||||
data.clone(),
|
||||
);
|
||||
|
||||
common::verify_signatures(
|
||||
client,
|
||||
program,
|
||||
payer,
|
||||
body,
|
||||
body_hash,
|
||||
secret_key,
|
||||
);
|
||||
|
||||
// Post VAA
|
||||
common::post_vaa(
|
||||
client,
|
||||
program,
|
||||
payer,
|
||||
vaa,
|
||||
);
|
||||
|
||||
// Did it actually work?
|
||||
fn update_guardian_set(
|
||||
index: u32,
|
||||
keys: &[[u8; 20]],
|
||||
) -> Vec<u8> {
|
||||
let mut v = Cursor::new(Vec::new());
|
||||
v.write_u32::<BigEndian>(index).unwrap();
|
||||
v.write_u8(keys.len() as u8).unwrap();
|
||||
keys.iter().map(|key| v.write(key));
|
||||
v.into_inner()
|
||||
}
|
||||
|
||||
/// A utility function for emulating what the guardians should be doing, I.E, detecting a message
|
||||
|
@ -123,13 +140,13 @@ fn test_bridge_messages() {
|
|||
fn guardian_sign_round(
|
||||
emitter: &Keypair,
|
||||
data: Vec<u8>,
|
||||
nonce: u32,
|
||||
) -> (PostVAAData, Vec<u8>, [u8; 32], secp256k1::SecretKey) {
|
||||
let mut vaa = PostVAAData {
|
||||
version: 0,
|
||||
guardian_set_index: 0,
|
||||
|
||||
// Body part
|
||||
nonce: 0,
|
||||
emitter_chain: 1,
|
||||
emitter_address: emitter.pubkey().to_bytes(),
|
||||
sequence: 0,
|
||||
|
@ -138,6 +155,7 @@ fn guardian_sign_round(
|
|||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs() as u32,
|
||||
nonce,
|
||||
};
|
||||
|
||||
// Hash data, the thing we wish to actually sign.
|
||||
|
@ -147,17 +165,13 @@ fn guardian_sign_round(
|
|||
v.write_u32::<BigEndian>(vaa.nonce).unwrap();
|
||||
v.write_u16::<BigEndian>(vaa.emitter_chain).unwrap();
|
||||
v.write(&vaa.emitter_address).unwrap();
|
||||
v.write_u64::<BigEndian>(vaa.sequence).unwrap();
|
||||
v.write(&vaa.payload).unwrap();
|
||||
v.into_inner()
|
||||
};
|
||||
|
||||
// Public Key: 0x1d72877eb2d898738afe94c6101152ede0435de9
|
||||
let secret_key = secp256k1::SecretKey::parse(&[
|
||||
0x99, 0x70, 0x1c, 0x80, 0x5e, 0xf9, 0x38, 0xe1, 0x3f, 0x0e, 0x48, 0xf0, 0x9e, 0x2c, 0x32,
|
||||
0x78, 0x91, 0xc1, 0xd8, 0x47, 0x29, 0xd1, 0x52, 0xf3, 0x01, 0xe7, 0xe6, 0x2c, 0xbf, 0x1f,
|
||||
0x91, 0xc9
|
||||
]).unwrap();
|
||||
|
||||
let secret_key = secp256k1::SecretKey::parse(&INITIAL_SECRET).unwrap();
|
||||
let public_key = secp256k1::PublicKey::from_secret_key(&secret_key);
|
||||
println!("{}", hex::encode(&public_key.serialize()));
|
||||
|
||||
|
@ -170,10 +184,7 @@ fn guardian_sign_round(
|
|||
};
|
||||
|
||||
// Sign the body hash of the VAA.
|
||||
let sig = secp256k1::sign(
|
||||
&Message::parse(&body_hash),
|
||||
&secret_key,
|
||||
);
|
||||
let sig = secp256k1::sign(&Message::parse(&body_hash), &secret_key);
|
||||
|
||||
// Insert signature into VAA.
|
||||
let signature = sig.0.serialize();
|
||||
|
@ -186,21 +197,3 @@ fn guardian_sign_round(
|
|||
|
||||
(vaa, body, body_hash, secret_key)
|
||||
}
|
||||
|
||||
fn create_message(data: Vec<u8>) -> PostedMessage {
|
||||
PostedMessage(PostedMessageData {
|
||||
vaa_version: 0,
|
||||
vaa_time: 0,
|
||||
vaa_signature_account: Pubkey::new_unique(),
|
||||
|
||||
nonce: 0,
|
||||
sequence: 0,
|
||||
emitter_chain: 1,
|
||||
emitter_address: [0u8; 32],
|
||||
payload: data,
|
||||
submission_time: SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs() as u32,
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue