Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(starknet-core): initialize EthAddress from bytes #506

Merged
merged 7 commits into from
Dec 9, 2023
Merged
Changes from 4 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
86 changes: 85 additions & 1 deletion starknet-core/src/types/eth_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,18 @@ mod errors {
#[derive(Debug)]
pub struct FromFieldElementError;

#[derive(Debug)]
pub struct FromBytesSliceError(pub alloc::string::String);

glihm marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(feature = "std")]
impl std::error::Error for FromHexError {}

#[cfg(feature = "std")]
impl std::error::Error for FromFieldElementError {}

#[cfg(feature = "std")]
impl std::error::Error for FromBytesSliceError {}

impl Display for FromHexError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self {
Expand All @@ -55,8 +61,14 @@ mod errors {
write!(f, "FieldElement value out of range")
}
}

impl Display for FromBytesSliceError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "invalid slice for ETH address: {}", self.0)
}
}
}
pub use errors::{FromFieldElementError, FromHexError};
pub use errors::{FromBytesSliceError, FromFieldElementError, FromHexError};

impl EthAddress {
pub fn from_hex(hex: &str) -> Result<Self, FromHexError> {
Expand Down Expand Up @@ -156,3 +168,75 @@ impl From<EthAddress> for FieldElement {
FieldElement::from_byte_slice_be(&value.inner).unwrap()
}
}

impl TryFrom<&[u8]> for EthAddress {
type Error = FromBytesSliceError;

fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
if value.len() != 20 {
return Err(FromBytesSliceError(format!(
"expected 20 bytes found {}",
value.len()
)));
}

Ok(Self {
inner: value
.try_into()
.map_err(|e| FromBytesSliceError(format!("can't convert slice to array: {}", e)))?,
})
glihm marked this conversation as resolved.
Show resolved Hide resolved
}
}

impl From<[u8; 20]> for EthAddress {
fn from(value: [u8; 20]) -> Self {
Self { inner: value }
}
}

#[cfg(test)]
mod tests {
use super::EthAddress;

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
fn test_eth_address_from_bytes_array() {
// address: e7f1725e7734ce288f8367e1bb143e90bb3f0512
let address_bytes: [u8; 20] = [
231, 241, 114, 94, 119, 52, 206, 40, 143, 131, 103, 225, 187, 20, 62, 144, 187, 63, 5,
18,
];

let eth_address: EthAddress = address_bytes.into();
assert_eq!(
EthAddress::from_hex("0xe7f1725e7734ce288f8367e1bb143e90bb3f0512").unwrap(),
eth_address
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
fn test_eth_address_from_slice() {
// address: e7f1725e7734ce288f8367e1bb143e90bb3f0512, inside a buffer with more data.
let buffer: Vec<u8> = vec![
0, 1, 2, 231, 241, 114, 94, 119, 52, 206, 40, 143, 131, 103, 225, 187, 20, 62, 144,
187, 63, 5, 18, 11, 22, 33,
];

let eth_address: EthAddress = (&buffer[3..23])
.try_into()
.expect("failed to get eth_address from slice");
assert_eq!(
EthAddress::from_hex("0xe7f1725e7734ce288f8367e1bb143e90bb3f0512").unwrap(),
eth_address
);
}

#[test]
#[should_panic(expected = "fail: FromBytesSliceError(\"expected 20 bytes found 4\")")]
fn test_eth_address_from_slice_invalid_slice() {
let buffer: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7];

EthAddress::try_from(&buffer[0..4]).expect("fail");
}
}
Loading