This commit is contained in:
Sergio Chouhy 2025-10-02 08:39:53 -03:00
parent a00773d5aa
commit 86f61e5ac9
16 changed files with 47 additions and 216 deletions

View File

@ -8,11 +8,11 @@
"port": 3040,
"initial_accounts": [
{
"addr": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
"addr": "0eee24287296ba55278f1e5403be014754866366388730303c2889be17ada065",
"balance": 10000
},
{
"addr": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766",
"addr": "9e3d8e654d440e95293aa2dceceb137899a59535e952f747068e7a0ee30965f2",
"balance": 20000
}
],
@ -154,4 +154,4 @@
37,
37
]
}
}

View File

@ -9,7 +9,7 @@
"initial_accounts": [
{
"Public": {
"address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
"address": "0eee24287296ba55278f1e5403be014754866366388730303c2889be17ada065",
"pub_sign_key": [
1,
1,
@ -48,7 +48,7 @@
},
{
"Public": {
"address": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766",
"address": "9e3d8e654d440e95293aa2dceceb137899a59535e952f747068e7a0ee30965f2",
"pub_sign_key": [
2,
2,

View File

@ -26,8 +26,8 @@ struct Args {
test_name: String,
}
pub const ACC_SENDER: &str = "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f";
pub const ACC_RECEIVER: &str = "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766";
pub const ACC_SENDER: &str = "0eee24287296ba55278f1e5403be014754866366388730303c2889be17ada065";
pub const ACC_RECEIVER: &str = "9e3d8e654d440e95293aa2dceceb137899a59535e952f747068e7a0ee30965f2";
pub const ACC_SENDER_PRIVATE: &str =
"9cb6b0035320266e430eac9d96745769e7efcf30d2b9cc21ff000b3f873dc2a8";
@ -389,10 +389,7 @@ pub async fn test_success_token_program() {
// Bytes from 1 to 33 represent the id of the token this account is associated with.
// In this example, this is a token account of the newly created token, so it is expected
// to be equal to the address of the token definition account.
assert_eq!(
&supply_acc.data[1..33],
nssa::AccountId::from(&definition_addr).to_bytes()
);
assert_eq!(&supply_acc.data[1..33], definition_addr.to_bytes());
assert_eq!(
u128::from_le_bytes(supply_acc.data[33..].try_into().unwrap()),
37
@ -419,10 +416,7 @@ pub async fn test_success_token_program() {
// First byte equal to 1 means it's a token holding account
assert_eq!(supply_acc.data[0], 1);
// Bytes from 1 to 33 represent the id of the token this account is associated with.
assert_eq!(
&supply_acc.data[1..33],
nssa::AccountId::from(&definition_addr).to_bytes()
);
assert_eq!(&supply_acc.data[1..33], definition_addr.to_bytes());
assert_eq!(
u128::from_le_bytes(supply_acc.data[33..].try_into().unwrap()),
30
@ -440,10 +434,7 @@ pub async fn test_success_token_program() {
// First byte equal to 1 means it's a token holding account
assert_eq!(recipient_acc.data[0], 1);
// Bytes from 1 to 33 represent the id of the token this account is associated with.
assert_eq!(
&recipient_acc.data[1..33],
nssa::AccountId::from(&definition_addr).to_bytes()
);
assert_eq!(&recipient_acc.data[1..33], definition_addr.to_bytes());
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
7

View File

@ -60,17 +60,6 @@ impl Display for Address {
}
}
#[cfg(feature = "host")]
impl From<&Address> for AccountId {
fn from(address: &Address) -> Self {
const PUBLIC_ACCOUNT_ID_PREFIX: &[u8; 32] = b"/NSSA/v0.1/AccountId/Public/\x00\x00\x00\x00";
let mut bytes = PUBLIC_ACCOUNT_ID_PREFIX.to_vec();
bytes.extend_from_slice(&address.value);
AccountId::new(Impl::hash_bytes(&bytes).as_bytes().try_into().unwrap())
}
}
#[cfg(test)]
mod tests {
use crate::account::AccountId;
@ -104,17 +93,4 @@ mod tests {
let result = hex_str.parse::<Address>().unwrap_err();
assert!(matches!(result, AddressError::InvalidLength(_)));
}
#[test]
fn test_account_id_from_address() {
let address: Address = "37".repeat(32).parse().unwrap();
let expected_account_id = AccountId::new([
93, 223, 66, 245, 78, 230, 157, 188, 110, 161, 134, 255, 137, 177, 220, 88, 37, 44,
243, 91, 236, 4, 36, 147, 185, 112, 21, 49, 234, 4, 107, 185,
]);
let account_id = AccountId::from(&address);
assert_eq!(account_id, expected_account_id);
}
}

View File

@ -1,143 +0,0 @@
use std::{fmt::Display, str::FromStr};
use nssa_core::account::AccountId;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use crate::signature::PublicKey;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct Address {
value: [u8; 32],
}
impl Address {
pub fn new(value: [u8; 32]) -> Self {
Self { value }
}
pub fn value(&self) -> &[u8; 32] {
&self.value
}
}
impl AsRef<[u8]> for Address {
fn as_ref(&self) -> &[u8] {
&self.value
}
}
impl From<&PublicKey> for Address {
fn from(value: &PublicKey) -> Self {
// TODO: Check specs
Self::new(*value.value())
}
}
#[derive(Debug, thiserror::Error)]
pub enum AddressError {
#[error("invalid hex")]
InvalidHex(#[from] hex::FromHexError),
#[error("invalid length: expected 32 bytes, got {0}")]
InvalidLength(usize),
}
impl FromStr for Address {
type Err = AddressError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let bytes = hex::decode(s)?;
if bytes.len() != 32 {
return Err(AddressError::InvalidLength(bytes.len()));
}
let mut value = [0u8; 32];
value.copy_from_slice(&bytes);
Ok(Address { value })
}
}
impl Display for Address {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", hex::encode(self.value))
}
}
impl Serialize for Address {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let hex_string = self.to_string();
hex_string.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Address {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let hex_string = String::deserialize(deserializer)?;
Address::from_str(&hex_string).map_err(serde::de::Error::custom)
}
}
impl From<&Address> for AccountId {
fn from(address: &Address) -> Self {
const PUBLIC_ACCOUNT_ID_PREFIX: &[u8; 32] = b"/NSSA/v0.1/AccountId/Public/\x00\x00\x00\x00";
let mut hasher = Sha256::new();
hasher.update(PUBLIC_ACCOUNT_ID_PREFIX);
hasher.update(address.value);
AccountId::new(hasher.finalize().into())
}
}
#[cfg(test)]
mod tests {
use nssa_core::account::AccountId;
use crate::{Address, address::AddressError};
#[test]
fn parse_valid_address() {
let hex_str = "00".repeat(32); // 64 hex chars = 32 bytes
let addr: Address = hex_str.parse().unwrap();
assert_eq!(addr.value, [0u8; 32]);
}
#[test]
fn parse_invalid_hex() {
let hex_str = "zz".repeat(32); // invalid hex chars
let result = hex_str.parse::<Address>().unwrap_err();
assert!(matches!(result, AddressError::InvalidHex(_)));
}
#[test]
fn parse_wrong_length_short() {
let hex_str = "00".repeat(31); // 62 chars = 31 bytes
let result = hex_str.parse::<Address>().unwrap_err();
assert!(matches!(result, AddressError::InvalidLength(_)));
}
#[test]
fn parse_wrong_length_long() {
let hex_str = "00".repeat(33); // 66 chars = 33 bytes
let result = hex_str.parse::<Address>().unwrap_err();
assert!(matches!(result, AddressError::InvalidLength(_)));
}
#[test]
fn test_account_id_from_address() {
let address: Address = "37".repeat(32).parse().unwrap();
let expected_account_id = AccountId::new([
93, 223, 66, 245, 78, 230, 157, 188, 110, 161, 134, 255, 137, 177, 220, 88, 37, 44,
243, 91, 236, 4, 36, 147, 185, 112, 21, 49, 234, 4, 107, 185,
]);
let account_id = AccountId::from(&address);
assert_eq!(account_id, expected_account_id);
}
}

View File

@ -1,4 +1,3 @@
// pub mod address;
pub mod encoding;
pub mod error;
mod merkle_tree;

View File

@ -94,7 +94,7 @@ impl PrivacyPreservingTransaction {
AccountWithMetadata::new(
state.get_account_by_address(address),
signer_addresses.contains(address),
address,
*address,
)
})
.collect();

View File

@ -1,7 +1,9 @@
use std::collections::{HashMap, HashSet};
use nssa_core::{
account::{Account, AccountWithMetadata}, address::Address, program::validate_execution
account::{Account, AccountWithMetadata},
address::Address,
program::validate_execution,
};
use sha2::{Digest, digest::FixedOutput};
@ -93,7 +95,7 @@ impl PublicTransaction {
AccountWithMetadata::new(
state.get_account_by_address(address),
signer_addresses.contains(address),
address,
*address,
)
})
.collect();
@ -185,12 +187,12 @@ pub mod tests {
let tx = transaction_for_tests();
let expected_signer_addresses = vec![
Address::new([
27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30,
24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143,
14, 238, 36, 40, 114, 150, 186, 85, 39, 143, 30, 84, 3, 190, 1, 71, 84, 134, 99,
102, 56, 135, 48, 48, 60, 40, 137, 190, 23, 173, 160, 101,
]),
Address::new([
77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217,
234, 216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102,
158, 61, 142, 101, 77, 68, 14, 149, 41, 58, 162, 220, 236, 235, 19, 120, 153, 165,
149, 53, 233, 82, 247, 71, 6, 142, 122, 14, 227, 9, 101, 242,
]),
];
let signer_addresses = tx.signer_addresses();

View File

@ -2,6 +2,8 @@ use nssa_core::address::Address;
use crate::{PrivateKey, error::NssaError};
use sha2::{Digest, Sha256};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PublicKey([u8; 32]);
@ -30,9 +32,13 @@ impl PublicKey {
}
impl From<&PublicKey> for Address {
fn from(value: &PublicKey) -> Self {
// TODO: Check specs
Self::new(*value.value())
fn from(key: &PublicKey) -> Self {
const PUBLIC_ACCOUNT_ID_PREFIX: &[u8; 32] = b"/NSSA/v0.1/AccountId/Public/\x00\x00\x00\x00";
let mut hasher = Sha256::new();
hasher.update(PUBLIC_ACCOUNT_ID_PREFIX);
hasher.update(key.0);
Self::new(hasher.finalize().into())
}
}

View File

@ -808,7 +808,7 @@ pub mod tests {
let sender = AccountWithMetadata::new(
state.get_account_by_address(&sender_keys.address()),
true,
&sender_keys.address(),
sender_keys.address(),
);
let sender_nonce = sender.account.nonce;
@ -913,7 +913,7 @@ pub mod tests {
let recipient_pre = AccountWithMetadata::new(
state.get_account_by_address(recipient_address),
false,
recipient_address,
*recipient_address,
);
let esk = [3; 32];

View File

@ -231,13 +231,13 @@ mod tests {
fn setup_sequencer_config() -> SequencerConfig {
let acc1_addr = vec![
27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24,
52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143,
14, 238, 36, 40, 114, 150, 186, 85, 39, 143, 30, 84, 3, 190, 1, 71, 84, 134, 99, 102,
56, 135, 48, 48, 60, 40, 137, 190, 23, 173, 160, 101,
];
let acc2_addr = vec![
77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217, 234,
216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102,
158, 61, 142, 101, 77, 68, 14, 149, 41, 58, 162, 220, 236, 235, 19, 120, 153, 165, 149,
53, 233, 82, 247, 71, 6, 142, 122, 14, 227, 9, 101, 242,
];
let initial_acc1 = AccountInitialData {

View File

@ -308,13 +308,13 @@ mod tests {
let tempdir = tempdir().unwrap();
let home = tempdir.path().to_path_buf();
let acc1_addr = vec![
27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24,
52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143,
14, 238, 36, 40, 114, 150, 186, 85, 39, 143, 30, 84, 3, 190, 1, 71, 84, 134, 99, 102,
56, 135, 48, 48, 60, 40, 137, 190, 23, 173, 160, 101,
];
let acc2_addr = vec![
77, 75, 108, 209, 54, 16, 50, 202, 155, 210, 174, 185, 217, 0, 170, 77, 69, 217, 234,
216, 10, 201, 66, 51, 116, 196, 81, 167, 37, 77, 7, 102,
158, 61, 142, 101, 77, 68, 14, 149, 41, 58, 162, 220, 236, 235, 19, 120, 153, 165, 149,
53, 233, 82, 247, 71, 6, 142, 122, 14, 227, 9, 101, 242,
];
let initial_acc1 = AccountInitialData {
@ -352,8 +352,8 @@ mod tests {
let balance_to_move = 10;
let tx = common::test_utils::create_transaction_native_token_transfer(
[
27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30,
24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143,
14, 238, 36, 40, 114, 150, 186, 85, 39, 143, 30, 84, 3, 190, 1, 71, 84, 134, 99,
102, 56, 135, 48, 48, 60, 40, 137, 190, 23, 173, 160, 101,
],
0,
[2; 32],

View File

@ -8,11 +8,11 @@
"port": 3040,
"initial_accounts": [
{
"addr": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
"addr": "0eee24287296ba55278f1e5403be014754866366388730303c2889be17ada065",
"balance": 10000
},
{
"addr": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766",
"addr": "9e3d8e654d440e95293aa2dceceb137899a59535e952f747068e7a0ee30965f2",
"balance": 20000
}
]

View File

@ -71,14 +71,14 @@ mod tests {
fn create_initial_accounts() -> Vec<InitialAccountData> {
let initial_acc1 = serde_json::from_str(r#"{
"Public": {
"address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
"address": "0eee24287296ba55278f1e5403be014754866366388730303c2889be17ada065",
"pub_sign_key": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
}
}"#).unwrap();
let initial_acc2 = serde_json::from_str(r#"{
"Public": {
"address": "4d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766",
"address": "9e3d8e654d440e95293aa2dceceb137899a59535e952f747068e7a0ee30965f2",
"pub_sign_key": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
}
}"#).unwrap();

View File

@ -38,7 +38,7 @@ impl WalletCore {
let recipient_pre = nssa_core::account::AccountWithMetadata {
account: to_acc.clone(),
is_authorized: false,
account_id: (&to).into(),
account_id: to,
};
//Move into different function

View File

@ -34,7 +34,7 @@ impl WalletCore {
let sender_pre = nssa_core::account::AccountWithMetadata {
account: from_acc.clone(),
is_authorized: true,
account_id: (&from).into(),
account_id: from,
};
let recipient_pre = nssa_core::account::AccountWithMetadata {
account: to_acc.clone(),
@ -117,7 +117,7 @@ impl WalletCore {
let sender_pre = nssa_core::account::AccountWithMetadata {
account: from_acc.clone(),
is_authorized: true,
account_id: (&from).into(),
account_id: from,
};
let recipient_pre = nssa_core::account::AccountWithMetadata {