Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions core/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,7 @@ where

#[inline]
fn verify_intent_nonce(&self, nonce: Nonce, intent_deadline: Deadline) -> Result<()> {
let Some(nonce) = VersionedNonce::maybe_from(nonce) else {
return Ok(());
};

match nonce {
match nonce.try_into()? {
VersionedNonce::V1(SaltedNonce {
salt,
nonce: ExpirableNonce { deadline, .. },
Expand Down
23 changes: 15 additions & 8 deletions core/src/nonce/versioned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use hex_literal::hex;
use near_sdk::borsh::{BorshDeserialize, BorshSerialize};

use crate::{
Nonce,
DefuseError, Nonce, Result,
nonce::{expirable::ExpirableNonce, salted::SaltedNonce},
};

Expand All @@ -22,10 +22,17 @@ pub enum VersionedNonce {
impl VersionedNonce {
/// Magic prefixes (first 4 bytes of `sha256(<versioned_nonce>)`) used to mark versioned nonces:
pub const VERSIONED_MAGIC_PREFIX: [u8; 4] = hex!("5628f6c6");
}

impl TryFrom<Nonce> for VersionedNonce {
type Error = DefuseError;

fn try_from(nonce: Nonce) -> Result<Self> {
let mut versioned = nonce
.strip_prefix(&Self::VERSIONED_MAGIC_PREFIX)
.ok_or(DefuseError::InvalidNonce)?;

pub fn maybe_from(n: Nonce) -> Option<Self> {
let mut versioned = n.strip_prefix(&Self::VERSIONED_MAGIC_PREFIX)?;
Self::deserialize_reader(&mut versioned).ok()
Self::deserialize_reader(&mut versioned).map_err(|_| DefuseError::InvalidNonce)
}
}

Expand Down Expand Up @@ -57,8 +64,8 @@ mod tests {
let mut u = Unstructured::new(&random_bytes);
let legacy_nonce: Nonce = u.arbitrary().unwrap();

let expected = VersionedNonce::maybe_from(legacy_nonce);
assert!(expected.is_none());
let expected = VersionedNonce::try_from(legacy_nonce);
assert!(matches!(expected, Err(DefuseError::InvalidNonce)));

let mut u = Unstructured::new(&random_bytes);
let nonce_bytes: [u8; 15] = u.arbitrary().unwrap();
Expand All @@ -68,7 +75,7 @@ mod tests {
let salted = SaltedNonce::new(salt, ExpirableNonce::new(now, nonce_bytes));
let nonce: Nonce = VersionedNonce::V1(salted.clone()).into();

let exp = VersionedNonce::maybe_from(nonce);
assert_eq!(exp, Some(VersionedNonce::V1(salted)));
let exp = VersionedNonce::try_from(nonce).unwrap();
assert_eq!(exp, VersionedNonce::V1(salted));
}
}
3 changes: 2 additions & 1 deletion defuse/src/contract/garbage_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ impl GarbageCollector for Contract {
impl Contract {
#[inline]
fn is_nonce_cleanable(&self, nonce: Nonce) -> bool {
let Some(versioned_nonce) = VersionedNonce::maybe_from(nonce) else {
// legacy nonces can not be cleaned up
let Ok(versioned_nonce) = VersionedNonce::try_from(nonce) else {
return false;
};

Expand Down
32 changes: 3 additions & 29 deletions tests/src/tests/defuse/accounts/nonces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use arbitrary::{Arbitrary, Unstructured};
use chrono::{TimeDelta, Utc};
use defuse::{
contract::Role,
core::{Deadline, Nonce, Salt, intents::DefuseIntents},
core::{Deadline, Salt, intents::DefuseIntents},
};
use itertools::Itertools;

Expand Down Expand Up @@ -39,7 +39,7 @@ async fn test_commit_nonces(random_bytes: Vec<u8>, #[notrace] mut rng: impl Rng)

let user = env.create_user().await;

// legacy nonce
// can't commit legacy nonce
{
let deadline = Deadline::MAX;
let legacy_nonce = rng.random();
Expand All @@ -56,14 +56,7 @@ async fn test_commit_nonces(random_bytes: Vec<u8>, #[notrace] mut rng: impl Rng)
)],
)
.await
.unwrap();

assert!(
env.defuse
.is_nonce_used(user.id(), &legacy_nonce)
.await
.unwrap(),
);
.assert_err_contains("invalid nonce");
}

// invalid salt
Expand Down Expand Up @@ -238,7 +231,6 @@ async fn test_cleanup_nonces(#[notrace] mut rng: impl Rng) {
.unwrap(),
);

let legacy_nonce: Nonce = rng.random();
let expirable_nonce = create_random_salted_nonce(current_salt, deadline, &mut rng);
let long_term_expirable_nonce =
create_random_salted_nonce(current_salt, long_term_deadline, &mut rng);
Expand All @@ -249,16 +241,6 @@ async fn test_cleanup_nonces(#[notrace] mut rng: impl Rng) {
.execute_intents(
env.defuse.id(),
[
user.sign_defuse_message(
SigningStandard::arbitrary(&mut Unstructured::new(
&rng.random::<[u8; 1]>(),
))
.unwrap(),
env.defuse.id(),
legacy_nonce,
deadline,
DefuseIntents { intents: [].into() },
),
user.sign_defuse_message(
SigningStandard::arbitrary(&mut Unstructured::new(
&rng.random::<[u8; 1]>(),
Expand Down Expand Up @@ -326,21 +308,13 @@ async fn test_cleanup_nonces(#[notrace] mut rng: impl Rng) {
env.defuse.id(),
vec![
(user.id().clone(), vec![expirable_nonce]),
(user.id().clone(), vec![legacy_nonce]),
(user.id().clone(), vec![long_term_expirable_nonce]),
(unknown_user, vec![expirable_nonce]),
],
)
.await
.unwrap();

assert!(
env.defuse
.is_nonce_used(user.id(), &legacy_nonce)
.await
.unwrap(),
);

assert!(
env.defuse
.is_nonce_used(user.id(), &long_term_expirable_nonce)
Expand Down
84 changes: 0 additions & 84 deletions tests/src/tests/defuse/intents/legacy_nonce.rs

This file was deleted.

Loading
Loading