#![allow(warnings)] use borsh::BorshSerialize; use byteorder::{ BigEndian, WriteBytesExt, }; use hex_literal::hex; use secp256k1::{ Message, PublicKey, SecretKey, }; use sha3::Digest; use solana_client::rpc_client::RpcClient; use solana_program::{ borsh::try_from_slice_unchecked, hash, instruction::{ AccountMeta, Instruction, }, program_pack::Pack, pubkey::Pubkey, system_instruction::{ self, create_account, }, system_program, sysvar, }; use solana_sdk::{ signature::{ read_keypair_file, Keypair, Signer, }, transaction::Transaction, }; use std::{ convert::TryInto, io::{ Cursor, Write, }, time::{ Duration, SystemTime, }, }; use bridge::{ accounts::GuardianSetDerivationData, instruction, types::{ BridgeConfig, GovernancePayloadGuardianSetChange, GovernancePayloadSetMessageFee, GovernancePayloadTransferFees, PostedMessage, PostedMessageData, SequenceTracker, SignatureSet, }, Initialize, PostVAAData, SerializePayload, Signature, }; use primitive_types::U256; mod common; const GOV_KEY: [u8; 64] = [ 240, 133, 120, 113, 30, 67, 38, 184, 197, 72, 234, 99, 241, 21, 58, 225, 41, 157, 171, 44, 196, 163, 134, 236, 92, 148, 110, 68, 127, 114, 177, 0, 173, 253, 199, 9, 242, 142, 201, 174, 108, 197, 18, 102, 115, 0, 31, 205, 127, 188, 191, 56, 171, 228, 20, 247, 149, 170, 141, 231, 147, 88, 97, 199, ]; struct Context { public: Vec<[u8; 20]>, secret: Vec, } #[test] fn run_integration_tests() { let (ref payer, ref client, ref program) = common::setup(); let (public_keys, secret_keys) = common::generate_keys(6); let mut context = Context { public: public_keys, secret: secret_keys, }; common::initialize(client, program, payer, &*context.public.clone()); // Tests are currently unhygienic as It's difficult to wrap `solana-test-validator` within the // integration tests so for now we work around it by simply chain-calling our tests. test_bridge_messages(&mut context); test_guardian_set_change(&mut context); test_guardian_set_change_fails(&mut context); test_set_fees(&mut context); test_transfer_fees(&mut context); } fn test_bridge_messages(context: &mut Context) { let (ref payer, ref client, ref program) = common::setup(); // Data/Nonce used for emitting a message we want to prove exists. let nonce = 12397; let message = b"Prove Me".to_vec(); let emitter = Keypair::new(); // Post the message, publishing the data for guardian consumption. let message_key = common::post_message( client, program, payer, &emitter, nonce, message.clone(), 10_000, false, ) .unwrap(); // Emulate Guardian behaviour, verifying the data and publishing signatures/VAA. let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0); common::verify_signatures(client, program, payer, body, body_hash, &context.secret, 0).unwrap(); common::post_vaa(client, program, payer, vaa).unwrap(); } fn test_guardian_set_change(context: &mut Context) { // Initialize a wormhole bridge on Solana to test with. let (ref payer, ref client, ref program) = common::setup(); // Data/Nonce used for emitting a message we want to prove exists. let nonce = 12397; let message = b"Prove Me".to_vec(); let emitter = Keypair::from_bytes(&GOV_KEY).unwrap(); // Post the message, publishing the data for guardian consumption. let message_key = common::post_message( client, program, payer, &emitter, nonce, message.clone(), 10_000, false, ) .unwrap(); // Emulate Guardian behaviour, verifying the data and publishing signatures/VAA. let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0); common::verify_signatures(client, program, payer, body, body_hash, &context.secret, 0).unwrap(); common::post_vaa(client, program, payer, vaa).unwrap(); // Upgrade the guardian set with a new set of guardians. let (new_public_keys, new_secret_keys) = common::generate_keys(6); let nonce = 12398; let message = GovernancePayloadGuardianSetChange { new_guardian_set_index: 1, new_guardian_set: new_public_keys.clone(), } .try_to_vec() .unwrap(); let message_key = common::post_message( client, program, payer, &emitter, nonce, message.clone(), 10_000, false, ) .unwrap(); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 0); common::verify_signatures(client, program, payer, body, body_hash, &context.secret, 0).unwrap(); common::post_vaa(client, program, payer, vaa).unwrap(); common::upgrade_guardian_set( client, program, payer, message_key, emitter.pubkey(), 0, 1, 1, ) .unwrap(); // Submit the message a second time with a new nonce. let nonce = 12399; let message_key = common::post_message( client, program, payer, &emitter, nonce, message.clone(), 10_000, false, ) .unwrap(); context.public = new_public_keys; context.secret = new_secret_keys; // Emulate Guardian behaviour, verifying the data and publishing signatures/VAA. let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1); common::verify_signatures(client, program, payer, body, body_hash, &context.secret, 1).unwrap(); common::post_vaa(client, program, payer, vaa).unwrap(); } fn test_guardian_set_change_fails(context: &mut Context) { // Initialize a wormhole bridge on Solana to test with. let (ref payer, ref client, ref program) = common::setup(); let emitter = Keypair::new(); // Upgrade the guardian set with a new set of guardians. let (new_public_keys, new_secret_keys) = common::generate_keys(6); let nonce = 12400; let message = GovernancePayloadGuardianSetChange { new_guardian_set_index: 2, new_guardian_set: new_public_keys.clone(), } .try_to_vec() .unwrap(); let message_key = common::post_message( client, program, payer, &emitter, nonce, message.clone(), 10_000, false, ) .unwrap(); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1); assert!(common::upgrade_guardian_set( client, program, payer, message_key, emitter.pubkey(), 1, 2, 0, ) .is_err()); } fn test_set_fees(context: &mut Context) { // Initialize a wormhole bridge on Solana to test with. let (ref payer, ref client, ref program) = common::setup(); let emitter = Keypair::from_bytes(&GOV_KEY).unwrap(); let nonce = 12401; let message = GovernancePayloadSetMessageFee { fee: U256::from(100), persisted_fee: U256::from(100), } .try_to_vec() .unwrap(); let message_key = common::post_message( client, program, payer, &emitter, nonce, message.clone(), 10_000, false, ) .unwrap(); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1); common::verify_signatures(client, program, payer, body, body_hash, &context.secret, 1).unwrap(); common::post_vaa(client, program, payer, vaa).unwrap(); common::set_fees(client, program, payer, message_key, emitter.pubkey(), 3).unwrap(); // Check that posting a new message fails with too small a fee. let emitter = Keypair::new(); let nonce = 12402; let message = b"Fail to Pay".to_vec(); assert!(common::post_message( client, program, payer, &emitter, nonce, message.clone(), 50, false ) .is_err()); // And succeeds with the new. let emitter = Keypair::new(); let nonce = 12402; let message = b"Fail to Pay".to_vec(); common::post_message( client, program, payer, &emitter, nonce, message.clone(), 100, false, ) .unwrap(); } fn test_transfer_fees(context: &mut Context) { // Initialize a wormhole bridge on Solana to test with. let (ref payer, ref client, ref program) = common::setup(); let emitter = Keypair::from_bytes(&GOV_KEY).unwrap(); let nonce = 12401; let message = GovernancePayloadTransferFees { amount: 100.into(), to: payer.pubkey().to_bytes(), } .try_to_vec() .unwrap(); let message_key = common::post_message( client, program, payer, &emitter, nonce, message.clone(), 10_000, false, ) .unwrap(); let (vaa, body, body_hash) = common::generate_vaa(&emitter, message.clone(), nonce, 1); common::verify_signatures(client, program, payer, body, body_hash, &context.secret, 1).unwrap(); common::post_vaa(client, program, payer, vaa).unwrap(); common::transfer_fees( client, program, payer, message_key, emitter.pubkey(), 4, payer.pubkey(), ) .unwrap(); }