-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
20e16ab
commit e357f56
Showing
53 changed files
with
2,770 additions
and
324 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,198 @@ | ||
use radix_engine_common::crypto::{blake2b_256_hash, Hash}; | ||
use crate::prelude::*; | ||
use radix_engine::types::IsHash; | ||
use radix_engine_common::crypto::{ | ||
blake2b_256_hash, Hash as ScryptoHash, IsHash as ScryptoIsHash, | ||
}; | ||
|
||
/// Represents a 32-byte hash digest. | ||
/// | ||
/// Made UniFFI convertible via bytes (BagOfBytes). | ||
#[derive( | ||
Clone, | ||
Debug, | ||
PartialEq, | ||
Eq, | ||
std::hash::Hash, | ||
derive_more::Display, | ||
derive_more::FromStr, | ||
)] | ||
pub struct HashSecretMagic(ScryptoHash); | ||
|
||
impl From<HashSecretMagic> for Exactly32Bytes { | ||
fn from(value: HashSecretMagic) -> Self { | ||
Exactly32Bytes::from_bytes(value.0.as_bytes()) | ||
} | ||
} | ||
|
||
impl crate::UniffiCustomTypeConverter for HashSecretMagic { | ||
type Builtin = BagOfBytes; | ||
|
||
fn into_custom(val: Self::Builtin) -> uniffi::Result<Self> { | ||
Exactly32Bytes::try_from(val.bytes) | ||
.map(|e| e.bytes()) | ||
.map(|b: [u8; 32]| HashSecretMagic(ScryptoHash::from_bytes(b))) | ||
.map_err(|e| e.into()) | ||
} | ||
|
||
fn from_custom(obj: Self) -> Self::Builtin { | ||
BagOfBytes::from(obj.0.into_bytes().as_slice()) | ||
} | ||
} | ||
|
||
/// Represents a 32-byte hash digest. | ||
/// | ||
/// Made UniFFI convertible via HashSecretMagic, | ||
/// exposed in Swift/Kotlin as its own struct/data class, with | ||
/// hidden secret magic. | ||
#[derive( | ||
Clone, | ||
Debug, | ||
PartialEq, | ||
Eq, | ||
std::hash::Hash, | ||
derive_more::Display, | ||
derive_more::FromStr, | ||
uniffi::Record, | ||
)] | ||
pub struct Hash { | ||
pub(crate) secret_magic: HashSecretMagic, | ||
} | ||
|
||
impl From<Hash> for Exactly32Bytes { | ||
fn from(value: Hash) -> Self { | ||
value.secret_magic.into() | ||
} | ||
} | ||
|
||
impl AsRef<ScryptoHash> for Hash { | ||
fn as_ref(&self) -> &ScryptoHash { | ||
&self.secret_magic.0 | ||
} | ||
} | ||
|
||
impl AsRef<[u8]> for Hash { | ||
fn as_ref(&self) -> &[u8] { | ||
self.secret_magic.0.as_ref() | ||
} | ||
} | ||
|
||
impl ScryptoIsHash for Hash {} | ||
|
||
impl Hash { | ||
pub fn bytes(&self) -> Vec<u8> { | ||
self.secret_magic.0.clone().to_vec() | ||
} | ||
} | ||
|
||
impl From<ScryptoHash> for Hash { | ||
fn from(value: ScryptoHash) -> Self { | ||
Self { | ||
secret_magic: HashSecretMagic(value), | ||
} | ||
} | ||
} | ||
impl From<Hash> for ScryptoHash { | ||
fn from(value: Hash) -> Self { | ||
value.secret_magic.0 | ||
} | ||
} | ||
|
||
/// Computes the hash digest of a message. | ||
pub fn hash_of<T: AsRef<[u8]>>(data: T) -> Hash { | ||
blake2b_256_hash(data) | ||
blake2b_256_hash(data).into() | ||
} | ||
|
||
impl HasSampleValues for Hash { | ||
fn sample() -> Self { | ||
// "Hello Radix".as_bytes() | ||
"48f1bd08444b5e713db9e14caac2faae71836786ac94d645b00679728202a935" | ||
.parse::<Self>() | ||
.unwrap() | ||
} | ||
|
||
fn sample_other() -> Self { | ||
// "Radix... just imagine".as_bytes() | ||
"196ca16b4a35c1c3df18e20cb199c99d129cec6ea62eb03a29fde16db897f4b1" | ||
.parse::<Self>() | ||
.unwrap() | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::prelude::*; | ||
|
||
#[allow(clippy::upper_case_acronyms)] | ||
type SUT = Hash; | ||
|
||
#[test] | ||
fn equality() { | ||
assert_eq!(SUT::sample(), SUT::sample()); | ||
assert_eq!(SUT::sample_other(), SUT::sample_other()); | ||
} | ||
|
||
#[test] | ||
fn inequality() { | ||
assert_ne!(SUT::sample(), SUT::sample_other()); | ||
} | ||
|
||
#[test] | ||
fn test_hash() { | ||
assert_eq!( | ||
hash_of("Hello Radix".as_bytes()).to_string(), | ||
"48f1bd08444b5e713db9e14caac2faae71836786ac94d645b00679728202a935" | ||
); | ||
} | ||
|
||
#[test] | ||
fn to_string() { | ||
assert_eq!( | ||
SUT::sample_other().to_string(), | ||
"196ca16b4a35c1c3df18e20cb199c99d129cec6ea62eb03a29fde16db897f4b1" | ||
); | ||
} | ||
|
||
#[test] | ||
fn from_str() { | ||
assert_eq!( | ||
"48f1bd08444b5e713db9e14caac2faae71836786ac94d645b00679728202a935" | ||
.parse::<SUT>() | ||
.unwrap(), | ||
hash_of("Hello Radix".as_bytes()) | ||
); | ||
} | ||
|
||
#[test] | ||
fn manual_perform_uniffi_conversion_successful() { | ||
let sut = SUT::sample().secret_magic; | ||
let builtin = BagOfBytes::from_hex( | ||
"48f1bd08444b5e713db9e14caac2faae71836786ac94d645b00679728202a935", | ||
) | ||
.unwrap(); | ||
|
||
let ffi_side = | ||
<HashSecretMagic as crate::UniffiCustomTypeConverter>::from_custom( | ||
sut.clone(), | ||
); | ||
|
||
assert_eq!(ffi_side.to_hex(), builtin.to_hex()); | ||
|
||
let from_ffi_side = | ||
<HashSecretMagic as crate::UniffiCustomTypeConverter>::into_custom( | ||
ffi_side, | ||
) | ||
.unwrap(); | ||
|
||
assert_eq!(sut, from_ffi_side); | ||
} | ||
|
||
#[test] | ||
fn manual_perform_uniffi_conversion_fail() { | ||
assert!( | ||
<HashSecretMagic as crate::UniffiCustomTypeConverter>::into_custom( | ||
BagOfBytes::from_hex("deadbeef").unwrap(), | ||
) | ||
.is_err() | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.