From ce9c70682cc04146c0b501967bb5ec878bf86c9b Mon Sep 17 00:00:00 2001 From: A5 Pickle Date: Tue, 31 Jan 2023 18:21:19 +0000 Subject: [PATCH] cosmwasm: add prefix handling for observations verification --- .../contracts/global-accountant/src/contract.rs | 12 ++++++++++-- cosmwasm/contracts/global-accountant/src/msg.rs | 2 ++ .../global-accountant/tests/helpers/mod.rs | 14 +++++++++++++- .../tests/missing_observations.rs | 10 ++++------ .../global-accountant/tests/submit_observations.rs | 6 +++--- .../global-accountant/tests/submit_vaas.rs | 4 ++-- 6 files changed, 34 insertions(+), 14 deletions(-) diff --git a/cosmwasm/contracts/global-accountant/src/contract.rs b/cosmwasm/contracts/global-accountant/src/contract.rs index e91e05c47..e1098d228 100644 --- a/cosmwasm/contracts/global-accountant/src/contract.rs +++ b/cosmwasm/contracts/global-accountant/src/contract.rs @@ -31,7 +31,7 @@ use crate::{ AllTransfersResponse, BatchTransferStatusResponse, ChainRegistrationResponse, ExecuteMsg, MigrateMsg, MissingObservation, MissingObservationsResponse, Observation, ObservationError, ObservationStatus, QueryMsg, SubmitObservationResponse, TransferDetails, TransferStatus, - Upgrade, + Upgrade, SUBMITTED_OBSERVATIONS_PREFIX, }, state::{Data, PendingTransfer, CHAIN_REGISTRATIONS, DIGESTS, PENDING_TRANSFERS}, }; @@ -95,10 +95,18 @@ fn submit_observations( guardian_set_index: u32, signature: Signature, ) -> Result { + // We need to prepend an observation prefix to `observations`, which is the + // same prefix used by the guardians to sign these observations. This + // prefix specifies this type as global accountant observations. + let mut prepended = + Vec::with_capacity(SUBMITTED_OBSERVATIONS_PREFIX.len() + observations.len()); + prepended.extend_from_slice(SUBMITTED_OBSERVATIONS_PREFIX); + prepended.extend_from_slice(observations.as_slice()); + deps.querier .query::( &WormholeQuery::VerifySignature { - data: observations.clone(), + data: prepended.into(), guardian_set_index, signature, } diff --git a/cosmwasm/contracts/global-accountant/src/msg.rs b/cosmwasm/contracts/global-accountant/src/msg.rs index e0733b82e..a88754894 100644 --- a/cosmwasm/contracts/global-accountant/src/msg.rs +++ b/cosmwasm/contracts/global-accountant/src/msg.rs @@ -9,6 +9,8 @@ use wormhole::{ use crate::state::{self, PendingTransfer}; +pub const SUBMITTED_OBSERVATIONS_PREFIX: &[u8; 35] = b"acct_sub_obsfig_000000000000000000|"; + #[cw_serde] #[derive(Default)] pub struct Observation { diff --git a/cosmwasm/contracts/global-accountant/tests/helpers/mod.rs b/cosmwasm/contracts/global-accountant/tests/helpers/mod.rs index 4a1ac6c46..9993d1ab9 100644 --- a/cosmwasm/contracts/global-accountant/tests/helpers/mod.rs +++ b/cosmwasm/contracts/global-accountant/tests/helpers/mod.rs @@ -13,7 +13,7 @@ use global_accountant::{ msg::{ AllAccountsResponse, AllModificationsResponse, AllPendingTransfersResponse, AllTransfersResponse, BatchTransferStatusResponse, ChainRegistrationResponse, ExecuteMsg, - MissingObservationsResponse, QueryMsg, TransferStatus, + MissingObservationsResponse, QueryMsg, TransferStatus, SUBMITTED_OBSERVATIONS_PREFIX, }, state, }; @@ -306,6 +306,18 @@ pub fn sign_vaa_body(wh: &fake::WormholeKeeper, body: Body

) -> (v, data) } +pub fn sign_observations(wh: &fake::WormholeKeeper, observations: &[u8]) -> Vec { + let mut prepended = + Vec::with_capacity(SUBMITTED_OBSERVATIONS_PREFIX.len() + observations.len()); + prepended.extend_from_slice(SUBMITTED_OBSERVATIONS_PREFIX); + prepended.extend_from_slice(observations); + + let mut signatures = wh.sign(&prepended); + signatures.sort_by_key(|s| s.index); + + signatures +} + pub fn register_emitters(wh: &fake::WormholeKeeper, contract: &mut Contract, count: usize) { for i in 0..count { let body = Body { diff --git a/cosmwasm/contracts/global-accountant/tests/missing_observations.rs b/cosmwasm/contracts/global-accountant/tests/missing_observations.rs index 8cc860775..fcd175ad5 100644 --- a/cosmwasm/contracts/global-accountant/tests/missing_observations.rs +++ b/cosmwasm/contracts/global-accountant/tests/missing_observations.rs @@ -45,7 +45,7 @@ fn missing_observations() { let o = create_observation(); let digest = o.digest().unwrap(); let data = to_binary(&[o.clone()]).unwrap(); - let signatures = wh.sign(&data); + let signatures = sign_observations(&wh, &data); // Don't submit enough signatures for the transfer to reach quorum. for s in &signatures[..quorum - 1] { @@ -96,8 +96,7 @@ fn different_observations() { let first = create_observation(); let first_data = to_binary(&[first.clone()]).unwrap(); - let mut first_signatures = wh.sign(&first_data); - first_signatures.sort_by_key(|s| s.index); + let first_signatures = sign_observations(&wh, &first_data); // Don't submit enough signatures for the transfer to reach quorum. for s in &first_signatures[..quorum - 1] { @@ -124,8 +123,7 @@ fn different_observations() { .into(); second.payload = serde_wormhole::to_vec(&msg).map(From::from).unwrap(); let second_data = to_binary(&[second.clone()]).unwrap(); - let mut second_signatures = wh.sign(&second_data); - second_signatures.sort_by_key(|s| s.index); + let second_signatures = sign_observations(&wh, &second_data); // Submit a different set of signatures for the second observation. for s in second_signatures.iter().rev().take(quorum - 1) { @@ -170,7 +168,7 @@ fn guardian_set_change() { let o = create_observation(); let data = to_binary(&[o.clone()]).unwrap(); - let signatures = wh.sign(&data); + let signatures = sign_observations(&wh, &data); // Don't submit enough signatures for the transfer to reach quorum. for s in &signatures[..quorum - 1] { diff --git a/cosmwasm/contracts/global-accountant/tests/submit_observations.rs b/cosmwasm/contracts/global-accountant/tests/submit_observations.rs index 7004cb62a..0c5cf3f5d 100644 --- a/cosmwasm/contracts/global-accountant/tests/submit_observations.rs +++ b/cosmwasm/contracts/global-accountant/tests/submit_observations.rs @@ -54,7 +54,7 @@ fn batch() { let index = wh.guardian_set_index(); let obs = to_binary(&observations).unwrap(); - let signatures = wh.sign(&obs); + let signatures = sign_observations(&wh, &obs); let quorum = wh .calculate_quorum(index, contract.app().block_info().height) .unwrap() as usize; @@ -160,7 +160,7 @@ fn duplicates() { let index = wh.guardian_set_index(); let obs = to_binary(&observations).unwrap(); - let signatures = wh.sign(&obs); + let signatures = sign_observations(&wh, &obs); let quorum = wh .calculate_quorum(index, contract.app().block_info().height) .unwrap() as usize; @@ -256,7 +256,7 @@ fn transfer_tokens( }; let obs = to_binary(&vec![o.clone()]).unwrap(); - let signatures = wh.sign(&obs); + let signatures = sign_observations(wh, &obs); let responses = signatures .into_iter() diff --git a/cosmwasm/contracts/global-accountant/tests/submit_vaas.rs b/cosmwasm/contracts/global-accountant/tests/submit_vaas.rs index 2898263c7..10e1e2bd4 100644 --- a/cosmwasm/contracts/global-accountant/tests/submit_vaas.rs +++ b/cosmwasm/contracts/global-accountant/tests/submit_vaas.rs @@ -292,7 +292,7 @@ fn reobservation() { let obs = to_binary(&vec![o]).unwrap(); let index = wh.guardian_set_index(); - let signatures = wh.sign(&obs); + let signatures = sign_observations(&wh, &obs); for s in signatures { let resp = contract.submit_observations(obs.clone(), index, s).unwrap(); let mut responses: Vec = @@ -330,7 +330,7 @@ fn digest_mismatch() { let key = transfer::Key::new(o.emitter_chain, o.emitter_address.into(), o.sequence); let obs = to_binary(&vec![o]).unwrap(); let index = wh.guardian_set_index(); - let signatures = wh.sign(&obs); + let signatures = sign_observations(&wh, &obs); for s in signatures { let resp = contract.submit_observations(obs.clone(), index, s).unwrap(); let responses = from_binary::>(&resp.data.unwrap()).unwrap();