diff --git a/terra/contracts/wormhole/src/contract.rs b/terra/contracts/wormhole/src/contract.rs index 700e4faf..39821477 100644 --- a/terra/contracts/wormhole/src/contract.rs +++ b/terra/contracts/wormhole/src/contract.rs @@ -132,17 +132,16 @@ fn handle_submit_vaa( if vaa_archive_check(&deps.storage, &hash) { return ContractError::VaaAlreadyExecuted.std_err(); } - vaa_archive_add(&mut deps.storage, &hash)?; - + // Load and check guardian set let guardian_set = guardian_set_get(&deps.storage, vaa_guardian_set_index); let guardian_set: GuardianSetInfo = guardian_set.or(ContractError::InvalidGuardianSetIndex.std_err())?; - if guardian_set.expiration_time == 0 || guardian_set.expiration_time > env.block.time { + if guardian_set.expiration_time == 0 || guardian_set.expiration_time < env.block.time { return ContractError::GuardianSetExpired.std_err(); } - if len_signers < (guardian_set.addresses.len() / 4) * 3 + 1 { + if len_signers < guardian_set.quorum() { return ContractError::NoQuorum.std_err(); } @@ -176,7 +175,7 @@ fn handle_submit_vaa( let action = data.get_u8(body_offset + 4); let payload = &data[body_offset + 5..]; - match action { + let result = match action { 0x01 => { if vaa_guardian_set_index != state.guardian_set_index { return ContractError::NotCurrentGuardianSet.std_err(); @@ -185,7 +184,13 @@ fn handle_submit_vaa( } 0x10 => vaa_transfer(deps, env, payload), _ => ContractError::InvalidVAAAction.std_err(), + }; + + if result.is_ok() { + vaa_archive_add(&mut deps.storage, &hash)?; } + + result } /// Handle wrapped asset registration messages @@ -554,6 +559,7 @@ fn keys_equal(a: &VerifyKey, b: &GuardianAddress) -> bool { #[cfg(test)] mod tests { + use std::time::{UNIX_EPOCH, SystemTime}; use super::*; use crate::state::GuardianSetInfo; use cosmwasm_std::testing::{mock_dependencies, mock_env}; @@ -577,7 +583,7 @@ mod tests { let init_msg = InitMsg { initial_guardian_set: GuardianSetInfo { addresses: guardians.clone(), - expiration_time: 100, + expiration_time: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 1000, }, guardian_set_expirity: 50, wrapped_asset_code_id: 999, diff --git a/terra/contracts/wormhole/src/state.rs b/terra/contracts/wormhole/src/state.rs index 6a096b61..6e8c584f 100644 --- a/terra/contracts/wormhole/src/state.rs +++ b/terra/contracts/wormhole/src/state.rs @@ -55,6 +55,12 @@ pub struct GuardianSetInfo { pub expiration_time: u64, // Guardian set expiration time } +impl GuardianSetInfo { + pub fn quorum(&self) -> usize { + ((self.addresses.len() * 10 / 3) * 2) / 10 + 1 + } +} + // Wormhole contract generic information #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct WormholeInfo { @@ -108,3 +114,39 @@ pub fn wrapped_asset_address(storage: &mut S) -> Bucket> pub fn wrapped_asset_address_read(storage: &S) -> ReadonlyBucket> { bucket_read(WRAPPED_ASSET_ADDRESS_KEY, storage) } + +#[cfg(test)] +mod tests { + use super::*; + + fn build_guardian_set(length: usize) -> GuardianSetInfo { + let mut addresses: Vec = Vec::with_capacity(length); + for _ in 0..length { + addresses.push(GuardianAddress{bytes: vec![].into()}); + } + + GuardianSetInfo { + addresses, + expiration_time: 0, + } + } + + #[test] + fn quardian_set_quorum() { + assert_eq!(build_guardian_set(1).quorum(), 1); + assert_eq!(build_guardian_set(2).quorum(), 2); + assert_eq!(build_guardian_set(3).quorum(), 3); + assert_eq!(build_guardian_set(4).quorum(), 3); + assert_eq!(build_guardian_set(5).quorum(), 4); + assert_eq!(build_guardian_set(6).quorum(), 5); + assert_eq!(build_guardian_set(7).quorum(), 5); + assert_eq!(build_guardian_set(8).quorum(), 6); + assert_eq!(build_guardian_set(9).quorum(), 7); + assert_eq!(build_guardian_set(10).quorum(), 7); + assert_eq!(build_guardian_set(11).quorum(), 8); + assert_eq!(build_guardian_set(12).quorum(), 9); + assert_eq!(build_guardian_set(20).quorum(), 14); + assert_eq!(build_guardian_set(25).quorum(), 17); + assert_eq!(build_guardian_set(100).quorum(), 67); + } +} \ No newline at end of file diff --git a/terra/tools/prepare-wormhole.ts b/terra/tools/prepare-wormhole.ts index 81afd5b4..1e306a80 100644 --- a/terra/tools/prepare-wormhole.ts +++ b/terra/tools/prepare-wormhole.ts @@ -15,7 +15,7 @@ async function script() { addresses: [ { bytes: Buffer.from('beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe', 'hex').toString('base64') } ], - expiration_time: 1000 * 60 * 60 + expiration_time: Math.floor(Date.now() / 1000) + 1000 * 60 * 60 }, guardian_set_expirity: 0, wrapped_asset_code_id: wrapped_code_id,