diff --git a/bin/evd/src/main.rs b/bin/evd/src/main.rs index a2d5b75..a5c6c3e 100644 --- a/bin/evd/src/main.rs +++ b/bin/evd/src/main.rs @@ -655,7 +655,7 @@ fn run_custom_genesis( (addr.into_array(), acc.balance) }) .collect(); - let minter = AccountId::new(genesis_config.minter_id); + let minter = AccountId::from_u64(genesis_config.minter_id); let metadata = genesis_config.token.to_metadata(); let gas_config = default_gas_config(); diff --git a/bin/testapp/src/genesis_config.rs b/bin/testapp/src/genesis_config.rs index eedd964..cc3a318 100644 --- a/bin/testapp/src/genesis_config.rs +++ b/bin/testapp/src/genesis_config.rs @@ -12,7 +12,7 @@ pub type FundedAccount = ([u8; 20], u128); #[derive(Deserialize)] pub struct EvdGenesisConfig { pub token: TokenConfig, - pub minter_id: u128, + pub minter_id: u64, pub accounts: Vec, } diff --git a/bin/testapp/src/lib.rs b/bin/testapp/src/lib.rs index 23a5179..b7b03c8 100644 --- a/bin/testapp/src/lib.rs +++ b/bin/testapp/src/lib.rs @@ -17,7 +17,7 @@ use evolve_token::account::{Token, TokenRef}; use evolve_tx_eth::TxContext; use evolve_tx_eth::{register_runtime_contract_account, resolve_or_create_eoa_account}; -pub const MINTER: AccountId = AccountId::new(100_002); +pub const MINTER: AccountId = AccountId::from_u64(100002); pub struct MempoolNoOpPostTx; @@ -42,7 +42,7 @@ pub type MempoolStf = Stf< MempoolNoOpPostTx, >; -pub const PLACEHOLDER_ACCOUNT: AccountId = AccountId::new(u128::MAX); +pub const PLACEHOLDER_ACCOUNT: AccountId = AccountId::from_u64(u64::MAX); /// Default gas configuration for the test application. pub fn default_gas_config() -> StorageGasConfig { diff --git a/bin/testapp/src/main.rs b/bin/testapp/src/main.rs index 0bec09d..925dc2e 100644 --- a/bin/testapp/src/main.rs +++ b/bin/testapp/src/main.rs @@ -218,7 +218,7 @@ fn run_custom_genesis( return Err("custom genesis requires at least one account".into()); } - let minter = AccountId::new(config.minter_id); + let minter = AccountId::from_u64(config.minter_id); let metadata = config.token.to_metadata(); let genesis_block = BlockContext::new(0, 0); diff --git a/bin/testapp/tests/mempool_e2e.rs b/bin/testapp/tests/mempool_e2e.rs index 22fb06f..4d1d37e 100644 --- a/bin/testapp/tests/mempool_e2e.rs +++ b/bin/testapp/tests/mempool_e2e.rs @@ -270,7 +270,7 @@ fn setup_genesis( let init_storage = AsyncMockStorage::new(); let gas_config = default_gas_config(); - let stf = build_mempool_stf(gas_config.clone(), AccountId::new(0)); + let stf = build_mempool_stf(gas_config.clone(), AccountId::from_u64(0)); let (genesis_state, genesis_accounts) = do_eth_genesis( &stf, diff --git a/bin/txload/src/main.rs b/bin/txload/src/main.rs index 3ecaec6..89d10b8 100644 --- a/bin/txload/src/main.rs +++ b/bin/txload/src/main.rs @@ -567,7 +567,7 @@ mod tests { #[test] fn build_transfer_calldata_has_selector_and_borsh_args() { - let recipient = AccountId::new(42); + let recipient = AccountId::from_u64(42); let amount = 999_u128; let calldata = build_transfer_calldata(recipient, amount).unwrap(); diff --git a/crates/app/genesis/Cargo.toml b/crates/app/genesis/Cargo.toml index cdbc1e7..25ebd84 100644 --- a/crates/app/genesis/Cargo.toml +++ b/crates/app/genesis/Cargo.toml @@ -13,6 +13,7 @@ evolve_stf = { workspace = true } evolve_stf_traits = { workspace = true } borsh = { workspace = true } +hex = "0.4" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" diff --git a/crates/app/genesis/src/file.rs b/crates/app/genesis/src/file.rs index 34c6d66..d3a1262 100644 --- a/crates/app/genesis/src/file.rs +++ b/crates/app/genesis/src/file.rs @@ -40,7 +40,7 @@ pub struct GenesisTxJson { pub id: Option, /// Sender specification. - /// - "system": Use the system account (AccountId::new(0)) + /// - "system": Use the system account (AccountId::from_u64(0)) /// - "$ref": Reference a previously created account /// - number: Use a specific account ID #[serde(default = "default_sender")] @@ -64,7 +64,7 @@ fn default_sender() -> SenderSpec { } /// Specification for the sender of a genesis transaction. -#[derive(Debug, Clone, Default, Serialize)] +#[derive(Debug, Clone, Default, PartialEq, Eq)] pub enum SenderSpec { /// Use the system account #[default] @@ -72,7 +72,17 @@ pub enum SenderSpec { /// Reference a previously created account (starts with $) Reference(String), /// Use a specific account ID - AccountId(u128), + AccountId(AccountId), +} + +impl Serialize for SenderSpec { + fn serialize(&self, serializer: S) -> Result { + match self { + SenderSpec::System => serializer.serialize_str("system"), + SenderSpec::Reference(r) => serializer.serialize_str(r), + SenderSpec::AccountId(id) => serializer.serialize_str(&hex::encode(id.to_bytes())), + } + } } impl<'de> serde::Deserialize<'de> for SenderSpec { @@ -85,26 +95,47 @@ impl<'de> serde::Deserialize<'de> for SenderSpec { let value = serde_json::Value::deserialize(deserializer)?; match value { serde_json::Value::String(s) if s == "system" => Ok(SenderSpec::System), - serde_json::Value::String(s) => Ok(SenderSpec::Reference(s)), - serde_json::Value::Number(n) => n - .as_u64() - .map(|v| SenderSpec::AccountId(v as u128)) - .or_else(|| n.as_i64().map(|v| SenderSpec::AccountId(v as u128))) - .ok_or_else(|| D::Error::custom("invalid account ID number")), + serde_json::Value::String(s) if s.starts_with('$') => Ok(SenderSpec::Reference(s)), + serde_json::Value::String(s) => { + // Try hex-encoded account ID, fall back to reference + match hex::decode(s.trim_start_matches("0x")) { + Ok(b) if b.len() == 32 => { + let bytes: [u8; 32] = b.try_into().unwrap(); + Ok(SenderSpec::AccountId(AccountId::from_bytes(bytes))) + } + _ => Ok(SenderSpec::Reference(s)), + } + } + serde_json::Value::Number(n) => { + let v = n + .as_u64() + .ok_or_else(|| D::Error::custom("invalid account ID number"))?; + Ok(SenderSpec::AccountId(AccountId::from_u64(v))) + } _ => Err(D::Error::custom("expected string or number for sender")), } } } /// Specification for the recipient of a genesis transaction. -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum RecipientSpec { /// Use the runtime account for account creation Runtime, /// Reference a previously created account (starts with $) Reference(String), /// Use a specific account ID - AccountId(u128), + AccountId(AccountId), +} + +impl Serialize for RecipientSpec { + fn serialize(&self, serializer: S) -> Result { + match self { + RecipientSpec::Runtime => serializer.serialize_str("runtime"), + RecipientSpec::Reference(r) => serializer.serialize_str(r), + RecipientSpec::AccountId(id) => serializer.serialize_str(&hex::encode(id.to_bytes())), + } + } } impl<'de> serde::Deserialize<'de> for RecipientSpec { @@ -117,12 +148,23 @@ impl<'de> serde::Deserialize<'de> for RecipientSpec { let value = serde_json::Value::deserialize(deserializer)?; match value { serde_json::Value::String(s) if s == "runtime" => Ok(RecipientSpec::Runtime), - serde_json::Value::String(s) => Ok(RecipientSpec::Reference(s)), - serde_json::Value::Number(n) => n - .as_u64() - .map(|v| RecipientSpec::AccountId(v as u128)) - .or_else(|| n.as_i64().map(|v| RecipientSpec::AccountId(v as u128))) - .ok_or_else(|| D::Error::custom("invalid account ID number")), + serde_json::Value::String(s) if s.starts_with('$') => Ok(RecipientSpec::Reference(s)), + serde_json::Value::String(s) => { + // Try hex-encoded account ID, fall back to reference + match hex::decode(s.trim_start_matches("0x")) { + Ok(b) if b.len() == 32 => { + let bytes: [u8; 32] = b.try_into().unwrap(); + Ok(RecipientSpec::AccountId(AccountId::from_bytes(bytes))) + } + _ => Ok(RecipientSpec::Reference(s)), + } + } + serde_json::Value::Number(n) => { + let v = n + .as_u64() + .ok_or_else(|| D::Error::custom("invalid account ID number"))?; + Ok(RecipientSpec::AccountId(AccountId::from_u64(v))) + } _ => Err(D::Error::custom("expected string or number for recipient")), } } @@ -189,27 +231,31 @@ impl GenesisFile { let mut txs = Vec::with_capacity(self.transactions.len()); let mut id_to_account: HashMap = HashMap::new(); - let mut next_account_id: u128 = 1; // Start from 1, 0 is system + // Start from 1, 0 is system + let mut next_account_id = AccountId::from_u64(1); for (idx, tx_json) in self.transactions.iter().enumerate() { // Resolve sender - let sender = - match &tx_json.sender { - SenderSpec::System => SYSTEM_ACCOUNT_ID, - SenderSpec::Reference(r) if r.starts_with('$') => { - let ref_id = &r[1..]; - *id_to_account.get(ref_id).ok_or_else(|| { - GenesisError::InvalidReference(ref_id.to_string(), idx) - })? - } - SenderSpec::Reference(r) => { - // Treat as account ID string - AccountId::new(r.parse().map_err(|_| { + let sender = match &tx_json.sender { + SenderSpec::System => SYSTEM_ACCOUNT_ID, + SenderSpec::Reference(r) if r.starts_with('$') => { + let ref_id = &r[1..]; + *id_to_account + .get(ref_id) + .ok_or_else(|| GenesisError::InvalidReference(ref_id.to_string(), idx))? + } + SenderSpec::Reference(r) => { + // Treat as hex-encoded 32-byte account ID + let bytes = hex::decode(r.trim_start_matches("0x")) + .ok() + .and_then(|b| <[u8; 32]>::try_from(b).ok()) + .ok_or_else(|| { GenesisError::ParseError(format!("invalid sender: {}", r)) - })?) - } - SenderSpec::AccountId(id) => AccountId::new(*id), - }; + })?; + AccountId::from_bytes(bytes) + } + SenderSpec::AccountId(id) => *id, + }; // Resolve recipient let recipient = match &tx_json.recipient { @@ -221,12 +267,16 @@ impl GenesisFile { .ok_or_else(|| GenesisError::InvalidReference(ref_id.to_string(), idx))? } RecipientSpec::Reference(r) => { - // Treat as account ID string - AccountId::new(r.parse().map_err(|_| { - GenesisError::ParseError(format!("invalid recipient: {}", r)) - })?) + // Treat as hex-encoded 32-byte account ID + let bytes = hex::decode(r.trim_start_matches("0x")) + .ok() + .and_then(|b| <[u8; 32]>::try_from(b).ok()) + .ok_or_else(|| { + GenesisError::ParseError(format!("invalid recipient: {}", r)) + })?; + AccountId::from_bytes(bytes) } - RecipientSpec::AccountId(id) => AccountId::new(*id), + RecipientSpec::AccountId(id) => *id, }; // Resolve $references in the message payload @@ -244,9 +294,8 @@ impl GenesisFile { // If this transaction has an ID, assign it the next account ID // This assumes the transaction creates an account if let Some(id) = &tx_json.id { - let account_id = AccountId::new(next_account_id); - id_to_account.insert(id.clone(), account_id); - next_account_id += 1; + id_to_account.insert(id.clone(), next_account_id); + next_account_id = next_account_id.increase(); } txs.push(genesis_tx); @@ -267,8 +316,9 @@ fn resolve_references_in_value( let account_id = id_to_account .get(ref_id) .ok_or_else(|| GenesisError::InvalidReference(ref_id.to_string(), 0))?; - // Use string representation for u128 since JSON numbers are limited to i64/u64 - Ok(serde_json::Value::String(account_id.inner().to_string())) + Ok(serde_json::Value::String(hex::encode( + account_id.as_bytes(), + ))) } serde_json::Value::Array(arr) => { let resolved: Result, _> = arr @@ -360,7 +410,7 @@ mod tests { #[test] fn test_resolve_references_in_value() { let mut id_to_account = HashMap::new(); - id_to_account.insert("alice".to_string(), AccountId::new(1)); + id_to_account.insert("alice".to_string(), AccountId::from_u64(1)); let value = serde_json::json!({ "account": "$alice", @@ -372,10 +422,19 @@ mod tests { let resolved = resolve_references_in_value(&value, &id_to_account).unwrap(); - // Account IDs are resolved as strings (for u128 compatibility) - assert_eq!(resolved["account"], "1"); - assert_eq!(resolved["nested"]["ref"], "1"); - assert_eq!(resolved["list"][0], "1"); + // Account IDs are resolved as hex strings + assert_eq!( + resolved["account"], + "0000000000000000000000000000000000000000000000000000000000000001" + ); + assert_eq!( + resolved["nested"]["ref"], + "0000000000000000000000000000000000000000000000000000000000000001" + ); + assert_eq!( + resolved["list"][0], + "0000000000000000000000000000000000000000000000000000000000000001" + ); assert_eq!(resolved["list"][1], "literal"); } @@ -459,10 +518,10 @@ mod tests { ] }"#; let genesis = GenesisFile::parse(json).unwrap(); - assert!(matches!( + assert_eq!( genesis.transactions[0].sender, - SenderSpec::AccountId(123) - )); + SenderSpec::AccountId(AccountId::from_u64(123)) + ); } #[test] @@ -488,10 +547,10 @@ mod tests { ] }"#; let genesis = GenesisFile::parse(json).unwrap(); - assert!(matches!( + assert_eq!( genesis.transactions[0].recipient, - RecipientSpec::AccountId(456) - )); + RecipientSpec::AccountId(AccountId::from_u64(456)) + ); } #[test] @@ -577,8 +636,8 @@ mod tests { let txs = genesis.to_transactions(®istry).unwrap(); assert_eq!(txs.len(), 3); - assert_eq!(txs[2].sender, AccountId::new(1)); - assert_eq!(txs[2].recipient, AccountId::new(1)); + assert_eq!(txs[2].sender, AccountId::from_u64(1)); + assert_eq!(txs[2].recipient, AccountId::from_u64(1)); } #[test] diff --git a/crates/app/genesis/src/lib.rs b/crates/app/genesis/src/lib.rs index 6064607..1c670aa 100644 --- a/crates/app/genesis/src/lib.rs +++ b/crates/app/genesis/src/lib.rs @@ -38,7 +38,7 @@ use std::cell::RefCell; /// System account ID used as sender for genesis transactions. /// This is a sentinel value that indicates the transaction originates /// from the genesis process rather than a real account. -pub const SYSTEM_ACCOUNT_ID: AccountId = AccountId::new(0); +pub const SYSTEM_ACCOUNT_ID: AccountId = AccountId::from_u64(0); /// Applies genesis transactions to initialize chain state. /// @@ -441,7 +441,7 @@ mod tests { let mut codes = CodeStore::new(); codes.add_code(TestAccount); - let test_account_id = AccountId::new(100); + let test_account_id = AccountId::from_u64(100); let storage = setup_storage_with_account(test_account_id, "test_account"); let consensus_params = ConsensusParams::default(); @@ -467,8 +467,8 @@ mod tests { let mut codes = CodeStore::new(); codes.add_code(TestAccount); - let account1 = AccountId::new(100); - let account2 = AccountId::new(101); + let account1 = AccountId::from_u64(100); + let account2 = AccountId::from_u64(101); let mut storage = setup_storage_with_account(account1, "test_account"); let consensus_params = ConsensusParams::default(); // Add second account @@ -517,9 +517,9 @@ mod tests { codes.add_code(TestAccount); codes.add_code(FailingAccount); - let good_account = AccountId::new(100); - let bad_account = AccountId::new(101); - let after_bad = AccountId::new(102); + let good_account = AccountId::from_u64(100); + let bad_account = AccountId::from_u64(101); + let after_bad = AccountId::from_u64(102); let consensus_params = ConsensusParams::default(); let mut storage = setup_storage_with_account(good_account, "test_account"); @@ -585,7 +585,7 @@ mod tests { let mut codes = CodeStore::new(); codes.add_code(FailingAccount); - let bad_account = AccountId::new(100); + let bad_account = AccountId::from_u64(100); let storage = setup_storage_with_account(bad_account, "failing_account"); let consensus_params = ConsensusParams::default(); diff --git a/crates/app/genesis/src/types.rs b/crates/app/genesis/src/types.rs index 7dbff98..c143c16 100644 --- a/crates/app/genesis/src/types.rs +++ b/crates/app/genesis/src/types.rs @@ -47,7 +47,7 @@ pub struct GenesisTx { pub id: Option, /// The sender account ID. - /// For genesis, this is typically the system account (AccountId::new(0)) + /// For genesis, this is typically the system account (AccountId::from_u64(0)) /// or a virtual sender specified in the genesis file. pub sender: AccountId, diff --git a/crates/app/sdk/collections/src/mocks.rs b/crates/app/sdk/collections/src/mocks.rs index 14060ef..70c56a2 100644 --- a/crates/app/sdk/collections/src/mocks.rs +++ b/crates/app/sdk/collections/src/mocks.rs @@ -28,10 +28,10 @@ impl MockEnvironment { } impl MockEnvironment { - pub fn new(account_id: u128, sender_id: u128) -> Self { + pub fn new(account_id: u64, sender_id: u64) -> Self { Self { - account_id: AccountId::new(account_id), - sender_id: AccountId::new(sender_id), + account_id: AccountId::from_u64(account_id), + sender_id: AccountId::from_u64(sender_id), storage: HashMap::new(), should_fail: false, unique_counter: 0, diff --git a/crates/app/sdk/core/src/fungible_asset.rs b/crates/app/sdk/core/src/fungible_asset.rs index 50c6c25..b899e1f 100644 --- a/crates/app/sdk/core/src/fungible_asset.rs +++ b/crates/app/sdk/core/src/fungible_asset.rs @@ -53,14 +53,20 @@ impl FungibleAsset { mod tests { use super::*; + const ID_1234: AccountId = AccountId::from_u64(1234); + const ID_1111: AccountId = AccountId::from_u64(1111); + const ID_2222: AccountId = AccountId::from_u64(2222); + const ID_1: AccountId = AccountId::from_u64(1); + const ID_9999: AccountId = AccountId::from_u64(9999); + #[test] fn test_increase_same_id() { let mut asset1 = FungibleAsset { - asset_id: AccountId::new(1234), + asset_id: ID_1234, amount: 100, }; let asset2 = FungibleAsset { - asset_id: AccountId::new(1234), + asset_id: ID_1234, amount: 50, }; let result = asset1.increase(asset2); @@ -72,11 +78,11 @@ mod tests { #[test] fn test_decrease_same_id() { let mut asset1 = FungibleAsset { - asset_id: AccountId::new(1234), + asset_id: ID_1234, amount: 100, }; let asset2 = FungibleAsset { - asset_id: AccountId::new(1234), + asset_id: ID_1234, amount: 80, }; let result = asset1.decrease(asset2); @@ -88,11 +94,11 @@ mod tests { #[test] fn test_increase_different_id() { let mut asset1 = FungibleAsset { - asset_id: AccountId::new(1111), + asset_id: ID_1111, amount: 100, }; let asset2 = FungibleAsset { - asset_id: AccountId::new(2222), + asset_id: ID_2222, amount: 50, }; let result = asset1.increase(asset2); @@ -104,11 +110,11 @@ mod tests { #[test] fn test_decrease_different_id() { let mut asset1 = FungibleAsset { - asset_id: AccountId::new(1111), + asset_id: ID_1111, amount: 100, }; let asset2 = FungibleAsset { - asset_id: AccountId::new(2222), + asset_id: ID_2222, amount: 50, }; let result = asset1.decrease(asset2); @@ -120,11 +126,11 @@ mod tests { #[test] fn test_increase_overflow() { let mut asset1 = FungibleAsset { - asset_id: AccountId::new(1), + asset_id: ID_1, amount: u128::MAX, }; let asset2 = FungibleAsset { - asset_id: AccountId::new(1), + asset_id: ID_1, amount: 1, }; let result = asset1.increase(asset2); @@ -136,11 +142,11 @@ mod tests { #[test] fn test_decrease_insufficient_balance() { let mut asset1 = FungibleAsset { - asset_id: AccountId::new(9999), + asset_id: ID_9999, amount: 100, }; let asset2 = FungibleAsset { - asset_id: AccountId::new(9999), + asset_id: ID_9999, amount: 200, }; let result = asset1.decrease(asset2); diff --git a/crates/app/sdk/core/src/lib.rs b/crates/app/sdk/core/src/lib.rs index 0314223..38077ab 100644 --- a/crates/app/sdk/core/src/lib.rs +++ b/crates/app/sdk/core/src/lib.rs @@ -58,6 +58,18 @@ impl AccountId { Self(bytes) } + /// Construct from a `u64` numeric identifier. + /// + /// Encodes `n` in the last 8 bytes (indices 24–31) in big-endian order. + /// Suitable for well-known system accounts and test fixtures. + pub const fn from_u64(n: u64) -> Self { + let b = n.to_be_bytes(); + Self([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, b[0], b[1], + b[2], b[3], b[4], b[5], b[6], b[7], + ]) + } + /// Return raw canonical bytes. pub const fn to_bytes(self) -> [u8; 32] { self.0 @@ -68,42 +80,6 @@ impl AccountId { self.0 } - /// Backward-compatible constructor from `u128`. - /// - /// Encodes into the lower 16 bytes in big-endian order. - // TODO(account-id-cleanup): remove numeric AccountId compatibility (`new`/`inner`) - // after migrating genesis/tooling/docs to canonical 32-byte account IDs end-to-end. - pub const fn new(u: u128) -> Self { - let mut out = [0u8; 32]; - let bytes = u.to_be_bytes(); - out[16] = bytes[0]; - out[17] = bytes[1]; - out[18] = bytes[2]; - out[19] = bytes[3]; - out[20] = bytes[4]; - out[21] = bytes[5]; - out[22] = bytes[6]; - out[23] = bytes[7]; - out[24] = bytes[8]; - out[25] = bytes[9]; - out[26] = bytes[10]; - out[27] = bytes[11]; - out[28] = bytes[12]; - out[29] = bytes[13]; - out[30] = bytes[14]; - out[31] = bytes[15]; - Self(out) - } - - /// Legacy extractor for compatibility where a numeric ID is still required. - pub const fn inner(&self) -> u128 { - u128::from_be_bytes([ - self.0[16], self.0[17], self.0[18], self.0[19], self.0[20], self.0[21], self.0[22], - self.0[23], self.0[24], self.0[25], self.0[26], self.0[27], self.0[28], self.0[29], - self.0[30], self.0[31], - ]) - } - /// Increment account ID bytes in big-endian order (wraps on overflow). pub fn increase(&self) -> Self { let mut out = self.0; @@ -285,24 +261,24 @@ mod tests { #[test] fn test_one_coin_success() { let env = TestEnv { - whoami: AccountId::new(1), - sender: AccountId::new(2), + whoami: AccountId::from_u64(1), + sender: AccountId::from_u64(2), funds: vec![FungibleAsset { - asset_id: AccountId::new(10), + asset_id: AccountId::from_u64(10), amount: 100, }], }; let coin = one_coin(&env).unwrap(); - assert_eq!(coin.asset_id, AccountId::new(10)); + assert_eq!(coin.asset_id, AccountId::from_u64(10)); assert_eq!(coin.amount, 100); } #[test] fn test_one_coin_error() { let env = TestEnv { - whoami: AccountId::new(1), - sender: AccountId::new(2), + whoami: AccountId::from_u64(1), + sender: AccountId::from_u64(2), funds: vec![], }; @@ -317,17 +293,14 @@ mod tests { #[test] fn test_account_id_u128_compat() { - let id = AccountId::new(42u128); - assert_eq!(id.inner(), 42u128); - - let mut expected = [0u8; 32]; - expected[31] = 42; - assert_eq!(id.as_bytes(), expected); + let id = AccountId::from_u64(42); + assert_eq!(id.as_bytes()[31], 42u8); + assert_eq!(id.as_bytes()[0..31], [0u8; 31]); } #[test] fn test_account_id_increase() { - let a = AccountId::from_bytes([0u8; 32]); + let a = AccountId::from_u64(0); let b = a.increase(); let mut expected = [0u8; 32]; expected[31] = 1; diff --git a/crates/app/sdk/core/src/runtime_api.rs b/crates/app/sdk/core/src/runtime_api.rs index d1edf4b..3816227 100644 --- a/crates/app/sdk/core/src/runtime_api.rs +++ b/crates/app/sdk/core/src/runtime_api.rs @@ -3,7 +3,7 @@ use crate::{AccountId, InvokableMessage, InvokeRequest, InvokeResponse}; use borsh::{BorshDeserialize, BorshSerialize}; pub const ACCOUNT_IDENTIFIER_PREFIX: u8 = 0; pub const ACCOUNT_IDENTIFIER_SINGLETON_PREFIX: u8 = 1; -pub const RUNTIME_ACCOUNT_ID: AccountId = AccountId::from_bytes([0u8; 32]); +pub const RUNTIME_ACCOUNT_ID: AccountId = AccountId::from_u64(0); /// Storage key for consensus parameters. /// This is a well-known key that nodes read to validate blocks during sync. diff --git a/crates/app/sdk/core/src/storage_api.rs b/crates/app/sdk/core/src/storage_api.rs index 31f7a6c..0f1a332 100644 --- a/crates/app/sdk/core/src/storage_api.rs +++ b/crates/app/sdk/core/src/storage_api.rs @@ -1,7 +1,7 @@ use crate::{AccountId, InvokableMessage, Message}; use borsh::{BorshDeserialize, BorshSerialize}; -pub const STORAGE_ACCOUNT_ID: AccountId = AccountId::new(1); +pub const STORAGE_ACCOUNT_ID: AccountId = AccountId::from_u64(1); #[derive(BorshDeserialize, BorshSerialize, Clone)] pub struct StorageGetRequest { diff --git a/crates/app/sdk/core/src/unique_api.rs b/crates/app/sdk/core/src/unique_api.rs index 25dfef3..429cc8f 100644 --- a/crates/app/sdk/core/src/unique_api.rs +++ b/crates/app/sdk/core/src/unique_api.rs @@ -1,3 +1,3 @@ use crate::AccountId; -pub const UNIQUE_HANDLER_ACCOUNT_ID: AccountId = AccountId::new(5); +pub const UNIQUE_HANDLER_ACCOUNT_ID: AccountId = AccountId::from_u64(5); diff --git a/crates/app/sdk/extensions/nonceless_account/src/lib.rs b/crates/app/sdk/extensions/nonceless_account/src/lib.rs index 5d55218..b7ca420 100644 --- a/crates/app/sdk/extensions/nonceless_account/src/lib.rs +++ b/crates/app/sdk/extensions/nonceless_account/src/lib.rs @@ -109,9 +109,8 @@ mod tests { use crate::account::{NoncelessAccount, ERR_TIMESTAMP_REPLAY}; - fn setup_account(owner_id: u128) -> (NoncelessAccount, MockEnv) { - let contract_address = AccountId::new(1); - let owner = AccountId::new(owner_id); + fn setup_account(owner: AccountId) -> (NoncelessAccount, MockEnv) { + let contract_address = AccountId::from_u64(1); let mut env = MockEnv::new(contract_address, owner); let account = NoncelessAccount::default(); @@ -124,15 +123,17 @@ mod tests { #[test] fn test_initialize() { - let (account, mut env) = setup_account(42); + let owner42 = AccountId::from_u64(42); + let (account, mut env) = setup_account(owner42); assert_eq!(account.get_last_timestamp(&mut env).unwrap(), 0); - assert_eq!(account.get_owner(&mut env).unwrap(), AccountId::new(42)); + assert_eq!(account.get_owner(&mut env).unwrap(), owner42); } #[test] fn test_verify_and_update_success() { - let (account, mut env) = setup_account(42); + let owner42 = AccountId::from_u64(42); + let (account, mut env) = setup_account(owner42); account.verify_and_update(1000, &mut env).unwrap(); assert_eq!(account.get_last_timestamp(&mut env).unwrap(), 1000); @@ -143,7 +144,8 @@ mod tests { #[test] fn test_timestamp_replay_rejected() { - let (account, mut env) = setup_account(42); + let owner42 = AccountId::from_u64(42); + let (account, mut env) = setup_account(owner42); // First update succeeds account.verify_and_update(1000, &mut env).unwrap(); @@ -166,10 +168,11 @@ mod tests { #[test] fn test_unauthorized() { - let (account, mut env) = setup_account(42); + let owner42 = AccountId::from_u64(42); + let (account, mut env) = setup_account(owner42); // Change sender to non-owner - env = env.with_sender(AccountId::new(999)); + env = env.with_sender(AccountId::from_u64(999)); let result = account.verify_and_update(1000, &mut env); assert!(matches!(result, Err(e) if e == ERR_UNAUTHORIZED)); diff --git a/crates/app/sdk/extensions/scheduler/src/lib.rs b/crates/app/sdk/extensions/scheduler/src/lib.rs index e997c86..f6f86f7 100644 --- a/crates/app/sdk/extensions/scheduler/src/lib.rs +++ b/crates/app/sdk/extensions/scheduler/src/lib.rs @@ -134,7 +134,7 @@ mod tests { fn setup_scheduler() -> (Scheduler, MockEnv) { let scheduler = Scheduler::default(); - let contract_address = AccountId::new(1); + let contract_address = AccountId::from_u64(1); let mut env = MockEnv::new(contract_address, RUNTIME_ACCOUNT_ID); scheduler @@ -147,9 +147,9 @@ mod tests { #[test] fn update_begin_blockers_requires_runtime_sender() { let (scheduler, mut env) = setup_scheduler(); - env = env.with_sender(AccountId::new(999)); + env = env.with_sender(AccountId::from_u64(999)); - let result = scheduler.update_begin_blockers(vec![AccountId::new(10)], &mut env); + let result = scheduler.update_begin_blockers(vec![AccountId::from_u64(10)], &mut env); assert!(matches!(result, Err(e) if e == ERR_UNAUTHORIZED)); let stored = scheduler @@ -163,9 +163,9 @@ mod tests { #[test] fn update_end_blockers_requires_runtime_sender() { let (scheduler, mut env) = setup_scheduler(); - env = env.with_sender(AccountId::new(999)); + env = env.with_sender(AccountId::from_u64(999)); - let result = scheduler.update_end_blockers(vec![AccountId::new(20)], &mut env); + let result = scheduler.update_end_blockers(vec![AccountId::from_u64(20)], &mut env); assert!(matches!(result, Err(e) if e == ERR_UNAUTHORIZED)); let stored = scheduler @@ -181,10 +181,13 @@ mod tests { let (scheduler, mut env) = setup_scheduler(); scheduler - .update_begin_blockers(vec![AccountId::new(10), AccountId::new(11)], &mut env) + .update_begin_blockers( + vec![AccountId::from_u64(10), AccountId::from_u64(11)], + &mut env, + ) .unwrap(); scheduler - .update_end_blockers(vec![AccountId::new(20)], &mut env) + .update_end_blockers(vec![AccountId::from_u64(20)], &mut env) .unwrap(); let begin = scheduler @@ -204,7 +207,7 @@ mod tests { #[test] fn schedule_methods_require_runtime_sender() { let (scheduler, mut env) = setup_scheduler(); - env = env.with_sender(AccountId::new(999)); + env = env.with_sender(AccountId::from_u64(999)); let begin_result = scheduler.schedule_begin_block(&mut env); assert!(matches!(begin_result, Err(e) if e == ERR_UNAUTHORIZED)); diff --git a/crates/app/sdk/extensions/token/src/lib.rs b/crates/app/sdk/extensions/token/src/lib.rs index 1d3bda6..7cdaf0e 100644 --- a/crates/app/sdk/extensions/token/src/lib.rs +++ b/crates/app/sdk/extensions/token/src/lib.rs @@ -183,16 +183,15 @@ mod tests { /// Helper to initialize a `Token` with some default data. /// Returns `(token_instance, env)`. fn setup_token( - supply_manager_id: u128, - initial_holder_id: u128, + supply_manager: AccountId, + initial_holder: AccountId, initial_balance: u128, ) -> (Token, MockEnv) { // We'll make the contract's address distinct from the manager and holder - let contract_address = AccountId::new(1); - let sender_address = AccountId::new(supply_manager_id); + let contract_address = AccountId::from_u64(1); // Initialize environment such that `env.sender()` is the supply manager - let mut env = MockEnv::new(contract_address, sender_address); + let mut env = MockEnv::new(contract_address, supply_manager); // Create the token instance let token = Token::default(); @@ -207,17 +206,11 @@ mod tests { }; // Provide initial balances in a vector - let balances = vec![(AccountId::new(initial_holder_id), initial_balance)]; + let balances = vec![(initial_holder, initial_balance)]; // Initialize the token - // supply_manager = Some(AccountId::new(supply_manager_id)) token - .initialize( - metadata, - balances, - Some(AccountId::new(supply_manager_id)), - &mut env, - ) + .initialize(metadata, balances, Some(supply_manager), &mut env) .expect("Failed to initialize token"); (token, env) @@ -226,7 +219,9 @@ mod tests { #[test] fn test_initialize_and_metadata() { // Supply manager = 42, initial holder = 10, balance = 1_000 - let (token, mut env) = setup_token(42, 10, 1000); + let sm42 = AccountId::from_u64(42); + let h10 = AccountId::from_u64(10); + let (token, mut env) = setup_token(sm42, h10, 1000); // Check the metadata query let metadata = token.metadata(&mut env).expect("metadata query failed"); @@ -236,24 +231,26 @@ mod tests { // Check the initial holder's balance let balance = token - .get_balance(AccountId::new(10), &mut env) + .get_balance(h10, &mut env) .expect("get_balance failed") .unwrap(); assert_eq!(balance, 1000); // Check the supply manager let supply_manager = token.supply_manager.get(&mut env).unwrap(); - assert_eq!(supply_manager, Some(AccountId::new(42))); + assert_eq!(supply_manager, Some(sm42)); assert_eq!(token.total_supply(&mut env).unwrap(), 1000); } #[test] fn test_mint_authorized() { // supply_manager = 100, initial_holder = 10, balance=500 - let (token, mut env) = setup_token(100, 10, 500); + let sm100 = AccountId::from_u64(100); + let h10 = AccountId::from_u64(10); + let (token, mut env) = setup_token(sm100, h10, 500); // We'll mint to holder 10 some extra tokens. - let holder = AccountId::new(10); + let holder = h10; let before_balance = token.get_balance(holder, &mut env).unwrap().unwrap(); let before_supply = token.total_supply(&mut env).unwrap(); assert_eq!(before_balance, 500); @@ -278,29 +275,25 @@ mod tests { #[test] fn test_mint_unauthorized() { // supply_manager = 100, but environment sender is changed to 999 - let (token, mut env) = setup_token(100, 10, 500); + let sm100 = AccountId::from_u64(100); + let h10 = AccountId::from_u64(10); + let (token, mut env) = setup_token(sm100, h10, 500); // Change the environment's sender to something not the supply_manager - let new_sender = AccountId::new(999); + let new_sender = AccountId::from_u64(999); env = env.with_sender(new_sender); - let before_balance = token - .get_balance(AccountId::new(10), &mut env) - .unwrap() - .unwrap(); + let before_balance = token.get_balance(h10, &mut env).unwrap().unwrap(); let before_supply = token.total_supply(&mut env).unwrap(); // Attempt to mint - let result = token.mint(AccountId::new(10), 200, &mut env); + let result = token.mint(h10, 200, &mut env); assert!( matches!(result, Err(e) if e == ERR_UNAUTHORIZED), "Mint should fail with ERR_UNAUTHORIZED" ); - let after_balance = token - .get_balance(AccountId::new(10), &mut env) - .unwrap() - .unwrap(); + let after_balance = token.get_balance(h10, &mut env).unwrap().unwrap(); let after_supply = token.total_supply(&mut env).unwrap(); assert_eq!(after_balance, before_balance); assert_eq!(after_supply, before_supply); @@ -309,10 +302,12 @@ mod tests { #[test] fn test_burn_authorized() { // supply_manager = 42, initial_holder = 10, balance=1000 - let (token, mut env) = setup_token(42, 10, 1000); + let sm42 = AccountId::from_u64(42); + let h10 = AccountId::from_u64(10); + let (token, mut env) = setup_token(sm42, h10, 1000); // We'll burn from holder 10 - let holder = AccountId::new(10); + let holder = h10; let before_balance = token.get_balance(holder, &mut env).unwrap().unwrap(); let before_supply = token.total_supply(&mut env).unwrap(); @@ -340,28 +335,24 @@ mod tests { #[test] fn test_burn_unauthorized() { - let (token, mut env) = setup_token(42, 10, 500); + let sm42 = AccountId::from_u64(42); + let h10 = AccountId::from_u64(10); + let (token, mut env) = setup_token(sm42, h10, 500); // Change environment's sender to 999 - env = env.with_sender(AccountId::new(999)); + env = env.with_sender(AccountId::from_u64(999)); - let before_balance = token - .get_balance(AccountId::new(10), &mut env) - .unwrap() - .unwrap(); + let before_balance = token.get_balance(h10, &mut env).unwrap().unwrap(); let before_supply = token.total_supply(&mut env).unwrap(); // Attempt to burn - let result = token.burn(AccountId::new(10), 100, &mut env); + let result = token.burn(h10, 100, &mut env); assert!( matches!(result, Err(e) if e == ERR_UNAUTHORIZED), "Burn should fail with ERR_UNAUTHORIZED" ); - let after_balance = token - .get_balance(AccountId::new(10), &mut env) - .unwrap() - .unwrap(); + let after_balance = token.get_balance(h10, &mut env).unwrap().unwrap(); let after_supply = token.total_supply(&mut env).unwrap(); assert_eq!(after_balance, before_balance); assert_eq!(after_supply, before_supply); @@ -370,15 +361,17 @@ mod tests { #[test] fn test_transfer_sufficient_balance() { // supply_manager=1, just ignore it for now. initial_holder=50, balance=1000 - let (token, mut env) = setup_token(1, 50, 1000); + let sm1 = AccountId::from_u64(1); + let h50 = AccountId::from_u64(50); + let (token, mut env) = setup_token(sm1, h50, 1000); // For transfer, the environment's sender is the one transferring. // We'll assume the initial holder(50) is the same as env.sender, // so that holder can transfer their tokens. - env = env.with_sender(AccountId::new(50)); + env = env.with_sender(h50); // Transfer 300 tokens from 50 -> 60 - let recipient = AccountId::new(60); + let recipient = AccountId::from_u64(60); let supply_before = token.total_supply(&mut env).unwrap(); let result = token.transfer(recipient, 300, &mut env); assert!( @@ -386,10 +379,7 @@ mod tests { "Transfer should succeed with enough balance" ); - let from_balance = token - .get_balance(AccountId::new(50), &mut env) - .unwrap() - .unwrap(); + let from_balance = token.get_balance(h50, &mut env).unwrap().unwrap(); assert_eq!( from_balance, 700, "Should have subtracted 300 tokens from sender" @@ -406,32 +396,25 @@ mod tests { #[test] fn test_transfer_insufficient_balance() { - let (token, mut env) = setup_token(1, 50, 100); - - env = env.with_sender(AccountId::new(50)); - let before_from = token - .get_balance(AccountId::new(50), &mut env) - .unwrap() - .unwrap(); - let before_to = token - .get_balance(AccountId::new(60), &mut env) - .unwrap_or(None); + let sm1 = AccountId::from_u64(1); + let h50 = AccountId::from_u64(50); + let h60 = AccountId::from_u64(60); + let (token, mut env) = setup_token(sm1, h50, 100); + + env = env.with_sender(h50); + let before_from = token.get_balance(h50, &mut env).unwrap().unwrap(); + let before_to = token.get_balance(h60, &mut env).unwrap_or(None); let before_supply = token.total_supply(&mut env).unwrap(); // Attempt to transfer 999, but user only has 100 - let result = token.transfer(AccountId::new(60), 999, &mut env); + let result = token.transfer(h60, 999, &mut env); assert!( matches!(result, Err(e) if e == ERR_NOT_ENOUGH_BALANCE), "Should fail with ERR_NOT_ENOUGH_BALANCE" ); - let after_from = token - .get_balance(AccountId::new(50), &mut env) - .unwrap() - .unwrap(); - let after_to = token - .get_balance(AccountId::new(60), &mut env) - .unwrap_or(None); + let after_from = token.get_balance(h50, &mut env).unwrap().unwrap(); + let after_to = token.get_balance(h60, &mut env).unwrap_or(None); let after_supply = token.total_supply(&mut env).unwrap(); assert_eq!(after_from, before_from); assert_eq!(after_to, before_to); @@ -440,9 +423,11 @@ mod tests { #[test] fn test_burn_underflow_preserves_state() { - let (token, mut env) = setup_token(42, 10, 50); + let sm42 = AccountId::from_u64(42); + let h10 = AccountId::from_u64(10); + let (token, mut env) = setup_token(sm42, h10, 50); - let holder = AccountId::new(10); + let holder = h10; let before_balance = token.get_balance(holder, &mut env).unwrap().unwrap(); let before_supply = token.total_supply(&mut env).unwrap(); @@ -458,11 +443,13 @@ mod tests { #[test] fn test_get_balance_not_set_yet() { // supply_manager=2, initial_holder=10, initial_balance=100 - let (token, mut env) = setup_token(2, 10, 100); + let sm2 = AccountId::from_u64(2); + let h10 = AccountId::from_u64(10); + let (token, mut env) = setup_token(sm2, h10, 100); // Query an account that wasn't given an initial balance let balance = token - .get_balance(AccountId::new(999), &mut env) + .get_balance(AccountId::from_u64(999), &mut env) .expect("call failed"); assert_eq!(balance, None, "Account 999 should not have a balance yet"); } diff --git a/crates/app/sdk/standards/evolve_authentication/src/lib.rs b/crates/app/sdk/standards/evolve_authentication/src/lib.rs index 2058114..c006ce2 100644 --- a/crates/app/sdk/standards/evolve_authentication/src/lib.rs +++ b/crates/app/sdk/standards/evolve_authentication/src/lib.rs @@ -125,7 +125,7 @@ mod tests { impl AuthEnv { fn new(sender: AccountId, auth_result: Result<(), ErrorCode>) -> Self { Self { - whoami: AccountId::new(999), + whoami: AccountId::from_u64(999), sender, auth_result, last_exec_to: None, @@ -184,7 +184,7 @@ mod tests { fn make_tx(sender: AccountId) -> DummyTx { DummyTx { sender, - recipient: AccountId::new(200), + recipient: AccountId::from_u64(200), request: InvokeRequest::new(&DummyInvoke { value: 1 }).expect("request should encode"), payload: Message::new(&DummyInvoke { value: 42 }).expect("payload should encode"), } @@ -192,7 +192,7 @@ mod tests { #[test] fn validate_tx_dispatches_auth_to_sender_account() { - let sender = AccountId::new(100); + let sender = AccountId::from_u64(100); let tx = make_tx(sender); let validator = AuthenticationTxValidator::::new(); let mut env = AuthEnv::new(sender, Ok(())); @@ -207,7 +207,7 @@ mod tests { #[test] fn validate_tx_maps_unknown_function_to_not_eoa() { - let sender = AccountId::new(100); + let sender = AccountId::from_u64(100); let tx = make_tx(sender); let validator = AuthenticationTxValidator::::new(); let mut env = AuthEnv::new(sender, Err(ERR_UNKNOWN_FUNCTION)); @@ -221,7 +221,7 @@ mod tests { #[test] fn validate_tx_preserves_non_unknown_errors() { - let sender = AccountId::new(100); + let sender = AccountId::from_u64(100); let tx = make_tx(sender); let validator = AuthenticationTxValidator::::new(); let mut env = AuthEnv::new(sender, Err(evolve_core::ERR_UNAUTHORIZED)); diff --git a/crates/app/sdk/standards/evolve_fungible_asset/src/lib.rs b/crates/app/sdk/standards/evolve_fungible_asset/src/lib.rs index 52d9cf0..6cae606 100644 --- a/crates/app/sdk/standards/evolve_fungible_asset/src/lib.rs +++ b/crates/app/sdk/standards/evolve_fungible_asset/src/lib.rs @@ -48,8 +48,8 @@ mod tests { impl TestEnv { fn new() -> Self { Self { - whoami: AccountId::new(1), - sender: AccountId::new(2), + whoami: AccountId::from_u64(1), + sender: AccountId::from_u64(2), last_query: None, last_exec: None, } @@ -116,7 +116,7 @@ mod tests { #[test] fn interface_ref_queries_decode_expected_types() { let mut env = TestEnv::new(); - let account = AccountId::new(10); + let account = AccountId::from_u64(10); let fa = FungibleAssetInterfaceRef::new(account); let metadata = fa @@ -127,7 +127,7 @@ mod tests { assert_eq!(metadata.decimals, 6); let balance = fa - .get_balance(AccountId::new(999), &mut env) + .get_balance(AccountId::from_u64(999), &mut env) .expect("balance query should succeed"); assert_eq!(balance, Some(123)); @@ -141,10 +141,10 @@ mod tests { #[test] fn interface_ref_transfer_dispatches_exec_call() { let mut env = TestEnv::new(); - let account = AccountId::new(10); + let account = AccountId::from_u64(10); let fa = FungibleAssetInterfaceRef::new(account); - fa.transfer(AccountId::new(11), 55, &mut env) + fa.transfer(AccountId::from_u64(11), 55, &mut env) .expect("transfer should succeed"); assert_eq!(env.last_exec.as_deref(), Some("transfer")); diff --git a/crates/app/sdk/testing/src/lib.rs b/crates/app/sdk/testing/src/lib.rs index 2989aca..3484a4a 100644 --- a/crates/app/sdk/testing/src/lib.rs +++ b/crates/app/sdk/testing/src/lib.rs @@ -233,16 +233,16 @@ mod tests { #[test] fn test_env_configuration() { // Create numeric account IDs: - let whoami = AccountId::new(1234_u128); - let sender = AccountId::new(5678_u128); + let whoami = AccountId::from_u64(1234); + let sender = AccountId::from_u64(5678); let funds = vec![ FungibleAsset { - asset_id: AccountId::new(55000), + asset_id: AccountId::from_u64(55000), amount: 123, }, FungibleAsset { - asset_id: AccountId::new(55100), + asset_id: AccountId::from_u64(55100), amount: 456, }, ]; @@ -265,8 +265,8 @@ mod tests { #[test] fn test_storage_set_and_get() { - let whoami = AccountId::new(100_u128); - let sender = AccountId::new(200_u128); + let whoami = AccountId::from_u64(100); + let sender = AccountId::from_u64(200); let mut env = MockEnv::new(whoami, sender); // 1) Prepare a StorageSetRequest @@ -306,8 +306,8 @@ mod tests { #[test] fn test_storage_remove() { - let whoami = AccountId::new(300_u128); - let sender = AccountId::new(400_u128); + let whoami = AccountId::from_u64(300); + let sender = AccountId::from_u64(400); let mut env = MockEnv::new(whoami, sender); // First, set something @@ -352,8 +352,8 @@ mod tests { #[test] fn test_with_query_handler() { - let whoami = AccountId::new(700_u128); - let sender = AccountId::new(800_u128); + let whoami = AccountId::from_u64(700); + let sender = AccountId::from_u64(800); // This is a custom request type with a unique FUNCTION_IDENTIFIER #[derive(Clone, Debug)] @@ -418,7 +418,7 @@ mod tests { let invoke_req = make_invoke_request(&query).unwrap(); // Perform the query - let result = env.do_query(AccountId::new(9999_u128), &invoke_req); + let result = env.do_query(AccountId::from_u64(9999), &invoke_req); assert!(result.is_ok(), "Query handler should succeed."); let response: CustomQueryResp = result.unwrap().get().expect("Decode error"); @@ -430,8 +430,8 @@ mod tests { #[test] fn test_with_exec_handler() { - let whoami = AccountId::new(900_u128); - let sender = AccountId::new(1000_u128); + let whoami = AccountId::from_u64(900); + let sender = AccountId::from_u64(1000); // We'll reuse the same approach, but define a unique function ID #[derive(Clone, Debug)] @@ -493,11 +493,11 @@ mod tests { let invoke_req = make_invoke_request(&custom_exec_req).unwrap(); let funds = vec![FungibleAsset { - asset_id: AccountId::new(9999_u128), + asset_id: AccountId::from_u64(9999), amount: 100, }]; - let result = env.do_exec(AccountId::new(1111_u128), &invoke_req, funds); + let result = env.do_exec(AccountId::from_u64(1111), &invoke_req, funds); assert!(result.is_ok(), "Execution should succeed."); let response: CustomExecResp = result.unwrap().get().expect("Decode error"); assert!( @@ -529,23 +529,23 @@ mod tests { const FUNCTION_IDENTIFIER_NAME: &'static str = "missing_req"; } - let whoami = AccountId::new(1); - let sender = AccountId::new(2); + let whoami = AccountId::from_u64(1); + let sender = AccountId::from_u64(2); let mut env = MockEnv::new(whoami, sender); let req = make_invoke_request(&MissingReq).unwrap(); - let query_result = env.do_query(AccountId::new(3), &req); + let query_result = env.do_query(AccountId::from_u64(3), &req); assert!(matches!(query_result, Err(e) if e == ERR_UNKNOWN_FUNCTION)); - let exec_result = env.do_exec(AccountId::new(3), &req, Vec::new()); + let exec_result = env.do_exec(AccountId::from_u64(3), &req, Vec::new()); assert!(matches!(exec_result, Err(e) if e == ERR_UNKNOWN_FUNCTION)); } #[test] fn test_storage_set_is_namespaced_by_whoami() { - let owner_a = AccountId::new(10); - let owner_b = AccountId::new(11); - let sender = AccountId::new(20); + let owner_a = AccountId::from_u64(10); + let owner_b = AccountId::from_u64(11); + let sender = AccountId::from_u64(20); let mut env = MockEnv::new(owner_a, sender); let set_request = StorageSetRequest { @@ -588,8 +588,8 @@ mod tests { #[test] fn test_unique_id_monotonic_counter_prefix() { - let whoami = AccountId::new(100); - let sender = AccountId::new(200); + let whoami = AccountId::from_u64(100); + let sender = AccountId::from_u64(200); let mut env = MockEnv::new(whoami, sender); let id1 = env.unique_id().unwrap(); diff --git a/crates/app/stf/src/lib.rs b/crates/app/stf/src/lib.rs index fbc3a7d..b988fbc 100644 --- a/crates/app/stf/src/lib.rs +++ b/crates/app/stf/src/lib.rs @@ -107,8 +107,8 @@ mod model_tests { const DEFAULT_CASES: u32 = 32; const CI_CASES: u32 = 8; const MAX_TXS: usize = 16; - const TEST_ACCOUNT_ID: AccountId = AccountId::new(100); - const DEFAULT_SENDER_ID: AccountId = AccountId::new(200); + const TEST_ACCOUNT_ID: AccountId = AccountId::from_u64(100); + const DEFAULT_SENDER_ID: AccountId = AccountId::from_u64(200); fn proptest_cases() -> u32 { if let Ok(value) = std::env::var("EVOLVE_PROPTEST_CASES") { @@ -448,8 +448,8 @@ mod model_tests { 0..=MAX_TXS ) ) { - let test_account = AccountId::new(100); - let sender = AccountId::new(200); + let test_account = AccountId::from_u64(100); + let sender = AccountId::from_u64(200); let mut storage = InMemoryStorage::default(); let mut codes = CodeStore::new(); @@ -558,8 +558,8 @@ mod model_tests { 1..=8 ) ) { - let test_account = AccountId::new(100); - let sender = AccountId::new(200); + let test_account = AccountId::from_u64(100); + let sender = AccountId::from_u64(200); // Setup storage with account code let mut storage1 = InMemoryStorage::default(); @@ -649,8 +649,8 @@ mod model_tests { fn test_call_depth_exhaustion() { use crate::errors::ERR_CALL_DEPTH_EXCEEDED; - let recursive_account = AccountId::new(100); - let sender = AccountId::new(200); + let recursive_account = AccountId::from_u64(100); + let sender = AccountId::from_u64(200); let mut storage = InMemoryStorage::default(); let gas_config = StorageGasConfig { @@ -766,7 +766,7 @@ mod model_tests { ) -> SdkResult<()> { // Reject successful txs where sender has a specific pattern // (Using sender ID as a marker for simplicity) - if tx_result.is_ok() && tx.sender == AccountId::new(201) { + if tx_result.is_ok() && tx.sender == AccountId::from_u64(201) { return Err(ERR_REJECTED_BY_POST_TX); } Ok(()) @@ -790,7 +790,7 @@ mod model_tests { // Tx from sender 200 should succeed let tx_normal = TestTx { - sender: AccountId::new(200), + sender: AccountId::from_u64(200), recipient: TEST_ACCOUNT_ID, request: InvokeRequest::new(&msg).unwrap(), gas_limit: 10000, @@ -800,7 +800,7 @@ mod model_tests { // Tx from sender 201 should be rejected by post-tx handler let tx_marked = TestTx { - sender: AccountId::new(201), + sender: AccountId::from_u64(201), recipient: TEST_ACCOUNT_ID, request: InvokeRequest::new(&msg).unwrap(), gas_limit: 10000, diff --git a/crates/app/stf/src/runtime_api_impl.rs b/crates/app/stf/src/runtime_api_impl.rs index 9693916..ddc1677 100644 --- a/crates/app/stf/src/runtime_api_impl.rs +++ b/crates/app/stf/src/runtime_api_impl.rs @@ -2,8 +2,9 @@ use crate::execution_state::ExecutionState; use evolve_core::runtime_api::{ACCOUNT_IDENTIFIER_PREFIX, ACCOUNT_IDENTIFIER_SINGLETON_PREFIX}; use evolve_core::{AccountId, Message, ReadonlyKV, SdkResult}; -/// Initial account ID value - starts from u16::MAX to distinguish from default 0 -const INITIAL_ACCOUNT_ID: u64 = u16::MAX as u64; +/// First account number assigned by the runtime. Account IDs below this +/// threshold are reserved for well-known system accounts. +const INITIAL_ACCOUNT_NUMBER: u64 = 65_535; pub(crate) fn get_account_code_identifier_for_account( storage: &ExecutionState, @@ -41,7 +42,7 @@ pub(crate) fn next_account_number( let last = storage .get(&key)? .map(|msg| msg.get()) - .unwrap_or(Ok(AccountId::new(INITIAL_ACCOUNT_ID.into())))?; + .unwrap_or(Ok(AccountId::from_u64(INITIAL_ACCOUNT_NUMBER)))?; // set next storage.set(&key, Message::new(&last.increase())?)?; diff --git a/crates/app/tx/eth/src/traits.rs b/crates/app/tx/eth/src/traits.rs index 93bcb53..2721023 100644 --- a/crates/app/tx/eth/src/traits.rs +++ b/crates/app/tx/eth/src/traits.rs @@ -91,7 +91,7 @@ mod tests { #[test] fn test_runtime_contract_address_is_deterministic() { - let id = AccountId::new(0x112233u128); + let id = AccountId::from_u64(1122867); let a = derive_runtime_contract_address(id); let b = derive_runtime_contract_address(id); assert_eq!(a, b); diff --git a/crates/rpc/chain-index/src/integration.rs b/crates/rpc/chain-index/src/integration.rs index 35bab4c..6ce19ae 100644 --- a/crates/rpc/chain-index/src/integration.rs +++ b/crates/rpc/chain-index/src/integration.rs @@ -332,7 +332,7 @@ mod tests { #[test] fn test_event_to_stored_log() { let event = Event { - source: AccountId::new(42), + source: AccountId::from_u64(42), name: "Transfer".to_string(), contents: Message::from_bytes(vec![1, 2, 3, 4]), }; @@ -340,7 +340,7 @@ mod tests { let log = event_to_stored_log(&event); // Address should be derived from AccountId - assert_eq!(log.address, account_id_to_address(AccountId::new(42))); + assert_eq!(log.address, account_id_to_address(AccountId::from_u64(42))); // Should have one topic (the name hash) assert_eq!(log.topics.len(), 1); // Data should match contents diff --git a/crates/rpc/evnode/examples/run_server.rs b/crates/rpc/evnode/examples/run_server.rs index ece4b08..f603fb6 100644 --- a/crates/rpc/evnode/examples/run_server.rs +++ b/crates/rpc/evnode/examples/run_server.rs @@ -20,10 +20,6 @@ use evolve_evnode::{EvnodeServer, EvnodeServerConfig, ExecutorServiceConfig, Sta use evolve_stf_traits::{AccountsCodeStorage, StateChange, WritableAccountsCodeStorage}; use evolve_testapp::{build_mempool_stf, default_gas_config, install_account_codes}; -/// Scheduler account ID as allocated by do_genesis_inner in testapp. -/// This is the 4th account created: alice(65535), bob(65536), atom(65537), scheduler(65538) -const SCHEDULER_ACCOUNT_ID: u128 = 65538; - /// Simple in-memory storage for the example. struct ExampleStorageInner { data: RwLock, Vec>>, @@ -133,7 +129,7 @@ async fn main() -> Result<(), Box> { // 4. Build the STF let gas_config = default_gas_config(); - let stf = build_mempool_stf(gas_config, AccountId::new(SCHEDULER_ACCOUNT_ID)); + let stf = build_mempool_stf(gas_config, AccountId::from_u64(65538)); // 5. Configure the server let addr = "127.0.0.1:50051".parse()?; diff --git a/crates/rpc/types/src/log.rs b/crates/rpc/types/src/log.rs index e28d7c8..2de7758 100644 --- a/crates/rpc/types/src/log.rs +++ b/crates/rpc/types/src/log.rs @@ -157,7 +157,7 @@ mod tests { #[test] fn test_event_to_log_maps_source_name_and_contents() { let event = Event { - source: AccountId::new(42), + source: AccountId::from_u64(42), name: "Transfer".to_string(), contents: Message::from_bytes(vec![0xAB, 0xCD]), }; diff --git a/crates/storage/src/warming.rs b/crates/storage/src/warming.rs index 990780d..2154753 100644 --- a/crates/storage/src/warming.rs +++ b/crates/storage/src/warming.rs @@ -314,9 +314,9 @@ mod tests { use evolve_core::AccountId; use patterns::*; - let token = AccountId::new(1); - let sender = AccountId::new(2); - let recipient = AccountId::new(3); + let token = AccountId::from_u64(1); + let sender = AccountId::from_u64(2); + let recipient = AccountId::from_u64(3); // Just verify the functions don't panic and return non-empty keys assert!(!balance_key(token, sender).is_empty()); diff --git a/crates/testing/debugger/src/breakpoints.rs b/crates/testing/debugger/src/breakpoints.rs index a737a17..a9aea47 100644 --- a/crates/testing/debugger/src/breakpoints.rs +++ b/crates/testing/debugger/src/breakpoints.rs @@ -308,8 +308,8 @@ mod tests { #[test] fn test_on_account() { - let account = AccountId::new(42); - let other = AccountId::new(100); + let account = AccountId::from_u64(42); + let other = AccountId::from_u64(100); let bp = Breakpoint::on_account(account); let state = StateSnapshot::empty(); diff --git a/crates/testing/debugger/src/inspector.rs b/crates/testing/debugger/src/inspector.rs index 53131f7..9fff3ac 100644 --- a/crates/testing/debugger/src/inspector.rs +++ b/crates/testing/debugger/src/inspector.rs @@ -381,14 +381,14 @@ mod tests { let mut builder = TraceBuilder::new(42, StateSnapshot::empty()); builder.block_start(0, 1000); - builder.tx_start([1; 32], AccountId::new(1), AccountId::new(2)); + builder.tx_start([1; 32], AccountId::from_u64(1), AccountId::from_u64(2)); builder.state_change(b"balance:user1".to_vec(), None, Some(b"100".to_vec())); builder.state_change(b"balance:user2".to_vec(), None, Some(b"200".to_vec())); builder.tx_end([1; 32], true, 100); builder.block_end(0, [0; 32]); builder.block_start(1, 2000); - builder.tx_start([2; 32], AccountId::new(2), AccountId::new(3)); + builder.tx_start([2; 32], AccountId::from_u64(2), AccountId::from_u64(3)); builder.state_change( b"balance:user1".to_vec(), Some(b"100".to_vec()), diff --git a/crates/testing/debugger/src/lib.rs b/crates/testing/debugger/src/lib.rs index 24c8220..b177575 100644 --- a/crates/testing/debugger/src/lib.rs +++ b/crates/testing/debugger/src/lib.rs @@ -70,7 +70,7 @@ mod tests { let mut builder = TraceBuilder::new(42, StateSnapshot::empty()); builder.block_start(0, 1000); - builder.tx_start([1; 32], AccountId::new(1), AccountId::new(2)); + builder.tx_start([1; 32], AccountId::from_u64(1), AccountId::from_u64(2)); builder.state_change(b"key".to_vec(), None, Some(b"value".to_vec())); builder.tx_end([1; 32], true, 100); builder.block_end(0, [0; 32]); @@ -120,7 +120,7 @@ mod tests { fn test_breakpoint_on_error() { let mut builder = TraceBuilder::new(42, StateSnapshot::empty()); builder.block_start(0, 1000); - builder.tx_start([1; 32], AccountId::new(1), AccountId::new(2)); + builder.tx_start([1; 32], AccountId::from_u64(1), AccountId::from_u64(2)); builder.error(1, "test error"); builder.tx_end([1; 32], false, 50); builder.block_end(0, [0; 32]); diff --git a/crates/testing/debugger/src/replay.rs b/crates/testing/debugger/src/replay.rs index df27b85..c165485 100644 --- a/crates/testing/debugger/src/replay.rs +++ b/crates/testing/debugger/src/replay.rs @@ -316,13 +316,13 @@ mod tests { let mut builder = TraceBuilder::new(42, StateSnapshot::empty()); builder.block_start(0, 1000); - builder.tx_start([1; 32], AccountId::new(1), AccountId::new(2)); + builder.tx_start([1; 32], AccountId::from_u64(1), AccountId::from_u64(2)); builder.state_change(b"key1".to_vec(), None, Some(b"value1".to_vec())); builder.tx_end([1; 32], true, 100); builder.block_end(0, [0; 32]); builder.block_start(1, 2000); - builder.tx_start([2; 32], AccountId::new(2), AccountId::new(3)); + builder.tx_start([2; 32], AccountId::from_u64(2), AccountId::from_u64(3)); builder.state_change(b"key2".to_vec(), None, Some(b"value2".to_vec())); builder.tx_end([2; 32], true, 150); builder.block_end(1, [1; 32]); diff --git a/crates/testing/debugger/src/trace.rs b/crates/testing/debugger/src/trace.rs index 9743caa..a341cee 100644 --- a/crates/testing/debugger/src/trace.rs +++ b/crates/testing/debugger/src/trace.rs @@ -520,7 +520,7 @@ mod tests { let mut builder = TraceBuilder::new(42, StateSnapshot::empty()); builder.block_start(0, 1000); - builder.tx_start([1; 32], AccountId::new(1), AccountId::new(2)); + builder.tx_start([1; 32], AccountId::from_u64(1), AccountId::from_u64(2)); builder.state_change(b"key".to_vec(), None, Some(b"value".to_vec())); builder.tx_end([1; 32], true, 100); builder.block_end(0, [0; 32]);