From 0dbc9f9da4b62f5fe0447fdb377de5629165a335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Delabrouille?= Date: Wed, 20 Dec 2023 04:42:50 +0100 Subject: [PATCH 1/3] feat: impl From for StarkFelt --- .gitignore | 1 + src/core.rs | 9 +++++++++ src/hash.rs | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/.gitignore b/.gitignore index 8e1ad418..d68be5fc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /logs /target /Cargo.lock +*.DS_Store diff --git a/src/core.rs b/src/core.rs index 20b37f13..561a3f54 100644 --- a/src/core.rs +++ b/src/core.rs @@ -264,6 +264,15 @@ impl TryFrom for EthAddress { } } +impl From for StarkFelt { + fn from(value: EthAddress) -> Self { + let mut bytes = [0u8; 32]; + // Padding H160 with zeros to 32 bytes (big endian) + bytes[12..32].copy_from_slice(value.0.as_bytes()); + StarkFelt::new_unchecked(bytes) + } +} + impl TryFrom> for EthAddress { type Error = StarknetApiError; fn try_from(val: PrefixedBytesAsHex<20_usize>) -> Result { diff --git a/src/hash.rs b/src/hash.rs index acbb1838..cad3196e 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -69,6 +69,10 @@ impl StarkFelt { Err(StarknetApiError::OutOfRange { string: hex_str_from_bytes::<32, true>(bytes) }) } + pub const fn new_unchecked(bytes: [u8; 32]) -> StarkFelt { + Self(bytes) + } + /// [StarkFelt] constant that's equal to 0. pub const ZERO: Self = { Self::from_u128(0_u128) }; From b45912e7e645f84dab3eddd8e957dce0e7fb3b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Delabrouille?= Date: Mon, 8 Jan 2024 15:49:48 +0100 Subject: [PATCH 2/3] add safety comment on new_unchecked --- src/hash.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/hash.rs b/src/hash.rs index cad3196e..68f0a438 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -69,6 +69,22 @@ impl StarkFelt { Err(StarknetApiError::OutOfRange { string: hex_str_from_bytes::<32, true>(bytes) }) } + /// Returns a new *unchecked* [`StarkFelt`] + /// + /// # Safety + /// + /// The internal representation of the `StarkFelt` type is 256 bits. + /// The `StarkFelt` type max value is 2^251 + 17 ∗ 21^92 + 1, which is less than `U256::MAX`. + /// The `StarkFelt::new` method make sure that you can't initialize a `StarkFelt` greater than + /// it's specification maximum. This method does not not. It's your responsability make sure + /// it's okay to call this method. + /// + /// # Usage + /// + /// Most of the time you should use `new` instead, but it comes handy for a few case: + /// - creating instances of `StarkFelt` at compile time + /// - implementing `From for StarkFelt` on types that have a smaller binary representation + /// than `StarkFelt` pub const fn new_unchecked(bytes: [u8; 32]) -> StarkFelt { Self(bytes) } From a69acc867b28d53f3811d19db46a763e0f3c9dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Delabrouille?= Date: Tue, 9 Jan 2024 17:13:58 +0100 Subject: [PATCH 3/3] improve docstrings --- src/hash.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/hash.rs b/src/hash.rs index 68f0a438..e9ab99d2 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -73,17 +73,15 @@ impl StarkFelt { /// /// # Safety /// - /// The internal representation of the `StarkFelt` type is 256 bits. - /// The `StarkFelt` type max value is 2^251 + 17 ∗ 21^92 + 1, which is less than `U256::MAX`. - /// The `StarkFelt::new` method make sure that you can't initialize a `StarkFelt` greater than - /// it's specification maximum. This method does not not. It's your responsability make sure - /// it's okay to call this method. + /// To avoid undefined behavior, refer to [`StarkFelt`] struct's docstring + /// for the required constraints on the `bytes` argument, or use [`StarkFelt::new`] instead of + /// this method. /// /// # Usage /// - /// Most of the time you should use `new` instead, but it comes handy for a few case: + /// Most of the time you should use `new` instead, but it comes in handy for a few cases: /// - creating instances of `StarkFelt` at compile time - /// - implementing `From for StarkFelt` on types that have a smaller binary representation + /// - implementing `From for StarkFelt` for types that have a smaller binary representation /// than `StarkFelt` pub const fn new_unchecked(bytes: [u8; 32]) -> StarkFelt { Self(bytes)