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 FeeCollector<'a> = Derive<Info<'a>, "fee_collector">;
|
||||||
pub type Bridge<'a, const State: AccountState> = Derive<Data<'a, BridgeData, { State }>, "Bridge">;
|
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 type GuardianSet<'b, const State: AccountState> = Data<'b, types::GuardianSetData, { State }>;
|
||||||
|
|
||||||
pub struct GuardianSetDerivationData {
|
pub struct GuardianSetDerivationData {
|
||||||
|
|
|
@ -85,7 +85,7 @@ pub fn post_message(
|
||||||
emitter: Pubkey,
|
emitter: Pubkey,
|
||||||
nonce: u32,
|
nonce: u32,
|
||||||
payload: Vec<u8>,
|
payload: Vec<u8>,
|
||||||
) -> solitaire::Result<Instruction> {
|
) -> solitaire::Result<(Pubkey, Instruction)> {
|
||||||
let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
|
let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
|
||||||
let fee_collector = FeeCollector::<'_>::key(None, &program_id);
|
let fee_collector = FeeCollector::<'_>::key(None, &program_id);
|
||||||
let sequence = Sequence::<'_>::key(
|
let sequence = Sequence::<'_>::key(
|
||||||
|
@ -104,7 +104,7 @@ pub fn post_message(
|
||||||
&program_id,
|
&program_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Instruction {
|
Ok((message, Instruction {
|
||||||
program_id,
|
program_id,
|
||||||
|
|
||||||
accounts: vec![
|
accounts: vec![
|
||||||
|
@ -124,7 +124,7 @@ pub fn post_message(
|
||||||
payload: payload.clone(),
|
payload: payload.clone(),
|
||||||
})
|
})
|
||||||
.try_to_vec()?,
|
.try_to_vec()?,
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_signatures(
|
pub fn verify_signatures(
|
||||||
|
@ -255,7 +255,7 @@ pub fn upgrade_guardian_set(
|
||||||
&ClaimDerivationData {
|
&ClaimDerivationData {
|
||||||
emitter_address: emitter.to_bytes(),
|
emitter_address: emitter.to_bytes(),
|
||||||
emitter_chain: 1,
|
emitter_chain: 1,
|
||||||
sequence: 0,
|
sequence: 1,
|
||||||
},
|
},
|
||||||
&program_id,
|
&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(
|
execute(
|
||||||
client,
|
client,
|
||||||
payer,
|
payer,
|
||||||
&[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,
|
program: &Pubkey,
|
||||||
payer: &Keypair,
|
payer: &Keypair,
|
||||||
emitter: &Keypair,
|
emitter: &Keypair,
|
||||||
sequence: u64,
|
nonce: u32,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) {
|
) -> Pubkey {
|
||||||
// Transfer money into the fee collector as it needs a balance/must exist.
|
// Transfer money into the fee collector as it needs a balance/must exist.
|
||||||
let fee_collector = FeeCollector::<'_>::key(None, program);
|
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(
|
execute(
|
||||||
client,
|
client,
|
||||||
payer,
|
payer,
|
||||||
&[payer, emitter],
|
&[payer, emitter],
|
||||||
&[instructions::post_message(
|
&[instruction],
|
||||||
*program,
|
|
||||||
payer.pubkey(),
|
|
||||||
emitter.pubkey(),
|
|
||||||
0,
|
|
||||||
data,
|
|
||||||
)
|
|
||||||
.unwrap()],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
message_key
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_signatures(
|
pub fn verify_signatures(
|
||||||
|
@ -188,6 +198,7 @@ mod helpers {
|
||||||
program: &Pubkey,
|
program: &Pubkey,
|
||||||
payer: &Keypair,
|
payer: &Keypair,
|
||||||
vaa: PostVAAData,
|
vaa: PostVAAData,
|
||||||
|
guardian_set_index: u32,
|
||||||
) {
|
) {
|
||||||
execute(
|
execute(
|
||||||
client,
|
client,
|
||||||
|
@ -196,8 +207,90 @@ mod helpers {
|
||||||
&[instructions::post_vaa(
|
&[instructions::post_vaa(
|
||||||
*program,
|
*program,
|
||||||
payer.pubkey(),
|
payer.pubkey(),
|
||||||
|
*emitter,
|
||||||
|
guardian_set_index,
|
||||||
vaa,
|
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)]
|
#![allow(warnings)]
|
||||||
|
|
||||||
use borsh::BorshSerialize;
|
use borsh::BorshSerialize;
|
||||||
use secp256k1::{Message};
|
use secp256k1::Message;
|
||||||
|
|
||||||
use solana_client::rpc_client::RpcClient;
|
use solana_client::rpc_client::RpcClient;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
|
@ -34,10 +34,12 @@ use byteorder::{
|
||||||
WriteBytesExt,
|
WriteBytesExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::convert::TryInto;
|
use std::{
|
||||||
use std::io::{
|
convert::TryInto,
|
||||||
Cursor,
|
io::{
|
||||||
Write,
|
Cursor,
|
||||||
|
Write,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::time::{
|
use std::time::{
|
||||||
|
@ -52,6 +54,7 @@ use bridge::{
|
||||||
instruction,
|
instruction,
|
||||||
types::{
|
types::{
|
||||||
BridgeConfig,
|
BridgeConfig,
|
||||||
|
GovernancePayloadGuardianSetChange,
|
||||||
PostedMessage,
|
PostedMessage,
|
||||||
PostedMessageData,
|
PostedMessageData,
|
||||||
SequenceTracker,
|
SequenceTracker,
|
||||||
|
@ -60,62 +63,76 @@ use bridge::{
|
||||||
Initialize,
|
Initialize,
|
||||||
PostVAAData,
|
PostVAAData,
|
||||||
Signature,
|
Signature,
|
||||||
|
SerializePayload,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
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]
|
#[test]
|
||||||
fn test_bridge_messages() {
|
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();
|
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();
|
let emitter = Keypair::new();
|
||||||
|
|
||||||
// Data we want to verify exists.
|
// Initialize the Bridge.
|
||||||
let data = vec![];
|
common::initialize(client, program, payer, &[INITIAL_PUBLIC]);
|
||||||
let message = create_message(data.clone());
|
|
||||||
|
|
||||||
// Initialize the Bridge
|
// Post the message, publishing the data for guardian consumption.
|
||||||
common::initialize(
|
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,
|
client,
|
||||||
program,
|
program,
|
||||||
payer,
|
payer,
|
||||||
|
message_key,
|
||||||
|
emitter.pubkey(),
|
||||||
|
0,
|
||||||
|
1,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Post a Message
|
fn update_guardian_set(
|
||||||
common::post_message(
|
index: u32,
|
||||||
client,
|
keys: &[[u8; 20]],
|
||||||
program,
|
) -> Vec<u8> {
|
||||||
payer,
|
let mut v = Cursor::new(Vec::new());
|
||||||
&emitter,
|
v.write_u32::<BigEndian>(index).unwrap();
|
||||||
message.0.sequence,
|
v.write_u8(keys.len() as u8).unwrap();
|
||||||
message.0.payload,
|
keys.iter().map(|key| v.write(key));
|
||||||
);
|
v.into_inner()
|
||||||
|
|
||||||
// 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?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A utility function for emulating what the guardians should be doing, I.E, detecting a message
|
/// 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(
|
fn guardian_sign_round(
|
||||||
emitter: &Keypair,
|
emitter: &Keypair,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
|
nonce: u32,
|
||||||
) -> (PostVAAData, Vec<u8>, [u8; 32], secp256k1::SecretKey) {
|
) -> (PostVAAData, Vec<u8>, [u8; 32], secp256k1::SecretKey) {
|
||||||
let mut vaa = PostVAAData {
|
let mut vaa = PostVAAData {
|
||||||
version: 0,
|
version: 0,
|
||||||
guardian_set_index: 0,
|
guardian_set_index: 0,
|
||||||
|
|
||||||
// Body part
|
// Body part
|
||||||
nonce: 0,
|
|
||||||
emitter_chain: 1,
|
emitter_chain: 1,
|
||||||
emitter_address: emitter.pubkey().to_bytes(),
|
emitter_address: emitter.pubkey().to_bytes(),
|
||||||
sequence: 0,
|
sequence: 0,
|
||||||
|
@ -138,6 +155,7 @@ fn guardian_sign_round(
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_secs() as u32,
|
.as_secs() as u32,
|
||||||
|
nonce,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hash data, the thing we wish to actually sign.
|
// 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_u32::<BigEndian>(vaa.nonce).unwrap();
|
||||||
v.write_u16::<BigEndian>(vaa.emitter_chain).unwrap();
|
v.write_u16::<BigEndian>(vaa.emitter_chain).unwrap();
|
||||||
v.write(&vaa.emitter_address).unwrap();
|
v.write(&vaa.emitter_address).unwrap();
|
||||||
|
v.write_u64::<BigEndian>(vaa.sequence).unwrap();
|
||||||
v.write(&vaa.payload).unwrap();
|
v.write(&vaa.payload).unwrap();
|
||||||
v.into_inner()
|
v.into_inner()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Public Key: 0x1d72877eb2d898738afe94c6101152ede0435de9
|
// Public Key: 0x1d72877eb2d898738afe94c6101152ede0435de9
|
||||||
let secret_key = secp256k1::SecretKey::parse(&[
|
let secret_key = secp256k1::SecretKey::parse(&INITIAL_SECRET).unwrap();
|
||||||
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 public_key = secp256k1::PublicKey::from_secret_key(&secret_key);
|
let public_key = secp256k1::PublicKey::from_secret_key(&secret_key);
|
||||||
println!("{}", hex::encode(&public_key.serialize()));
|
println!("{}", hex::encode(&public_key.serialize()));
|
||||||
|
|
||||||
|
@ -170,10 +184,7 @@ fn guardian_sign_round(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sign the body hash of the VAA.
|
// Sign the body hash of the VAA.
|
||||||
let sig = secp256k1::sign(
|
let sig = secp256k1::sign(&Message::parse(&body_hash), &secret_key);
|
||||||
&Message::parse(&body_hash),
|
|
||||||
&secret_key,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Insert signature into VAA.
|
// Insert signature into VAA.
|
||||||
let signature = sig.0.serialize();
|
let signature = sig.0.serialize();
|
||||||
|
@ -186,21 +197,3 @@ fn guardian_sign_round(
|
||||||
|
|
||||||
(vaa, body, body_hash, secret_key)
|
(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