cosmwasm: add prefix handling for observations verification

This commit is contained in:
A5 Pickle 2023-01-31 18:21:19 +00:00 committed by Evan Gray
parent 1ca872018b
commit ce9c70682c
6 changed files with 34 additions and 14 deletions

View File

@ -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<Response, AnyError> {
// 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::<Empty>(
&WormholeQuery::VerifySignature {
data: observations.clone(),
data: prepended.into(),
guardian_set_index,
signature,
}

View File

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

View File

@ -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<P: Serialize>(wh: &fake::WormholeKeeper, body: Body<P>) ->
(v, data)
}
pub fn sign_observations(wh: &fake::WormholeKeeper, observations: &[u8]) -> Vec<Signature> {
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 {

View File

@ -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] {

View File

@ -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()

View File

@ -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<SubmitObservationResponse> =
@ -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::<Vec<SubmitObservationResponse>>(&resp.data.unwrap()).unwrap();