Skip to content
Open
Show file tree
Hide file tree
Changes from all 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