Fixed guardian set expiration and quorum logic, tests updated

This commit is contained in:
Yuriy Savchenko 2020-12-17 15:47:40 +02:00 committed by Leopold Schabel
parent 82fd4293e2
commit eaee9c0638
3 changed files with 55 additions and 7 deletions

View File

@ -132,17 +132,16 @@ fn handle_submit_vaa<S: Storage, A: Api, Q: Querier>(
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<S: Storage, A: Api, Q: Querier>(
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<S: Storage, A: Api, Q: Querier>(
}
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,

View File

@ -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<S: Storage>(storage: &mut S) -> Bucket<S, Vec<u8>>
pub fn wrapped_asset_address_read<S: Storage>(storage: &S) -> ReadonlyBucket<S, Vec<u8>> {
bucket_read(WRAPPED_ASSET_ADDRESS_KEY, storage)
}
#[cfg(test)]
mod tests {
use super::*;
fn build_guardian_set(length: usize) -> GuardianSetInfo {
let mut addresses: Vec<GuardianAddress> = 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);
}
}

View File

@ -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,