diff --git a/Cargo.lock b/Cargo.lock index 642ab61c75d..bdb772e3da1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3342,23 +3342,12 @@ dependencies = [ [[package]] name = "near-account-id" -version = "0.0.0" +version = "1.0.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e328ed1bf9045c46595cc88274a46a6412e3a070c2ad3c146e2f94ed150a7c2" dependencies = [ - "arbitrary", - "bolero", "borsh 1.0.0", "serde", - "serde_json", -] - -[[package]] -name = "near-account-id-fuzz" -version = "0.0.0" -dependencies = [ - "borsh 1.0.0", - "libfuzzer-sys", - "near-account-id", - "serde_json", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5d61d9ad3dc..5c7d52eb4e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,8 +32,6 @@ members = [ "chain/rosetta-rpc", "chain/telemetry", "core/async", - "core/account-id", - "core/account-id/fuzz", "core/chain-configs", "core/crypto", "core/dyn-configs", @@ -176,7 +174,7 @@ lru = "0.7.2" memmap2 = "0.5" memoffset = "0.8" more-asserts = "0.2" -near-account-id = { path = "core/account-id", features = ["internal_unstable"] } +near-account-id = { version = "1.0.0-alpha.1", features = ["internal_unstable", "serde", "borsh"] } near-actix-test-utils = { path = "test-utils/actix-test-utils" } near-amend-genesis = { path = "tools/amend-genesis" } near-database-tool = { path = "tools/database" } diff --git a/chain/client/src/test_utils/test_env.rs b/chain/client/src/test_utils/test_env.rs index 2b2d4f5856d..6c8020ab9c4 100644 --- a/chain/client/src/test_utils/test_env.rs +++ b/chain/client/src/test_utils/test_env.rs @@ -435,8 +435,10 @@ impl TestEnv { relayer: AccountId, receiver_id: AccountId, ) -> SignedTransaction { - let inner_signer = InMemorySigner::from_seed(sender.clone(), KeyType::ED25519, &sender); - let relayer_signer = InMemorySigner::from_seed(relayer.clone(), KeyType::ED25519, &relayer); + let inner_signer = + InMemorySigner::from_seed(sender.clone(), KeyType::ED25519, sender.as_str()); + let relayer_signer = + InMemorySigner::from_seed(relayer.clone(), KeyType::ED25519, relayer.as_str()); let tip = self.clients[0].chain.head().unwrap(); let user_nonce = tip.height + 1; let relayer_nonce = tip.height + 1; diff --git a/chain/client/src/tests/bug_repros.rs b/chain/client/src/tests/bug_repros.rs index fa124e41e4e..5781c7b21dd 100644 --- a/chain/client/src/tests/bug_repros.rs +++ b/chain/client/src/tests/bug_repros.rs @@ -315,7 +315,7 @@ fn test_long_gap_between_blocks() { if approval_message.approval.target_height < target_height { (NetworkResponses::NoResponse.into(), false) } else { - if approval_message.target.as_ref() == "test1" { + if approval_message.target == "test1" { (NetworkResponses::NoResponse.into(), true) } else { (NetworkResponses::NoResponse.into(), false) diff --git a/chain/client/src/tests/catching_up.rs b/chain/client/src/tests/catching_up.rs index b7a15637621..bc39235fcbd 100644 --- a/chain/client/src/tests/catching_up.rs +++ b/chain/client/src/tests/catching_up.rs @@ -17,6 +17,7 @@ use near_network::types::{AccountIdOrPeerTrackingShard, PeerInfo}; use near_network::types::{NetworkRequests, NetworkResponses, PeerManagerMessageRequest}; use near_o11y::testonly::init_integration_logger; use near_o11y::WithSpanContextExt; +use near_primitives::account::id::AccountIdRef; use near_primitives::hash::{hash as hash_func, CryptoHash}; use near_primitives::network::PeerId; use near_primitives::receipt::Receipt; @@ -689,8 +690,8 @@ fn test_chunk_grieving() { let archive = vec![false; vs.all_block_producers().count()]; let epoch_sync_enabled = vec![true; vs.all_block_producers().count()]; - let malicious_node = "test3.6".parse().unwrap(); - let victim_node = "test3.5".parse().unwrap(); + let malicious_node = AccountIdRef::new_or_panic("test3.6"); + let victim_node = AccountIdRef::new_or_panic("test3.5"); let phase = Arc::new(RwLock::new(ChunkGrievingPhases::FirstAttack)); let grieving_chunk_hash = Arc::new(RwLock::new(ChunkHash::default())); let unaccepted_block_hash = Arc::new(RwLock::new(CryptoHash::default())); diff --git a/chain/epoch-manager/src/tests/mod.rs b/chain/epoch-manager/src/tests/mod.rs index 83470815584..1308dd6ce91 100644 --- a/chain/epoch-manager/src/tests/mod.rs +++ b/chain/epoch-manager/src/tests/mod.rs @@ -9,6 +9,7 @@ use crate::test_utils::{ record_with_block_info, reward, setup_default_epoch_manager, setup_epoch_manager, stake, DEFAULT_TOTAL_SUPPLY, }; +use near_primitives::account::id::AccountIdRef; use near_primitives::challenge::SlashedValidator; use near_primitives::epoch_manager::EpochConfig; use near_primitives::hash::hash; @@ -167,7 +168,7 @@ fn test_validator_change_of_stake() { ], ); matches!( - epoch_info.validator_kickout().get("test1"), + epoch_info.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(ValidatorKickoutReason::NotEnoughStake { stake: 10, .. }) ); } @@ -211,7 +212,7 @@ fn test_fork_finalization() { let block_producer_id = EpochManager::block_producer_from_info(&epoch_info, height); let block_producer = epoch_info.get_validator(block_producer_id); let account_id = block_producer.account_id(); - if validator_accounts.iter().any(|v| *v == account_id.as_ref()) { + if validator_accounts.iter().any(|v| *v == account_id) { record_block(epoch_manager, prev_block, *curr_block, height, vec![]); prev_block = *curr_block; branch_blocks.push(*curr_block); @@ -332,10 +333,10 @@ fn test_validator_kickout() { let height = i as u64; let epoch_id = epoch_manager.get_epoch_id_from_prev_block(&prev_block).unwrap(); let block_producer = epoch_manager.get_block_producer_info(&epoch_id, height).unwrap(); - if block_producer.account_id().as_ref() == "test2" && epoch_id == init_epoch_id { + if block_producer.account_id() == "test2" && epoch_id == init_epoch_id { // test2 skips its blocks in the first epoch test2_expected_blocks += 1; - } else if block_producer.account_id().as_ref() == "test1" && epoch_id != init_epoch_id { + } else if block_producer.account_id() == "test1" && epoch_id != init_epoch_id { // test1 skips its blocks in subsequent epochs () } else { @@ -733,8 +734,8 @@ fn test_validator_reward_one_validator() { PROTOCOL_VERSION, epoch_length * NUM_NS_IN_SECOND, ); - let test2_reward = *validator_reward.get("test2").unwrap(); - let protocol_reward = *validator_reward.get("near").unwrap(); + let test2_reward = *validator_reward.get(AccountIdRef::new_or_panic("test2")).unwrap(); + let protocol_reward = *validator_reward.get(AccountIdRef::new_or_panic("near")).unwrap(); let epoch_info = epoch_manager.get_epoch_info(&EpochId(h[2])).unwrap(); check_validators(&epoch_info, &[("test2", stake_amount + test2_reward)]); @@ -831,10 +832,10 @@ fn test_validator_reward_weight_by_stake() { PROTOCOL_VERSION, epoch_length * NUM_NS_IN_SECOND, ); - let test1_reward = *validator_reward.get("test1").unwrap(); - let test2_reward = *validator_reward.get("test2").unwrap(); + let test1_reward = *validator_reward.get(AccountIdRef::new_or_panic("test1")).unwrap(); + let test2_reward = *validator_reward.get(AccountIdRef::new_or_panic("test2")).unwrap(); assert_eq!(test1_reward, test2_reward * 2); - let protocol_reward = *validator_reward.get("near").unwrap(); + let protocol_reward = *validator_reward.get(AccountIdRef::new_or_panic("near")).unwrap(); let epoch_info = epoch_manager.get_epoch_info(&EpochId(h[2])).unwrap(); check_validators( @@ -915,9 +916,7 @@ fn test_reward_multiple_shards() { let expected_chunk_producer = epoch_manager .get_chunk_producer_info(&epoch_id, height, shard_index as u64) .unwrap(); - if expected_chunk_producer.account_id().as_ref() == "test1" - && epoch_id == init_epoch_id - { + if expected_chunk_producer.account_id() == "test1" && epoch_id == init_epoch_id { expected_chunks += 1; false } else { @@ -949,8 +948,8 @@ fn test_reward_multiple_shards() { PROTOCOL_VERSION, epoch_length * NUM_NS_IN_SECOND, ); - let test2_reward = *validator_reward.get("test2").unwrap(); - let protocol_reward = *validator_reward.get("near").unwrap(); + let test2_reward = *validator_reward.get(AccountIdRef::new_or_panic("test2")).unwrap(); + let protocol_reward = *validator_reward.get(AccountIdRef::new_or_panic("near")).unwrap(); let epoch_infos: Vec<_> = h.iter().filter_map(|x| epoch_manager.get_epoch_info(&EpochId(*x)).ok()).collect(); let epoch_info = &epoch_infos[1]; @@ -1371,7 +1370,7 @@ fn count_missing_blocks( let mut result = ValidatorStats { produced: 0, expected: 0 }; for h in height_range { let block_producer = epoch_manager.get_block_producer_info(epoch_id, h).unwrap(); - if validator == block_producer.account_id().as_ref() { + if validator == block_producer.account_id() { if produced_heights.contains(&h) { result.produced += 1; } @@ -1627,8 +1626,14 @@ fn test_fishermen_unstake() { ], ); let kickout = epoch_info.validator_kickout(); - assert_eq!(kickout.get("test2").unwrap(), &ValidatorKickoutReason::Unstaked); - matches!(kickout.get("test3"), Some(ValidatorKickoutReason::NotEnoughStake { .. })); + assert_eq!( + kickout.get(AccountIdRef::new_or_panic("test2")).unwrap(), + &ValidatorKickoutReason::Unstaked + ); + matches!( + kickout.get(AccountIdRef::new_or_panic("test3")), + Some(ValidatorKickoutReason::NotEnoughStake { .. }) + ); } #[test] @@ -1711,7 +1716,7 @@ fn test_kickout_set() { let epoch_info1 = epoch_manager.get_epoch_info(&EpochId(h[2])).unwrap(); assert_eq!( epoch_info1.validators_iter().map(|r| r.account_id().clone()).collect::>(), - vec!["test1".parse().unwrap()] + vec!["test1"] ); assert_eq!( epoch_info1.stake_change().clone(), @@ -1798,15 +1803,15 @@ fn test_unstake_slash() { let epoch_info3 = epoch_manager.get_epoch_info(&EpochId(h[3])).unwrap(); let epoch_info4 = epoch_manager.get_epoch_info(&EpochId(h[4])).unwrap(); assert_eq!( - epoch_info1.validator_kickout().get("test1"), + epoch_info1.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(&ValidatorKickoutReason::Unstaked) ); assert_eq!( - epoch_info2.validator_kickout().get("test1"), + epoch_info2.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(&ValidatorKickoutReason::Slashed) ); assert_eq!( - epoch_info3.validator_kickout().get("test1"), + epoch_info3.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(&ValidatorKickoutReason::Slashed) ); assert!(epoch_info4.validator_kickout().is_empty()); @@ -1848,15 +1853,15 @@ fn test_no_unstake_slash() { let epoch_info3 = epoch_manager.get_epoch_info(&EpochId(h[3])).unwrap(); let epoch_info4 = epoch_manager.get_epoch_info(&EpochId(h[4])).unwrap(); assert_eq!( - epoch_info1.validator_kickout().get("test1"), + epoch_info1.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(&ValidatorKickoutReason::Slashed) ); assert_eq!( - epoch_info2.validator_kickout().get("test1"), + epoch_info2.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(&ValidatorKickoutReason::Slashed) ); assert_eq!( - epoch_info3.validator_kickout().get("test1"), + epoch_info3.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(&ValidatorKickoutReason::Slashed) ); assert!(epoch_info4.validator_kickout().is_empty()); @@ -1900,16 +1905,16 @@ fn test_slash_non_validator() { let epoch_info4 = epoch_manager.get_epoch_info(&EpochId(h[4])).unwrap(); // Slashed let epoch_info5 = epoch_manager.get_epoch_info(&EpochId(h[5])).unwrap(); // Ok assert_eq!( - epoch_info1.validator_kickout().get("test1"), + epoch_info1.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(&ValidatorKickoutReason::Unstaked) ); assert!(epoch_info2.validator_kickout().is_empty()); assert_eq!( - epoch_info3.validator_kickout().get("test1"), + epoch_info3.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(&ValidatorKickoutReason::Slashed) ); assert_eq!( - epoch_info4.validator_kickout().get("test1"), + epoch_info4.validator_kickout().get(AccountIdRef::new_or_panic("test1")), Some(&ValidatorKickoutReason::Slashed) ); assert!(epoch_info5.validator_kickout().is_empty()); @@ -1952,9 +1957,9 @@ fn test_slash_restake() { vec![stake("test1".parse().unwrap(), stake_amount)], ); let epoch_info2 = epoch_manager.get_epoch_info(&EpochId(h[2])).unwrap(); - assert!(epoch_info2.stake_change().get("test1").is_none()); + assert!(epoch_info2.stake_change().get(AccountIdRef::new_or_panic("test1")).is_none()); let epoch_info4 = epoch_manager.get_epoch_info(&EpochId(h[4])).unwrap(); - assert!(epoch_info4.stake_change().get("test1").is_some()); + assert!(epoch_info4.stake_change().get(AccountIdRef::new_or_panic("test1")).is_some()); } #[test] @@ -1979,7 +1984,7 @@ fn test_all_kickout_edge_case() { let block_producer = epoch_info.validator_account_id(block_producer); if height < EPOCH_LENGTH { // kickout test2 during first epoch - if block_producer.as_ref() == "test1" || block_producer.as_ref() == "test3" { + if block_producer == "test1" || block_producer == "test3" { record_block(&mut epoch_manager, prev_block, *curr_block, height, Vec::new()); prev_block = *curr_block; } @@ -2018,7 +2023,7 @@ fn check_validators(epoch_info: &EpochInfo, expected_validators: &[(&str, u128)] for (v, (account_id, stake)) in epoch_info.validators_iter().zip(expected_validators.into_iter()) { - assert_eq!(v.account_id().as_ref(), *account_id); + assert_eq!(v.account_id(), *account_id); assert_eq!(v.stake(), *stake); } } @@ -2026,7 +2031,7 @@ fn check_validators(epoch_info: &EpochInfo, expected_validators: &[(&str, u128)] fn check_fishermen(epoch_info: &EpochInfo, expected_fishermen: &[(&str, u128)]) { for (v, (account_id, stake)) in epoch_info.fishermen_iter().zip(expected_fishermen.into_iter()) { - assert_eq!(v.account_id().as_ref(), *account_id); + assert_eq!(v.account_id(), *account_id); assert_eq!(v.stake(), *stake); } } diff --git a/chain/epoch-manager/src/validator_selection.rs b/chain/epoch-manager/src/validator_selection.rs index 41499687e22..ebbbbdcf533 100644 --- a/chain/epoch-manager/src/validator_selection.rs +++ b/chain/epoch-manager/src/validator_selection.rs @@ -362,6 +362,7 @@ impl Ord for OrderedValidatorStake { mod tests { use super::*; use near_crypto::{KeyType, PublicKey}; + use near_primitives::account::id::AccountIdRef; use near_primitives::epoch_manager::epoch_info::{EpochInfo, EpochInfoV3}; use near_primitives::epoch_manager::ValidatorSelectionConfig; use near_primitives::shard_layout::ShardLayout; @@ -496,11 +497,11 @@ mod tests { let kickout = epoch_info.validator_kickout(); assert_eq!(kickout.len(), 2); assert_eq!( - kickout.get("test1").unwrap(), + kickout.get(AccountIdRef::new_or_panic("test1")).unwrap(), &ValidatorKickoutReason::NotEnoughStake { stake: test1_stake, threshold: 2011 }, ); assert_eq!( - kickout.get("test2").unwrap(), + kickout.get(AccountIdRef::new_or_panic("test2")).unwrap(), &ValidatorKickoutReason::NotEnoughStake { stake: 2002, threshold: 2011 }, ); } @@ -663,7 +664,7 @@ mod tests { // stake below validator threshold, but above fishermen threshold become fishermen let fishermen: Vec<_> = epoch_info.fishermen_iter().map(|v| v.take_account_id()).collect(); - assert_eq!(fishermen, vec!["test4".parse().unwrap()]); + assert_eq!(fishermen, vec!["test4"]); // too low stakes are kicked out let kickout = epoch_info.validator_kickout(); @@ -673,11 +674,11 @@ mod tests { #[cfg(not(feature = "protocol_feature_fix_staking_threshold"))] let expected_threshold = 300; assert_eq!( - kickout.get("test5").unwrap(), + kickout.get(AccountIdRef::new_or_panic("test5")).unwrap(), &ValidatorKickoutReason::NotEnoughStake { stake: 100, threshold: expected_threshold }, ); assert_eq!( - kickout.get("test6").unwrap(), + kickout.get(AccountIdRef::new_or_panic("test6")).unwrap(), &ValidatorKickoutReason::NotEnoughStake { stake: 50, threshold: expected_threshold }, ); diff --git a/chain/jsonrpc/jsonrpc-tests/tests/rpc_query.rs b/chain/jsonrpc/jsonrpc-tests/tests/rpc_query.rs index 89fe598db60..9065667b816 100644 --- a/chain/jsonrpc/jsonrpc-tests/tests/rpc_query.rs +++ b/chain/jsonrpc/jsonrpc-tests/tests/rpc_query.rs @@ -24,7 +24,7 @@ use near_jsonrpc_tests::{self as test_utils, test_with_client}; fn test_block_by_id_height() { test_with_client!(test_utils::NodeType::NonValidator, client, async move { let block = client.block_by_id(BlockId::Height(0)).await.unwrap(); - assert_eq!(block.author, "test1".parse().unwrap()); + assert_eq!(block.author, "test1"); assert_eq!(block.header.height, 0); assert_eq!(block.header.epoch_id.0.as_ref(), &[0; 32]); assert_eq!(block.header.hash.0.as_ref().len(), 32); @@ -69,7 +69,7 @@ fn test_block_query() { for block in &[block_response1, block_response2, block_response3, block_response4, block_response5] { - assert_eq!(block.author, "test1".parse().unwrap()); + assert_eq!(block.author, "test1"); assert_eq!(block.header.height, 0); assert_eq!(block.header.epoch_id.as_ref(), &[0; 32]); assert_eq!(block.header.hash.as_ref().len(), 32); @@ -89,7 +89,7 @@ fn test_block_query() { fn test_chunk_by_hash() { test_with_client!(test_utils::NodeType::NonValidator, client, async move { let chunk = client.chunk(ChunkId::BlockShardId(BlockId::Height(0), 0u64)).await.unwrap(); - assert_eq!(chunk.author, "test1".parse().unwrap()); + assert_eq!(chunk.author, "test1"); assert_eq!(chunk.header.balance_burnt, 0); assert_eq!(chunk.header.chunk_hash.as_ref().len(), 32); assert_eq!(chunk.header.encoded_length, 8); @@ -454,7 +454,7 @@ fn test_validators_ordered() { .unwrap(); assert_eq!( validators.into_iter().map(|v| v.take_account_id()).collect::>(), - vec!["test1".parse().unwrap()] + vec!["test1"] ) }); } @@ -560,7 +560,7 @@ fn test_get_chunk_with_object_in_params() { ) .await .unwrap(); - assert_eq!(chunk.author, "test1".parse().unwrap()); + assert_eq!(chunk.author, "test1"); assert_eq!(chunk.header.balance_burnt, 0); assert_eq!(chunk.header.chunk_hash.as_ref().len(), 32); assert_eq!(chunk.header.encoded_length, 8); diff --git a/chain/network/src/store/schema/mod.rs b/chain/network/src/store/schema/mod.rs index 9eb3173fd91..dbc153f1257 100644 --- a/chain/network/src/store/schema/mod.rs +++ b/chain/network/src/store/schema/mod.rs @@ -20,7 +20,7 @@ pub struct AccountIdFormat; impl Format for AccountIdFormat { type T = AccountId; fn encode(a: &AccountId, w: &mut W) -> io::Result<()> { - w.write_all(a.as_ref().as_bytes()) + w.write_all(a.as_bytes()) } fn decode(a: &[u8]) -> Result { std::str::from_utf8(a).map_err(invalid_data)?.parse().map_err(invalid_data) diff --git a/chain/pool/src/lib.rs b/chain/pool/src/lib.rs index 3d5e6fd3395..79a3efe7162 100644 --- a/chain/pool/src/lib.rs +++ b/chain/pool/src/lib.rs @@ -74,7 +74,7 @@ impl TransactionPool { fn key(&self, account_id: &AccountId, public_key: &PublicKey) -> PoolKey { let mut v = borsh::to_vec(&public_key).unwrap(); v.extend_from_slice(&self.key_seed); - v.extend_from_slice(account_id.as_ref().as_bytes()); + v.extend_from_slice(account_id.as_bytes()); hash(&v) } diff --git a/core/account-id/Cargo.toml b/core/account-id/Cargo.toml deleted file mode 100644 index fe68a0bff7f..00000000000 --- a/core/account-id/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "near-account-id" -version.workspace = true -authors.workspace = true -edition.workspace = true -# This crate is published to crates.io with a semver API. Care must be taken -# when updaing its rust-version. -rust-version = "1.63.0" -description = "This crate contains the Account ID primitive and its validation facilities" -repository.workspace = true -license.workspace = true -publish = true - -[features] -default = ["borsh", "serde"] -internal_unstable = [] - -[dependencies] -arbitrary = { workspace = true, optional = true } -borsh = { workspace = true, optional = true } -serde = { workspace = true, optional = true } - -[dev-dependencies] -bolero.workspace = true -serde_json.workspace = true diff --git a/core/account-id/LICENSE-APACHE b/core/account-id/LICENSE-APACHE deleted file mode 120000 index 0eb30ff1b50..00000000000 --- a/core/account-id/LICENSE-APACHE +++ /dev/null @@ -1 +0,0 @@ -../../licenses/LICENSE-APACHE \ No newline at end of file diff --git a/core/account-id/LICENSE-MIT b/core/account-id/LICENSE-MIT deleted file mode 120000 index df3ae884029..00000000000 --- a/core/account-id/LICENSE-MIT +++ /dev/null @@ -1 +0,0 @@ -../../licenses/LICENSE-MIT \ No newline at end of file diff --git a/core/account-id/README.md b/core/account-id/README.md deleted file mode 100644 index f91c54dd4ae..00000000000 --- a/core/account-id/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# near-account-id - -This crate provides a type for representing a syntactically valid, unique account identifier on the [NEAR](https://near.org) network, according to the [NEAR Account ID](https://docs.near.org/concepts/basics/account#account-id-rules) rules. - -[![crates.io](https://img.shields.io/crates/v/near-account-id?label=latest)](https://crates.io/crates/near-account-id) -[![Documentation](https://docs.rs/near-account-id/badge.svg)](https://docs.rs/near-account-id) -![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/near-account-id.svg) - -## Usage - -```rust -use near_account_id::AccountId; - -let alice: AccountId = "alice.near".parse()?; - -assert!("ƒelicia.near".parse::().is_err()); // (ƒ is not f) -``` - -See the [docs](https://docs.rs/near-account-id) for more information. - -## License - -Licensed under either of - -- Apache License, Version 2.0 - ([LICENSE-APACHE](LICENSE-APACHE) or ) -- MIT license - ([LICENSE-MIT](LICENSE-MIT) or ) - -at your option. - -## Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. diff --git a/core/account-id/fuzz/.gitignore b/core/account-id/fuzz/.gitignore deleted file mode 100644 index 572e03bdf32..00000000000 --- a/core/account-id/fuzz/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ - -target -corpus -artifacts diff --git a/core/account-id/fuzz/Cargo.toml b/core/account-id/fuzz/Cargo.toml deleted file mode 100644 index bdfaa4ad7a6..00000000000 --- a/core/account-id/fuzz/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "near-account-id-fuzz" -version.workspace = true -authors.workspace = true -edition.workspace = true -rust-version.workspace = true -repository.workspace = true -license.workspace = true -publish = false - -[package.metadata] -cargo-fuzz = true - -[dependencies] -libfuzzer-sys.workspace = true -borsh.workspace = true -serde_json.workspace = true -near-account-id.workspace = true - -[[bin]] -name = "serde" -path = "fuzz_targets/serde.rs" -test = false -doc = false - -[[bin]] -name = "borsh" -path = "fuzz_targets/borsh.rs" -test = false -doc = false diff --git a/core/account-id/fuzz/README.md b/core/account-id/fuzz/README.md deleted file mode 100644 index 4a1e7901fdc..00000000000 --- a/core/account-id/fuzz/README.md +++ /dev/null @@ -1,26 +0,0 @@ -## Fuzzing `near-account-id` - -### Setup - -First, ensure [`cargo-fuzz`](https://github.com/rust-fuzz/cargo-fuzz) is installed: - -```console -cargo install cargo-fuzz -``` - -### Execution - -Finally, there are two fuzzing targets available: one for [`serde`](https://github.com/serde-rs/serde) and another for [`borsh`](https://github.com/near/borsh-rs). You can run both tests with: - -```console -cd core/account-id/fuzz -RUSTC_BOOTSTRAP=1 cargo fuzz run serde -RUSTC_BOOTSTRAP=1 cargo fuzz run borsh -``` - -By default each fuzz test runs infinitely. To specify how many runs each test is allowed, you can use this: - -```console -RUSTC_BOOTSTRAP=1 cargo fuzz run serde -runs=1000000000 -RUSTC_BOOTSTRAP=1 cargo fuzz run borsh -runs=1000000000 -``` diff --git a/core/account-id/fuzz/fuzz_targets/borsh.rs b/core/account-id/fuzz/fuzz_targets/borsh.rs deleted file mode 100644 index 1173fd2f43b..00000000000 --- a/core/account-id/fuzz/fuzz_targets/borsh.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![no_main] - -use borsh::BorshDeserialize; -use libfuzzer_sys::fuzz_target; -use near_account_id::AccountId; - -fuzz_target!(|bytes: &[u8]| { - if let Ok(account_id) = AccountId::try_from_slice(bytes) { - assert_eq!( - account_id, - AccountId::try_from_slice(borsh::to_vec(&account_id).unwrap().as_slice()).unwrap() - ); - } -}); diff --git a/core/account-id/fuzz/fuzz_targets/serde.rs b/core/account-id/fuzz/fuzz_targets/serde.rs deleted file mode 100644 index 97e57e90511..00000000000 --- a/core/account-id/fuzz/fuzz_targets/serde.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![no_main] - -use std::str; - -use libfuzzer_sys::fuzz_target; -use near_account_id::AccountId; -use serde_json::json; - -fuzz_target!(|bytes: &[u8]| { - if let Ok(account_id) = str::from_utf8(bytes) { - if let Ok(account_id) = serde_json::from_value::(json!(account_id)) { - assert_eq!( - account_id, - serde_json::from_value(serde_json::to_value(&account_id).unwrap()).unwrap() - ); - } - } -}); diff --git a/core/account-id/src/borsh.rs b/core/account-id/src/borsh.rs deleted file mode 100644 index 8e0d6e7da5a..00000000000 --- a/core/account-id/src/borsh.rs +++ /dev/null @@ -1,78 +0,0 @@ -use super::AccountId; - -use std::io::{Read, Write}; - -use borsh::{BorshDeserialize, BorshSerialize}; - -impl BorshSerialize for AccountId { - fn serialize(&self, writer: &mut W) -> std::io::Result<()> { - self.0.serialize(writer) - } -} - -impl BorshDeserialize for AccountId { - fn deserialize_reader(rd: &mut R) -> std::io::Result { - let account_id = Box::::deserialize_reader(rd)?; - Self::validate(&account_id).map_err(|err| { - std::io::Error::new( - std::io::ErrorKind::InvalidData, - format!("invalid value: \"{}\", {}", account_id, err), - ) - })?; - Ok(Self(account_id)) - } -} - -#[cfg(test)] -mod tests { - use super::{ - super::tests::{BAD_ACCOUNT_IDS, OK_ACCOUNT_IDS}, - *, - }; - - #[test] - fn test_is_valid_account_id() { - for account_id in OK_ACCOUNT_IDS.iter() { - let parsed_account_id = account_id.parse::().unwrap_or_else(|err| { - panic!("Valid account id {:?} marked invalid: {}", account_id, err) - }); - - let str_serialized_account_id = borsh::to_vec(&account_id).unwrap(); - - let deserialized_account_id = AccountId::try_from_slice(&str_serialized_account_id) - .unwrap_or_else(|err| { - panic!("failed to deserialize account ID {:?}: {}", account_id, err) - }); - assert_eq!(deserialized_account_id, parsed_account_id); - - let serialized_account_id = - borsh::to_vec(&deserialized_account_id).unwrap_or_else(|err| { - panic!("failed to serialize account ID {:?}: {}", account_id, err) - }); - assert_eq!(serialized_account_id, str_serialized_account_id); - } - - for account_id in BAD_ACCOUNT_IDS.iter() { - let str_serialized_account_id = borsh::to_vec(&account_id).unwrap(); - - assert!( - AccountId::try_from_slice(&str_serialized_account_id).is_err(), - "successfully deserialized invalid account ID {:?}", - account_id - ); - } - } - - #[test] - fn fuzz() { - bolero::check!().for_each(|input: &[u8]| { - if let Ok(account_id) = AccountId::try_from_slice(input) { - assert_eq!( - account_id, - AccountId::try_from_slice(borsh::to_vec(&account_id).unwrap().as_slice()) - .unwrap() - ); - } - }); - } -} diff --git a/core/account-id/src/errors.rs b/core/account-id/src/errors.rs deleted file mode 100644 index ae2f443869b..00000000000 --- a/core/account-id/src/errors.rs +++ /dev/null @@ -1,67 +0,0 @@ -use std::fmt; -use std::fmt::Write; - -/// An error which can be returned when parsing a NEAR Account ID. -#[derive(Eq, Clone, Debug, PartialEq)] -pub struct ParseAccountError { - pub(crate) kind: ParseErrorKind, - pub(crate) char: Option<(usize, char)>, -} - -impl ParseAccountError { - /// Returns the specific cause why parsing the Account ID failed. - pub fn kind(&self) -> &ParseErrorKind { - &self.kind - } -} - -impl std::error::Error for ParseAccountError {} -impl fmt::Display for ParseAccountError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut buf = self.kind.to_string(); - if let Some((idx, char)) = self.char { - write!(buf, " {:?} at index {}", char, idx)? - } - buf.fmt(f) - } -} - -/// A list of errors that occur when parsing an invalid Account ID. -/// -/// Also see [Error kind precedence](crate::AccountId#error-kind-precedence). -#[non_exhaustive] -#[derive(Eq, Clone, Debug, PartialEq)] -pub enum ParseErrorKind { - /// The Account ID is too long. - /// - /// Returned if the `AccountId` is longer than [`AccountId::MAX_LEN`](crate::AccountId::MAX_LEN). - TooLong, - /// The Account ID is too short. - /// - /// Returned if the `AccountId` is shorter than [`AccountId::MIN_LEN`](crate::AccountId::MIN_LEN). - TooShort, - /// The Account ID has a redundant separator. - /// - /// This variant would be returned if the Account ID either begins with, - /// ends with or has separators immediately following each other. - /// - /// Cases: `jane.`, `angela__moss`, `tyrell..wellick` - RedundantSeparator, - /// The Account ID contains an invalid character. - /// - /// This variant would be returned if the Account ID contains an upper-case character, non-separating symbol or space. - /// - /// Cases: `ƒelicia.near`, `user@app.com`, `Emily.near`. - InvalidChar, -} - -impl fmt::Display for ParseErrorKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - ParseErrorKind::TooLong => "the Account ID is too long".fmt(f), - ParseErrorKind::TooShort => "the Account ID is too short".fmt(f), - ParseErrorKind::RedundantSeparator => "the Account ID has a redundant separator".fmt(f), - ParseErrorKind::InvalidChar => "the Account ID contains an invalid character".fmt(f), - } - } -} diff --git a/core/account-id/src/lib.rs b/core/account-id/src/lib.rs deleted file mode 100644 index 196232f03b8..00000000000 --- a/core/account-id/src/lib.rs +++ /dev/null @@ -1,744 +0,0 @@ -//! This crate provides a type for representing a syntactically valid, unique account identifier on the [NEAR](https://near.org) network. -//! -//! ## Account ID Rules -//! -//! - Minimum length is `2` -//! - Maximum length is `64` -//! - An **Account ID** consists of **Account ID parts** separated by `.`, example: -//! - `root` ✔ -//! - `alice.near` ✔ -//! - `app.stage.testnet` ✔ -//! - Must not start or end with separators (`_`, `-` or `.`): -//! - `_alice.` ✗ -//! - `.bob.near-` ✗ -//! - Each part of the **Account ID** consists of lowercase alphanumeric symbols separated either by `_` or `-`, example: -//! - `ƒelicia.near` ✗ (`ƒ` is not `f`) -//! - `1_4m_n0t-al1c3.near` ✔ -//! - Separators are not permitted to immediately follow each other, example: -//! - `alice..near` ✗ -//! - `not-_alice.near` ✗ -//! - An **Account ID** that is 64 characters long and consists of lowercase hex characters is a specific **implicit account ID** -//! -//! Learn more here: -//! -//! Also see [Error kind precedence](AccountId#error-kind-precedence). -//! -//! ## Usage -//! -//! ``` -//! use near_account_id::AccountId; -//! -//! let alice: AccountId = "alice.near".parse().unwrap(); -//! -//! assert!("ƒelicia.near".parse::().is_err()); // (ƒ is not f) -//! ``` - -use std::{fmt, str::FromStr}; - -mod errors; - -#[cfg(feature = "borsh")] -mod borsh; -#[cfg(feature = "serde")] -mod serde; - -pub use errors::{ParseAccountError, ParseErrorKind}; - -/// NEAR Account Identifier. -/// -/// This is a unique, syntactically valid, human-readable account identifier on the NEAR network. -/// -/// [See the crate-level docs for information about validation.](index.html#account-id-rules) -/// -/// Also see [Error kind precedence](AccountId#error-kind-precedence). -/// -/// ## Examples -/// -/// ``` -/// use near_account_id::AccountId; -/// -/// let alice: AccountId = "alice.near".parse().unwrap(); -/// -/// assert!("ƒelicia.near".parse::().is_err()); // (ƒ is not f) -/// ``` -#[derive(Eq, Ord, Hash, Clone, Debug, PartialEq, PartialOrd)] -pub struct AccountId(Box); - -impl AccountId { - /// Shortest valid length for a NEAR Account ID. - pub const MIN_LEN: usize = 2; - /// Longest valid length for a NEAR Account ID. - pub const MAX_LEN: usize = 64; - - /// Returns a string slice of the entire Account ID. - /// - /// ## Examples - /// - /// ``` - /// use near_account_id::AccountId; - /// - /// let carol: AccountId = "carol.near".parse().unwrap(); - /// assert_eq!("carol.near", carol.as_str()); - /// ``` - pub fn as_str(&self) -> &str { - self - } - - /// Returns `true` if the `AccountId` is a top-level NEAR Account ID. - /// - /// See [Top-level Accounts](https://docs.near.org/docs/concepts/account#top-level-accounts). - /// - /// ## Examples - /// - /// ``` - /// use near_account_id::AccountId; - /// - /// let near_tla: AccountId = "near".parse().unwrap(); - /// assert!(near_tla.is_top_level()); - /// - /// // "alice.near" is a sub account of "near" account - /// let alice: AccountId = "alice.near".parse().unwrap(); - /// assert!(!alice.is_top_level()); - /// ``` - pub fn is_top_level(&self) -> bool { - !self.is_system() && !self.contains('.') - } - - /// Returns `true` if the `AccountId` is a direct sub-account of the provided parent account. - /// - /// See [Subaccounts](https://docs.near.org/docs/concepts/account#subaccounts). - /// - /// ## Examples - /// - /// ``` - /// use near_account_id::AccountId; - /// - /// let near_tla: AccountId = "near".parse().unwrap(); - /// assert!(near_tla.is_top_level()); - /// - /// let alice: AccountId = "alice.near".parse().unwrap(); - /// assert!(alice.is_sub_account_of(&near_tla)); - /// - /// let alice_app: AccountId = "app.alice.near".parse().unwrap(); - /// - /// // While app.alice.near is a sub account of alice.near, - /// // app.alice.near is not a sub account of near - /// assert!(alice_app.is_sub_account_of(&alice)); - /// assert!(!alice_app.is_sub_account_of(&near_tla)); - /// ``` - pub fn is_sub_account_of(&self, parent: &AccountId) -> bool { - self.strip_suffix(parent.as_str()) - .and_then(|s| s.strip_suffix('.')) - .map_or(false, |s| !s.contains('.')) - } - - /// Returns `true` if the `AccountId` is a 64 characters long hexadecimal. - /// - /// See [Implicit-Accounts](https://docs.near.org/docs/concepts/account#implicit-accounts). - /// - /// ## Examples - /// - /// ``` - /// use near_account_id::AccountId; - /// - /// let alice: AccountId = "alice.near".parse().unwrap(); - /// assert!(!alice.is_implicit()); - /// - /// let rando = "98793cd91a3f870fb126f66285808c7e094afcfc4eda8a970f6648cdf0dbd6de" - /// .parse::() - /// .unwrap(); - /// assert!(rando.is_implicit()); - /// ``` - pub fn is_implicit(&self) -> bool { - self.len() == 64 && self.as_bytes().iter().all(|b| matches!(b, b'a'..=b'f' | b'0'..=b'9')) - } - - /// Returns `true` if this `AccountId` is the system account. - /// - /// See [System account](https://nomicon.io/DataStructures/Account.html?highlight=system#system-account). - /// - /// ## Examples - /// - /// ``` - /// use near_account_id::AccountId; - /// - /// let alice: AccountId = "alice.near".parse().unwrap(); - /// assert!(!alice.is_system()); - /// - /// let system: AccountId = "system".parse().unwrap(); - /// assert!(system.is_system()); - /// ``` - pub fn is_system(&self) -> bool { - self.as_str() == "system" - } - - /// Validates a string as a well-structured NEAR Account ID. - /// - /// Checks Account ID validity without constructing an `AccountId` instance. - /// - /// ## Examples - /// - /// ``` - /// use near_account_id::{AccountId, ParseErrorKind}; - /// - /// assert!(AccountId::validate("alice.near").is_ok()); - /// - /// assert!( - /// matches!( - /// AccountId::validate("ƒelicia.near"), // fancy ƒ! - /// Err(err) if err.kind() == &ParseErrorKind::InvalidChar - /// ) - /// ); - /// ``` - /// - /// ## Error kind precedence - /// - /// If an Account ID has multiple format violations, the first one would be reported. - /// - /// ### Examples - /// - /// ``` - /// use near_account_id::{AccountId, ParseErrorKind}; - /// - /// assert!( - /// matches!( - /// AccountId::validate("A__ƒƒluent."), - /// Err(err) if err.kind() == &ParseErrorKind::InvalidChar - /// ) - /// ); - /// - /// assert!( - /// matches!( - /// AccountId::validate("a__ƒƒluent."), - /// Err(err) if err.kind() == &ParseErrorKind::RedundantSeparator - /// ) - /// ); - /// - /// assert!( - /// matches!( - /// AccountId::validate("aƒƒluent."), - /// Err(err) if err.kind() == &ParseErrorKind::InvalidChar - /// ) - /// ); - /// - /// assert!( - /// matches!( - /// AccountId::validate("affluent."), - /// Err(err) if err.kind() == &ParseErrorKind::RedundantSeparator - /// ) - /// ); - /// ``` - pub fn validate(account_id: &str) -> Result<(), ParseAccountError> { - if account_id.len() < AccountId::MIN_LEN { - Err(ParseAccountError { kind: ParseErrorKind::TooShort, char: None }) - } else if account_id.len() > AccountId::MAX_LEN { - Err(ParseAccountError { kind: ParseErrorKind::TooLong, char: None }) - } else { - // Adapted from https://github.com/near/near-sdk-rs/blob/fd7d4f82d0dfd15f824a1cf110e552e940ea9073/near-sdk/src/environment/env.rs#L819 - - // NOTE: We don't want to use Regex here, because it requires extra time to compile it. - // The valid account ID regex is /^(([a-z\d]+[-_])*[a-z\d]+\.)*([a-z\d]+[-_])*[a-z\d]+$/ - // Instead the implementation is based on the previous character checks. - - // We can safely assume that last char was a separator. - let mut last_char_is_separator = true; - - let mut this = None; - for (i, c) in account_id.chars().enumerate() { - this.replace((i, c)); - let current_char_is_separator = match c { - 'a'..='z' | '0'..='9' => false, - '-' | '_' | '.' => true, - _ => { - return Err(ParseAccountError { - kind: ParseErrorKind::InvalidChar, - char: this, - }); - } - }; - if current_char_is_separator && last_char_is_separator { - return Err(ParseAccountError { - kind: ParseErrorKind::RedundantSeparator, - char: this, - }); - } - last_char_is_separator = current_char_is_separator; - } - - if last_char_is_separator { - return Err(ParseAccountError { - kind: ParseErrorKind::RedundantSeparator, - char: this, - }); - } - Ok(()) - } - } - - /// Creates an `AccountId` without any validation checks. - /// - /// Please note that this is restrictively for internal use only. Plus, being behind a feature flag, - /// this could be removed later in the future. - /// - /// ## Safety - /// - /// Since this skips validation and constructs an `AccountId` regardless, - /// the caller bears the responsibility of ensuring that the Account ID is valid. - /// You can use the [`AccountId::validate`] function sometime after its creation but before it's use. - /// - /// ## Examples - /// - /// ``` - /// use near_account_id::AccountId; - /// - /// let alice = AccountId::new_unvalidated("alice.near".to_string()); - /// assert!(AccountId::validate(alice.as_str()).is_ok()); - /// - /// let ƒelicia = AccountId::new_unvalidated("ƒelicia.near".to_string()); - /// assert!(AccountId::validate(ƒelicia.as_str()).is_err()); - /// ``` - #[doc(hidden)] - #[cfg(feature = "internal_unstable")] - #[deprecated = "AccountId construction without validation is illegal since #4440"] - pub fn new_unvalidated(account_id: String) -> Self { - Self(account_id.into_boxed_str()) - } -} - -impl std::ops::Deref for AccountId { - type Target = str; - - fn deref(&self) -> &Self::Target { - self.0.as_ref() - } -} - -impl AsRef for AccountId { - fn as_ref(&self) -> &str { - self - } -} - -impl std::borrow::Borrow for AccountId { - fn borrow(&self) -> &str { - self - } -} - -impl FromStr for AccountId { - type Err = ParseAccountError; - - fn from_str(account_id: &str) -> Result { - Self::validate(account_id)?; - Ok(Self(account_id.into())) - } -} - -impl TryFrom> for AccountId { - type Error = ParseAccountError; - - fn try_from(account_id: Box) -> Result { - Self::validate(&account_id)?; - Ok(Self(account_id)) - } -} - -impl TryFrom for AccountId { - type Error = ParseAccountError; - - fn try_from(account_id: String) -> Result { - Self::validate(&account_id)?; - Ok(Self(account_id.into_boxed_str())) - } -} - -impl fmt::Display for AccountId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.0, f) - } -} - -impl From for String { - fn from(account_id: AccountId) -> Self { - account_id.0.into_string() - } -} - -impl From for Box { - fn from(value: AccountId) -> Box { - value.0 - } -} - -#[cfg(feature = "arbitrary")] -impl<'a> arbitrary::Arbitrary<'a> for AccountId { - fn size_hint(_depth: usize) -> (usize, Option) { - (AccountId::MIN_LEN, Some(AccountId::MAX_LEN)) - } - - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - let mut s = u.arbitrary::<&str>()?; - loop { - match s.parse::() { - Ok(account_id) => break Ok(account_id), - Err(ParseAccountError { char: Some((idx, _)), .. }) => { - s = &s[..idx]; - continue; - } - _ => break Err(arbitrary::Error::IncorrectFormat), - } - } - } - - fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> arbitrary::Result { - <&str as arbitrary::Arbitrary>::arbitrary_take_rest(u)? - .parse() - .map_err(|_| arbitrary::Error::IncorrectFormat) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - pub const OK_ACCOUNT_IDS: [&str; 24] = [ - "aa", - "a-a", - "a-aa", - "100", - "0o", - "com", - "near", - "bowen", - "b-o_w_e-n", - "b.owen", - "bro.wen", - "a.ha", - "a.b-a.ra", - "system", - "over.9000", - "google.com", - "illia.cheapaccounts.near", - "0o0ooo00oo00o", - "alex-skidanov", - "10-4.8-2", - "b-o_w_e-n", - "no_lols", - "0123456789012345678901234567890123456789012345678901234567890123", - // Valid, but can't be created - "near.a", - ]; - - pub const BAD_ACCOUNT_IDS: [&str; 24] = [ - "a", - "A", - "Abc", - "-near", - "near-", - "-near-", - "near.", - ".near", - "near@", - "@near", - "неар", - "@@@@@", - "0__0", - "0_-_0", - "0_-_0", - "..", - "a..near", - "nEar", - "_bowen", - "hello world", - "abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz", - "01234567890123456789012345678901234567890123456789012345678901234", - // `@` separators are banned now - "some-complex-address@gmail.com", - "sub.buy_d1gitz@atata@b0-rg.c_0_m", - ]; - - #[test] - fn test_is_valid_account_id() { - for account_id in OK_ACCOUNT_IDS.iter().cloned() { - if let Err(err) = AccountId::validate(account_id) { - panic!("Valid account id {:?} marked invalid: {}", account_id, err.kind()); - } - } - - for account_id in BAD_ACCOUNT_IDS.iter().cloned() { - if AccountId::validate(account_id).is_ok() { - panic!("Invalid account id {:?} marked valid", account_id); - } - } - } - - #[test] - fn test_err_kind_classification() { - let id = "ErinMoriarty.near".parse::(); - debug_assert!( - matches!( - id, - Err(ParseAccountError { kind: ParseErrorKind::InvalidChar, char: Some((0, 'E')) }) - ), - "{:?}", - id - ); - - let id = "-KarlUrban.near".parse::(); - debug_assert!( - matches!( - id, - Err(ParseAccountError { - kind: ParseErrorKind::RedundantSeparator, - char: Some((0, '-')) - }) - ), - "{:?}", - id - ); - - let id = "anthonystarr.".parse::(); - debug_assert!( - matches!( - id, - Err(ParseAccountError { - kind: ParseErrorKind::RedundantSeparator, - char: Some((12, '.')) - }) - ), - "{:?}", - id - ); - - let id = "jack__Quaid.near".parse::(); - debug_assert!( - matches!( - id, - Err(ParseAccountError { - kind: ParseErrorKind::RedundantSeparator, - char: Some((5, '_')) - }) - ), - "{:?}", - id - ); - } - - #[test] - fn test_is_valid_top_level_account_id() { - let ok_top_level_account_ids = &[ - "aa", - "a-a", - "a-aa", - "100", - "0o", - "com", - "near", - "bowen", - "b-o_w_e-n", - "0o0ooo00oo00o", - "alex-skidanov", - "b-o_w_e-n", - "no_lols", - "0123456789012345678901234567890123456789012345678901234567890123", - ]; - for account_id in ok_top_level_account_ids { - assert!( - account_id - .parse::() - .map_or(false, |account_id| account_id.is_top_level()), - "Valid top level account id {:?} marked invalid", - account_id - ); - } - - let bad_top_level_account_ids = &[ - "ƒelicia.near", // fancy ƒ! - "near.a", - "b.owen", - "bro.wen", - "a.ha", - "a.b-a.ra", - "some-complex-address@gmail.com", - "sub.buy_d1gitz@atata@b0-rg.c_0_m", - "over.9000", - "google.com", - "illia.cheapaccounts.near", - "10-4.8-2", - "a", - "A", - "Abc", - "-near", - "near-", - "-near-", - "near.", - ".near", - "near@", - "@near", - "неар", - "@@@@@", - "0__0", - "0_-_0", - "0_-_0", - "..", - "a..near", - "nEar", - "_bowen", - "hello world", - "abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz", - "01234567890123456789012345678901234567890123456789012345678901234", - // Valid regex and length, but reserved - "system", - ]; - for account_id in bad_top_level_account_ids { - assert!( - !account_id - .parse::() - .map_or(false, |account_id| account_id.is_top_level()), - "Invalid top level account id {:?} marked valid", - account_id - ); - } - } - - #[test] - fn test_is_valid_sub_account_id() { - let ok_pairs = &[ - ("test", "a.test"), - ("test-me", "abc.test-me"), - ("gmail.com", "abc.gmail.com"), - ("gmail.com", "abc-lol.gmail.com"), - ("gmail.com", "abc_lol.gmail.com"), - ("gmail.com", "bro-abc_lol.gmail.com"), - ("g0", "0g.g0"), - ("1g", "1g.1g"), - ("5-3", "4_2.5-3"), - ]; - for (signer_id, sub_account_id) in ok_pairs { - assert!( - matches!( - (signer_id.parse::(), sub_account_id.parse::()), - (Ok(signer_id), Ok(sub_account_id)) if sub_account_id.is_sub_account_of(&signer_id) - ), - "Failed to create sub-account {:?} by account {:?}", - sub_account_id, - signer_id - ); - } - - let bad_pairs = &[ - ("test", ".test"), - ("test", "test"), - ("test", "a1.a.test"), - ("test", "est"), - ("test", ""), - ("test", "st"), - ("test5", "ббб"), - ("test", "a-test"), - ("test", "etest"), - ("test", "a.etest"), - ("test", "retest"), - ("test-me", "abc-.test-me"), - ("test-me", "Abc.test-me"), - ("test-me", "-abc.test-me"), - ("test-me", "a--c.test-me"), - ("test-me", "a_-c.test-me"), - ("test-me", "a-_c.test-me"), - ("test-me", "_abc.test-me"), - ("test-me", "abc_.test-me"), - ("test-me", "..test-me"), - ("test-me", "a..test-me"), - ("gmail.com", "a.abc@gmail.com"), - ("gmail.com", ".abc@gmail.com"), - ("gmail.com", ".abc@gmail@com"), - ("gmail.com", "abc@gmail@com"), - ("test", "a@test"), - ("test_me", "abc@test_me"), - ("gmail.com", "abc@gmail.com"), - ("gmail@com", "abc.gmail@com"), - ("gmail.com", "abc-lol@gmail.com"), - ("gmail@com", "abc_lol.gmail@com"), - ("gmail@com", "bro-abc_lol.gmail@com"), - ("gmail.com", "123456789012345678901234567890123456789012345678901234567890@gmail.com"), - ( - "123456789012345678901234567890123456789012345678901234567890", - "1234567890.123456789012345678901234567890123456789012345678901234567890", - ), - ("aa", "ъ@aa"), - ("aa", "ъ.aa"), - ]; - for (signer_id, sub_account_id) in bad_pairs { - assert!( - !matches!( - (signer_id.parse::(), sub_account_id.parse::()), - (Ok(signer_id), Ok(sub_account_id)) if sub_account_id.is_sub_account_of(&signer_id) - ), - "Invalid sub-account {:?} created by account {:?}", - sub_account_id, - signer_id - ); - } - } - - #[test] - fn test_is_account_id_64_len_hex() { - let valid_64_len_hex_account_ids = &[ - "0000000000000000000000000000000000000000000000000000000000000000", - "6174617461746174617461746174617461746174617461746174617461746174", - "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "20782e20662e64666420482123494b6b6c677573646b6c66676a646b6c736667", - ]; - for valid_account_id in valid_64_len_hex_account_ids { - assert!( - matches!( - valid_account_id.parse::(), - Ok(account_id) if account_id.is_implicit() - ), - "Account ID {} should be valid 64-len hex", - valid_account_id - ); - } - - let invalid_64_len_hex_account_ids = &[ - "000000000000000000000000000000000000000000000000000000000000000", - "6.74617461746174617461746174617461746174617461746174617461746174", - "012-456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", - "fffff_ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", - "00000000000000000000000000000000000000000000000000000000000000", - ]; - for invalid_account_id in invalid_64_len_hex_account_ids { - assert!( - !matches!( - invalid_account_id.parse::(), - Ok(account_id) if account_id.is_implicit() - ), - "Account ID {} is not an implicit account", - invalid_account_id - ); - } - } - - #[test] - #[cfg(feature = "arbitrary")] - fn test_arbitrary() { - let corpus = [ - ("a|bcd", None), - ("ab|cde", Some("ab")), - ("a_-b", None), - ("ab_-c", Some("ab")), - ("a", None), - ("miraclx.near", Some("miraclx.near")), - ("01234567890123456789012345678901234567890123456789012345678901234", None), - ]; - - for (input, expected_output) in corpus { - assert!(input.len() <= u8::MAX as usize); - let data = [input.as_bytes(), &[input.len() as _]].concat(); - let mut u = arbitrary::Unstructured::new(&data); - - assert_eq!(u.arbitrary::().as_deref().ok(), expected_output); - } - } -} diff --git a/core/account-id/src/serde.rs b/core/account-id/src/serde.rs deleted file mode 100644 index fb1d7ca7d38..00000000000 --- a/core/account-id/src/serde.rs +++ /dev/null @@ -1,78 +0,0 @@ -use super::AccountId; - -use serde::{de, ser}; - -impl ser::Serialize for AccountId { - fn serialize(&self, serializer: S) -> Result - where - S: ser::Serializer, - { - self.0.serialize(serializer) - } -} - -impl<'de> de::Deserialize<'de> for AccountId { - fn deserialize(deserializer: D) -> Result - where - D: de::Deserializer<'de>, - { - let account_id = Box::::deserialize(deserializer)?; - AccountId::validate(&account_id).map_err(|err| { - de::Error::custom(format!("invalid value: \"{}\", {}", account_id, err)) - })?; - Ok(AccountId(account_id)) - } -} - -#[cfg(test)] -mod tests { - use super::{ - super::tests::{BAD_ACCOUNT_IDS, OK_ACCOUNT_IDS}, - AccountId, - }; - - use serde_json::json; - - #[test] - fn test_is_valid_account_id() { - for account_id in OK_ACCOUNT_IDS.iter() { - let parsed_account_id = account_id.parse::().unwrap_or_else(|err| { - panic!("Valid account id {:?} marked invalid: {}", account_id, err) - }); - - let deserialized_account_id: AccountId = serde_json::from_value(json!(account_id)) - .unwrap_or_else(|err| { - panic!("failed to deserialize account ID {:?}: {}", account_id, err) - }); - assert_eq!(deserialized_account_id, parsed_account_id); - - let serialized_account_id = serde_json::to_value(&deserialized_account_id) - .unwrap_or_else(|err| { - panic!("failed to serialize account ID {:?}: {}", account_id, err) - }); - assert_eq!(serialized_account_id, json!(account_id)); - } - - for account_id in BAD_ACCOUNT_IDS.iter() { - assert!( - serde_json::from_value::(json!(account_id)).is_err(), - "successfully deserialized invalid account ID {:?}", - account_id - ); - } - } - - #[test] - fn fuzz() { - bolero::check!().for_each(|input: &[u8]| { - if let Ok(account_id) = std::str::from_utf8(input) { - if let Ok(account_id) = serde_json::from_value::(json!(account_id)) { - assert_eq!( - account_id, - serde_json::from_value(serde_json::to_value(&account_id).unwrap()).unwrap() - ); - } - } - }); - } -} diff --git a/core/crypto/src/util.rs b/core/crypto/src/util.rs index 4f37cd1e1f8..d0205c6802f 100644 --- a/core/crypto/src/util.rs +++ b/core/crypto/src/util.rs @@ -112,7 +112,7 @@ impl PublicKey { let mut public_key_data = Vec::with_capacity(33); public_key_data.push(KeyType::ED25519 as u8); public_key_data.extend( - hex::decode(account_id.as_ref().as_bytes()) + hex::decode(account_id.as_bytes()) .expect("account id was a valid hex of length 64 resulting in 32 bytes"), ); debug_assert_eq!(public_key_data.len(), 33); diff --git a/core/primitives/src/shard_layout.rs b/core/primitives/src/shard_layout.rs index f34800c53ca..7f2252b63c7 100644 --- a/core/primitives/src/shard_layout.rs +++ b/core/primitives/src/shard_layout.rs @@ -240,7 +240,7 @@ impl ShardLayout { pub fn account_id_to_shard_id(account_id: &AccountId, shard_layout: &ShardLayout) -> ShardId { match shard_layout { ShardLayout::V0(ShardLayoutV0 { num_shards, .. }) => { - let hash = CryptoHash::hash_bytes(account_id.as_ref().as_bytes()); + let hash = CryptoHash::hash_bytes(account_id.as_bytes()); let (bytes, _) = stdx::split_array::<32, 8, 24>(hash.as_bytes()); u64::from_le_bytes(*bytes) % num_shards } diff --git a/core/primitives/src/signable_message.rs b/core/primitives/src/signable_message.rs index 124eb4f6d53..6903effedd2 100644 --- a/core/primitives/src/signable_message.rs +++ b/core/primitives/src/signable_message.rs @@ -221,15 +221,15 @@ impl From for MessageDiscriminant { #[cfg(test)] mod tests { use near_crypto::{InMemorySigner, KeyType, PublicKey}; + use near_primitives_core::account::id::AccountIdRef; use super::*; use crate::action::delegate::{DelegateAction, SignedDelegateAction}; // Note: this is currently a simplified copy of near-primitives::test_utils::create_user_test_signer // TODO: consider whether it’s worth re-unifying them? it’s test-only code anyway. - fn create_user_test_signer(account_name: &str) -> InMemorySigner { - let account_id = account_name.parse().unwrap(); - InMemorySigner::from_seed(account_id, KeyType::ED25519, account_name) + fn create_user_test_signer(account_id: &AccountIdRef) -> InMemorySigner { + InMemorySigner::from_seed(account_id.to_owned(), KeyType::ED25519, account_id.as_str()) } // happy path for NEP-366 signature diff --git a/core/primitives/src/test_utils.rs b/core/primitives/src/test_utils.rs index c9de6f504d7..bb35526869b 100644 --- a/core/primitives/src/test_utils.rs +++ b/core/primitives/src/test_utils.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::sync::Arc; use near_crypto::{EmptySigner, InMemorySigner, KeyType, PublicKey, SecretKey, Signature, Signer}; +use near_primitives_core::account::id::AccountIdRef; use near_primitives_core::types::ProtocolVersion; use crate::account::{AccessKey, AccessKeyPermission, Account}; @@ -553,12 +554,12 @@ pub fn create_test_signer(account_name: &str) -> InMemoryValidatorSigner { /// This also works for predefined implicit accounts, where the signer will use the implicit key. /// /// Should be used only in tests. -pub fn create_user_test_signer(account_name: &str) -> InMemorySigner { - let account_id = account_name.parse().unwrap(); +pub fn create_user_test_signer(account_name: &AccountIdRef) -> InMemorySigner { + let account_id: AccountId = account_name.to_owned(); if account_id == implicit_test_account() { InMemorySigner::from_secret_key(account_id, implicit_test_account_secret()) } else { - InMemorySigner::from_seed(account_id, KeyType::ED25519, account_name) + InMemorySigner::from_seed(account_id, KeyType::ED25519, account_name.as_str()) } } diff --git a/core/primitives/src/trie_key.rs b/core/primitives/src/trie_key.rs index 3dbdf9f04b3..9d056507231 100644 --- a/core/primitives/src/trie_key.rs +++ b/core/primitives/src/trie_key.rs @@ -153,39 +153,39 @@ impl TrieKey { match self { TrieKey::Account { account_id } => { buf.push(col::ACCOUNT); - buf.extend(account_id.as_ref().as_bytes()); + buf.extend(account_id.as_bytes()); } TrieKey::ContractCode { account_id } => { buf.push(col::CONTRACT_CODE); - buf.extend(account_id.as_ref().as_bytes()); + buf.extend(account_id.as_bytes()); } TrieKey::AccessKey { account_id, public_key } => { buf.push(col::ACCESS_KEY); - buf.extend(account_id.as_ref().as_bytes()); + buf.extend(account_id.as_bytes()); buf.push(col::ACCESS_KEY); buf.extend(borsh::to_vec(&public_key).unwrap()); } TrieKey::ReceivedData { receiver_id, data_id } => { buf.push(col::RECEIVED_DATA); - buf.extend(receiver_id.as_ref().as_bytes()); + buf.extend(receiver_id.as_bytes()); buf.push(ACCOUNT_DATA_SEPARATOR); buf.extend(data_id.as_ref()); } TrieKey::PostponedReceiptId { receiver_id, data_id } => { buf.push(col::POSTPONED_RECEIPT_ID); - buf.extend(receiver_id.as_ref().as_bytes()); + buf.extend(receiver_id.as_bytes()); buf.push(ACCOUNT_DATA_SEPARATOR); buf.extend(data_id.as_ref()); } TrieKey::PendingDataCount { receiver_id, receipt_id } => { buf.push(col::PENDING_DATA_COUNT); - buf.extend(receiver_id.as_ref().as_bytes()); + buf.extend(receiver_id.as_bytes()); buf.push(ACCOUNT_DATA_SEPARATOR); buf.extend(receipt_id.as_ref()); } TrieKey::PostponedReceipt { receiver_id, receipt_id } => { buf.push(col::POSTPONED_RECEIPT); - buf.extend(receiver_id.as_ref().as_bytes()); + buf.extend(receiver_id.as_bytes()); buf.push(ACCOUNT_DATA_SEPARATOR); buf.extend(receipt_id.as_ref()); } @@ -198,7 +198,7 @@ impl TrieKey { } TrieKey::ContractData { account_id, key } => { buf.push(col::CONTRACT_DATA); - buf.extend(account_id.as_ref().as_bytes()); + buf.extend(account_id.as_bytes()); buf.push(ACCOUNT_DATA_SEPARATOR); buf.extend(key); } diff --git a/core/store/src/trie/split_state.rs b/core/store/src/trie/split_state.rs index 7c9dcf7bf53..fc6382023f5 100644 --- a/core/store/src/trie/split_state.rs +++ b/core/store/src/trie/split_state.rs @@ -496,8 +496,8 @@ mod tests { &all_receipts[new_start_index..], state_roots, &|account_id| ShardUId { - shard_id: (hash(account_id.as_ref().as_bytes()).0[0] as NumShards - % num_shards) as u32, + shard_id: (hash(account_id.as_bytes()).0[0] as NumShards % num_shards) + as u32, version: 1, }, ); diff --git a/genesis-tools/genesis-csv-to-json/src/csv_parser.rs b/genesis-tools/genesis-csv-to-json/src/csv_parser.rs index 17da184bddb..d6dc117ee68 100644 --- a/genesis-tools/genesis-csv-to-json/src/csv_parser.rs +++ b/genesis-tools/genesis-csv-to-json/src/csv_parser.rs @@ -249,7 +249,7 @@ fn account_records(row: &Row, gas_price: Balance) -> Vec { predecessor_id: row.account_id.clone(), receiver_id: row.account_id.clone(), // `receipt_id` can be anything as long as it is unique. - receipt_id: hash(row.account_id.as_ref().as_bytes()), + receipt_id: hash(row.account_id.as_bytes()), receipt: ReceiptEnum::Action(ActionReceipt { signer_id: row.account_id.clone(), // `signer_public_key` can be anything because the key checks are not applied when diff --git a/integration-tests/src/node/mod.rs b/integration-tests/src/node/mod.rs index 80b92c1005f..4976527724e 100644 --- a/integration-tests/src/node/mod.rs +++ b/integration-tests/src/node/mod.rs @@ -160,7 +160,7 @@ pub fn create_nodes_from_seeds(seeds: Vec) -> Vec { for record in records.iter_mut() { if let StateRecord::Account { account_id: record_account_id, ref mut account } = record { - if record_account_id.as_ref() == seed { + if *record_account_id == seed { is_account_record_found = true; account.set_code_hash(*ContractCode::new(code.to_vec(), None).hash()); } diff --git a/integration-tests/src/tests/client/chunks_management.rs b/integration-tests/src/tests/client/chunks_management.rs index 4a19bb8f741..6ae739e359a 100644 --- a/integration-tests/src/tests/client/chunks_management.rs +++ b/integration-tests/src/tests/client/chunks_management.rs @@ -194,9 +194,7 @@ impl Test { partial_encoded_chunk: _, } => { partial_chunk_msgs += 1; - if self.drop_to_4_from.contains(&from_whom.as_str()) - && to_whom.as_ref() == "test4" - { + if self.drop_to_4_from.contains(&from_whom.as_str()) && to_whom == "test4" { println!( "Dropping Partial Encoded Chunk Message from {from_whom} to test4" ); @@ -208,9 +206,7 @@ impl Test { println!("Dropping Partial Encoded Chunk Forward Message"); return (NetworkResponses::NoResponse.into(), false); } - if self.drop_to_4_from.contains(&from_whom.as_str()) - && to_whom.as_ref() == "test4" - { + if self.drop_to_4_from.contains(&from_whom.as_str()) && to_whom == "test4" { println!( "Dropping Partial Encoded Chunk Forward Message from {from_whom} to test4" ); @@ -224,15 +220,13 @@ impl Test { target: AccountIdOrPeerTrackingShard { account_id: Some(to_whom), .. }, .. } => { - if self.drop_to_4_from.contains(&to_whom.as_str()) - && from_whom.as_ref() == "test4" - { + if self.drop_to_4_from.contains(&to_whom.as_str()) && from_whom == "test4" { info!("Dropping Partial Encoded Chunk Request from test4 to {to_whom}"); return (NetworkResponses::NoResponse.into(), false); } if !self.drop_to_4_from.is_empty() - && from_whom.as_ref() == "test4" - && to_whom.as_ref() == "test2" + && from_whom == "test4" + && to_whom == "test2" { info!("Observed Partial Encoded Chunk Request from test4 to test2"); } diff --git a/integration-tests/src/tests/client/features/delegate_action.rs b/integration-tests/src/tests/client/features/delegate_action.rs index abb5d73feea..1aa2c11aa53 100644 --- a/integration-tests/src/tests/client/features/delegate_action.rs +++ b/integration-tests/src/tests/client/features/delegate_action.rs @@ -130,13 +130,13 @@ fn check_meta_tx_execution( let relayer_before = node_user.view_balance(&relayer).unwrap(); let receiver_before = node_user.view_balance(&receiver).unwrap_or(0); let relayer_nonce_before = node_user - .get_access_key(&relayer, &PublicKey::from_seed(KeyType::ED25519, &relayer)) + .get_access_key(&relayer, &PublicKey::from_seed(KeyType::ED25519, relayer.as_ref())) .unwrap() .nonce; let user_pubk = if sender.is_implicit() { PublicKey::from_implicit_account(&sender).unwrap() } else { - PublicKey::from_seed(KeyType::ED25519, &sender) + PublicKey::from_seed(KeyType::ED25519, sender.as_ref()) }; let user_nonce_before = node_user.get_access_key(&sender, &user_pubk).unwrap().nonce; @@ -148,13 +148,13 @@ fn check_meta_tx_execution( // both nonces should be increased by 1 let relayer_nonce = node_user - .get_access_key(&relayer, &PublicKey::from_seed(KeyType::ED25519, &relayer)) + .get_access_key(&relayer, &PublicKey::from_seed(KeyType::ED25519, relayer.as_ref())) .unwrap() .nonce; assert_eq!(relayer_nonce, relayer_nonce_before + 1); // user key must be checked for existence (to test DeleteKey action) if let Ok(user_nonce) = node_user - .get_access_key(&sender, &PublicKey::from_seed(KeyType::ED25519, &sender)) + .get_access_key(&sender, &PublicKey::from_seed(KeyType::ED25519, sender.as_ref())) .map(|key| key.nonce) { assert_eq!(user_nonce, user_nonce_before + 1); @@ -493,7 +493,7 @@ fn meta_tx_delete_key() { let fee_helper = fee_helper(&node); let tx_cost = fee_helper.delete_key_cost(); - let public_key = PublicKey::from_seed(KeyType::ED25519, &receiver); + let public_key = PublicKey::from_seed(KeyType::ED25519, receiver.as_ref()); let actions = vec![Action::DeleteKey(Box::new(DeleteKeyAction { public_key: public_key.clone() }))]; check_meta_tx_no_fn_call(&node, actions, tx_cost, 0, sender, relayer, receiver.clone()); @@ -518,7 +518,7 @@ fn meta_tx_delete_account() { .create_account( relayer.clone(), sender.clone(), - PublicKey::from_seed(KeyType::ED25519, &sender), + PublicKey::from_seed(KeyType::ED25519, sender.as_ref()), balance, ) .expect("account setup failed") @@ -577,13 +577,13 @@ fn meta_tx_ft_transfer() { .assert_success(); // register sender & receiver FT accounts - let actions = vec![ft_register_action(&sender), ft_register_action(&receiver)]; + let actions = vec![ft_register_action(sender.as_ref()), ft_register_action(&receiver)]; node.user() .sign_and_commit_actions(relayer.clone(), ft_contract.clone(), actions) .expect("registering FT accounts") .assert_success(); // initialize sender balance - let actions = vec![ft_transfer_action(&sender, 10_000).0]; + let actions = vec![ft_transfer_action(sender.as_ref(), 10_000).0]; node.user() .sign_and_commit_actions(relayer.clone(), ft_contract.clone(), actions) .expect("initializing sender balance failed") @@ -591,7 +591,7 @@ fn meta_tx_ft_transfer() { // START OF META TRANSACTION // 1% fee to the relayer - let (action0, bytes0) = ft_transfer_action(&relayer, 10); + let (action0, bytes0) = ft_transfer_action(relayer.as_ref(), 10); // the actual transfer let (action1, bytes1) = ft_transfer_action(receiver, 1000); let actions = vec![action0, action1]; @@ -612,19 +612,19 @@ fn meta_tx_ft_transfer() { assert_eq!(2, fn_call_logs.len(), "expected 2 JSON events but found {fn_call_logs:?}"); assert_eq!( fn_call_logs[0], - ft_transfer_event(&sender, &relayer, 10), + ft_transfer_event(sender.as_ref(), relayer.as_ref(), 10), "relayer event looks wrong" ); assert_eq!( fn_call_logs[1], - ft_transfer_event(&sender, &receiver, 1000), + ft_transfer_event(sender.as_str(), &receiver, 1000), "receiver event looks wrong" ); // Also check FT balances assert_ft_balance(&node, &ft_contract, &receiver, 1000); - assert_ft_balance(&node, &ft_contract, &sender, 10_000 - 1000 - 10); - assert_ft_balance(&node, &ft_contract, &relayer, 1_000_000 - 10_000 + 10); + assert_ft_balance(&node, &ft_contract, sender.as_ref(), 10_000 - 1000 - 10); + assert_ft_balance(&node, &ft_contract, relayer.as_ref(), 1_000_000 - 10_000 + 10); } /// Call the function "log_something" in the test contract. @@ -758,7 +758,7 @@ fn meta_tx_create_named_account() { let fee_helper = fee_helper(&node); let amount = NEAR_BASE; - let public_key = PublicKey::from_seed(KeyType::ED25519, &new_account); + let public_key = PublicKey::from_seed(KeyType::ED25519, new_account.as_ref()); // That's the minimum to create a (useful) account. let actions = vec![ diff --git a/integration-tests/src/tests/client/features/fix_storage_usage.rs b/integration-tests/src/tests/client/features/fix_storage_usage.rs index 1c17147ac3f..92bd49cbd00 100644 --- a/integration-tests/src/tests/client/features/fix_storage_usage.rs +++ b/integration-tests/src/tests/client/features/fix_storage_usage.rs @@ -69,7 +69,7 @@ fn test_fix_storage_usage_migration() { process_blocks_with_storage_usage_fix( near_primitives::chains::MAINNET.to_string(), |account_id: AccountId, block_height: u64, storage_usage: u64| { - if account_id.as_ref() == "near" && block_height >= 11 { + if account_id == "near" && block_height >= 11 { assert_eq!(storage_usage, 4378); } else { assert_eq!(storage_usage, 182); diff --git a/integration-tests/src/tests/client/features/increase_storage_compute_cost.rs b/integration-tests/src/tests/client/features/increase_storage_compute_cost.rs index aa732fc4f6c..5f89f10d3aa 100644 --- a/integration-tests/src/tests/client/features/increase_storage_compute_cost.rs +++ b/integration-tests/src/tests/client/features/increase_storage_compute_cost.rs @@ -212,7 +212,7 @@ fn assert_compute_limit_reached( let signer = InMemorySigner::from_seed( contract_account.clone(), KeyType::ED25519, - &contract_account, + contract_account.as_ref(), ); let tx = env.tx_from_actions(actions, &signer, signer.account_id.clone()); env.execute_tx(tx).unwrap().assert_success(); @@ -300,7 +300,8 @@ fn produce_saturated_chunk( gas, deposit: 0, }))]; - let signer = InMemorySigner::from_seed(user_account.clone(), KeyType::ED25519, user_account); + let signer = + InMemorySigner::from_seed(user_account.clone(), KeyType::ED25519, user_account.as_ref()); let tip = env.clients[0].chain.head().unwrap(); let mut tx_factory = || { diff --git a/integration-tests/src/tests/client/process_blocks.rs b/integration-tests/src/tests/client/process_blocks.rs index b0359661e78..b481d19142a 100644 --- a/integration-tests/src/tests/client/process_blocks.rs +++ b/integration-tests/src/tests/client/process_blocks.rs @@ -604,7 +604,7 @@ fn produce_block_with_approvals_arrived_early() { (NetworkResponses::NoResponse.into(), true) } NetworkRequests::Approval { approval_message } => { - if approval_message.target.as_ref() == "test1" + if approval_message.target == "test1" && approval_message.approval.target_height == 4 { approval_counter += 1; @@ -2978,7 +2978,7 @@ fn test_epoch_protocol_version_change() { .unwrap(); let chunk_producer = env.clients[0].epoch_manager.get_chunk_producer(&epoch_id, i, 0).unwrap(); - let index = if chunk_producer.as_ref() == "test0" { 0 } else { 1 }; + let index = if chunk_producer == "test0" { 0 } else { 1 }; let (encoded_chunk, merkle_paths, receipts) = create_chunk_on_height(&mut env.clients[index], i); @@ -3000,7 +3000,7 @@ fn test_epoch_protocol_version_change() { .get_epoch_id_from_prev_block(&head.last_block_hash) .unwrap(); let block_producer = env.clients[0].epoch_manager.get_block_producer(&epoch_id, i).unwrap(); - let index = if block_producer.as_ref() == "test0" { 0 } else { 1 }; + let index = if block_producer == "test0" { 0 } else { 1 }; let mut block = env.clients[index].produce_block(i).unwrap().unwrap(); // upgrade to new protocol version but in the second epoch one node vote for the old version. if i != 10 { diff --git a/integration-tests/src/tests/nearcore/rpc_nodes.rs b/integration-tests/src/tests/nearcore/rpc_nodes.rs index 614b9d28a75..a18e0b6f954 100644 --- a/integration-tests/src/tests/nearcore/rpc_nodes.rs +++ b/integration-tests/src/tests/nearcore/rpc_nodes.rs @@ -61,10 +61,7 @@ fn test_get_validator_info_rpc() { let res = client.validators(None).await.unwrap(); assert_eq!(res.current_validators.len(), 1); - assert!(res - .current_validators - .iter() - .any(|r| r.account_id.as_ref() == "near.0")); + assert!(res.current_validators.iter().any(|r| r.account_id == "near.0")); System::current().stop(); } }); diff --git a/integration-tests/src/tests/network/runner.rs b/integration-tests/src/tests/network/runner.rs index 892783a7193..e3b530c0d12 100644 --- a/integration-tests/src/tests/network/runner.rs +++ b/integration-tests/src/tests/network/runner.rs @@ -271,7 +271,7 @@ impl TestConfig { } fn peer_id(&self) -> PeerId { - peer_id_from_seed(&self.account_id) + peer_id_from_seed(self.account_id.as_ref()) } fn peer_info(&self) -> PeerInfo { @@ -398,7 +398,7 @@ impl Runner { config.whitelist.iter().map(|ix| self.test_config[*ix].peer_info()).collect(); let mut network_config = - config::NetworkConfig::from_seed(&config.account_id, config.node_addr); + config::NetworkConfig::from_seed(config.account_id.as_ref(), config.node_addr); network_config.peer_store.ban_window = config.ban_window; network_config.max_num_peers = config.max_num_peers; network_config.ttl_account_id_router = time::Duration::seconds(5); diff --git a/nearcore/src/runtime/mod.rs b/nearcore/src/runtime/mod.rs index 3f840647e43..1881ca35f14 100644 --- a/nearcore/src/runtime/mod.rs +++ b/nearcore/src/runtime/mod.rs @@ -1326,6 +1326,7 @@ mod test { use super::*; + use near_primitives::account::id::AccountIdRef; use near_primitives::trie_key::TrieKey; use primitive_types::U256; @@ -2095,13 +2096,13 @@ mod test { let bp = em.get_block_producer_info(&epoch_id, height).unwrap(); let cp = em.get_chunk_producer_info(&epoch_id, height, 0).unwrap(); - if bp.account_id().as_ref() == "test1" { + if bp.account_id() == "test1" { expected_blocks[0] += 1; } else { expected_blocks[1] += 1; } - if cp.account_id().as_ref() == "test1" { + if cp.account_id() == "test1" { expected_chunks[0] += 1; } else { expected_chunks[1] += 1; @@ -2486,7 +2487,7 @@ mod test { .into_iter() .map(|fishermen| fishermen.take_account_id()) .collect::>(), - vec!["test1".parse().unwrap(), "test2".parse().unwrap()] + vec!["test1", "test2"] ); let staking_transaction = stake(2, &signers[0], &block_producers[0], TESTING_INIT_STAKE); let staking_transaction2 = stake(2, &signers[1], &block_producers[1], 0); @@ -2553,7 +2554,7 @@ mod test { .into_iter() .map(|fishermen| fishermen.take_account_id()) .collect::>(), - vec!["test1".parse().unwrap()] + vec![AccountIdRef::new_or_panic("test1")] ); let staking_transaction = stake(2, &signers[0], &block_producers[0], 0); env.step_default(vec![staking_transaction]); diff --git a/runtime/near-vm-runner/src/logic/logic.rs b/runtime/near-vm-runner/src/logic/logic.rs index 9a25e665728..9f9ce4a6348 100644 --- a/runtime/near-vm-runner/src/logic/logic.rs +++ b/runtime/near-vm-runner/src/logic/logic.rs @@ -476,12 +476,11 @@ impl<'a> VMLogic<'a> { /// `base + write_register_base + write_register_byte * num_bytes` pub fn current_account_id(&mut self, register_id: u64) -> Result<()> { self.gas_counter.pay_base(base)?; - self.registers.set( &mut self.gas_counter, &self.config.limit_config, register_id, - self.context.current_account_id.as_ref().as_bytes(), + self.context.current_account_id.as_bytes(), ) } @@ -511,7 +510,7 @@ impl<'a> VMLogic<'a> { &mut self.gas_counter, &self.config.limit_config, register_id, - self.context.signer_account_id.as_ref().as_bytes(), + self.context.signer_account_id.as_bytes(), ) } @@ -569,7 +568,7 @@ impl<'a> VMLogic<'a> { &mut self.gas_counter, &self.config.limit_config, register_id, - self.context.predecessor_account_id.as_ref().as_bytes(), + self.context.predecessor_account_id.as_bytes(), ) } diff --git a/runtime/near-vm-runner/src/logic/tests/context.rs b/runtime/near-vm-runner/src/logic/tests/context.rs index 8cb548e9df5..64623897593 100644 --- a/runtime/near-vm-runner/src/logic/tests/context.rs +++ b/runtime/near-vm-runner/src/logic/tests/context.rs @@ -50,19 +50,14 @@ decl_test_bytes!( test_current_account_id, current_account_id, ctx, - ctx.current_account_id.as_ref().as_bytes() -); -decl_test_bytes!( - test_signer_account_id, - signer_account_id, - ctx, - ctx.signer_account_id.as_ref().as_bytes() + ctx.current_account_id.as_bytes() ); +decl_test_bytes!(test_signer_account_id, signer_account_id, ctx, ctx.signer_account_id.as_bytes()); decl_test_bytes!( test_predecessor_account_id, predecessor_account_id, ctx, - ctx.predecessor_account_id.as_ref().as_bytes() + ctx.predecessor_account_id.as_bytes() ); decl_test_bytes!(test_signer_account_pk, signer_account_pk, ctx, ctx.signer_account_pk); diff --git a/runtime/runtime-params-estimator/src/action_costs.rs b/runtime/runtime-params-estimator/src/action_costs.rs index 542e9e881ef..8b0f2951a12 100644 --- a/runtime/runtime-params-estimator/src/action_costs.rs +++ b/runtime/runtime-params-estimator/src/action_costs.rs @@ -254,7 +254,7 @@ impl ActionEstimation { let signer_id = tb.account_by_requirement(self.signer, None); let predecessor_id = tb.account_by_requirement(self.predecessor, Some(&signer_id)); let receiver_id = tb.account_by_requirement(self.receiver, Some(&signer_id)); - let signer_public_key = PublicKey::from_seed(KeyType::ED25519, &signer_id); + let signer_public_key = PublicKey::from_seed(KeyType::ED25519, signer_id.as_str()); let action_receipt = ActionReceipt { signer_id, diff --git a/runtime/runtime/src/actions.rs b/runtime/runtime/src/actions.rs index c594f347bb5..3a968d6d4f9 100644 --- a/runtime/runtime/src/actions.rs +++ b/runtime/runtime/src/actions.rs @@ -784,7 +784,7 @@ fn validate_delegate_action_key( ) .into()); } - if delegate_action.receiver_id.as_ref() != function_call_permission.receiver_id { + if delegate_action.receiver_id != function_call_permission.receiver_id { result.result = Err(ActionErrorKind::DelegateActionAccessKeyError( InvalidAccessKeyError::ReceiverMismatch { tx_receiver: delegate_action.receiver_id.clone(), diff --git a/runtime/runtime/src/balance_checker.rs b/runtime/runtime/src/balance_checker.rs index a8da12381c0..c66e681a411 100644 --- a/runtime/runtime/src/balance_checker.rs +++ b/runtime/runtime/src/balance_checker.rs @@ -41,7 +41,7 @@ fn receipt_cost( Ok(match &receipt.receipt { ReceiptEnum::Action(action_receipt) => { let mut total_cost = total_deposit(&action_receipt.actions)?; - if !AccountId::is_system(&receipt.predecessor_id) { + if !receipt.predecessor_id.is_system() { let mut total_gas = safe_add_gas( config.fees.fee(ActionCosts::new_action_receipt).exec_fee(), total_prepaid_exec_fees(config, &action_receipt.actions, &receipt.receiver_id)?, diff --git a/runtime/runtime/src/lib.rs b/runtime/runtime/src/lib.rs index 337b5fb80c1..32877466d20 100644 --- a/runtime/runtime/src/lib.rs +++ b/runtime/runtime/src/lib.rs @@ -307,7 +307,7 @@ impl Runtime { result.compute_usage = exec_fees; let account_id = &receipt.receiver_id; let is_the_only_action = actions.len() == 1; - let is_refund = AccountId::is_system(&receipt.predecessor_id); + let is_refund = receipt.predecessor_id.is_system(); // Account validation if let Err(e) = check_account_existence( action, @@ -575,7 +575,7 @@ impl Runtime { } } - let gas_deficit_amount = if AccountId::is_system(&receipt.predecessor_id) { + let gas_deficit_amount = if receipt.predecessor_id.is_system() { // We will set gas_burnt for refund receipts to be 0 when we calculate tx_burnt_amount // Here we don't set result.gas_burnt to be zero if CountRefundReceiptsInGasLimit is // enabled because we want it to be counted in gas limit calculation later @@ -625,8 +625,7 @@ impl Runtime { }; // If the receipt is a refund, then we consider it free without burnt gas. - let gas_burnt: Gas = - if AccountId::is_system(&receipt.predecessor_id) { 0 } else { result.gas_burnt }; + let gas_burnt: Gas = if receipt.predecessor_id.is_system() { 0 } else { result.gas_burnt }; // `gas_deficit_amount` is strictly less than `gas_price * gas_burnt`. let mut tx_burnt_amount = safe_gas_to_balance(apply_state.gas_price, gas_burnt)? - gas_deficit_amount; diff --git a/runtime/runtime/src/verifier.rs b/runtime/runtime/src/verifier.rs index 08323a15948..8429c1d9ef6 100644 --- a/runtime/runtime/src/verifier.rs +++ b/runtime/runtime/src/verifier.rs @@ -238,7 +238,7 @@ pub fn verify_and_charge_transaction( ) .into()); } - if transaction.receiver_id.as_ref() != function_call_permission.receiver_id { + if transaction.receiver_id != function_call_permission.receiver_id { return Err(InvalidTxError::InvalidAccessKeyError( InvalidAccessKeyError::ReceiverMismatch { tx_receiver: transaction.receiver_id.clone(), @@ -517,7 +517,7 @@ fn validate_add_key_action( /// /// Checks that the `beneficiary_id` is a valid account ID. fn validate_delete_action(action: &DeleteAccountAction) -> Result<(), ActionsValidationError> { - if AccountId::validate(&action.beneficiary_id).is_err() { + if AccountId::validate(action.beneficiary_id.as_str()).is_err() { return Err(ActionsValidationError::InvalidAccountId { account_id: action.beneficiary_id.to_string(), }); diff --git a/runtime/runtime/tests/runtime_group_tools/mod.rs b/runtime/runtime/tests/runtime_group_tools/mod.rs index 4c4fba335c4..7684d1ba7be 100644 --- a/runtime/runtime/tests/runtime_group_tools/mod.rs +++ b/runtime/runtime/tests/runtime_group_tools/mod.rs @@ -10,6 +10,7 @@ use near_primitives::test_utils::MockEpochInfoProvider; use near_primitives::transaction::{ExecutionOutcomeWithId, SignedTransaction}; use near_primitives::types::{AccountId, AccountInfo, Balance}; use near_primitives::version::PROTOCOL_VERSION; +use near_primitives_core::account::id::AccountIdRef; use near_primitives_core::config::ActionCosts; use near_store::genesis::GenesisStateApplier; use near_store::test_utils::create_tries; @@ -322,7 +323,7 @@ impl RuntimeGroup { self.executed_receipts .lock() .unwrap() - .get(executing_runtime) + .get(AccountIdRef::new_or_panic(executing_runtime)) .expect("Runtime not found") .iter() .find_map(|r| if &r.get_hash() == hash { Some(r.clone()) } else { None }) @@ -396,8 +397,8 @@ macro_rules! assert_receipts { $($action_name:ident, $action_pat:pat, $action_assert:block ),+ => [ $($produced_receipt:ident),*] ) => { let r = $group.get_receipt($to, $receipt); - assert_eq!(r.predecessor_id.as_ref(), $from); - assert_eq!(r.receiver_id.as_ref(), $to); + assert_eq!(r.predecessor_id, $from); + assert_eq!(r.receiver_id, $to); match &r.receipt { $receipt_pat => { $receipt_assert diff --git a/runtime/runtime/tests/test_async_calls.rs b/runtime/runtime/tests/test_async_calls.rs index cead94c01d2..e8fe09ed609 100644 --- a/runtime/runtime/tests/test_async_calls.rs +++ b/runtime/runtime/tests/test_async_calls.rs @@ -766,7 +766,7 @@ fn test_account_factory() { ReceiptEnum::Action(ActionReceipt{actions, output_data_receivers, ..}), { assert_eq!(output_data_receivers.len(), 1); data_id = output_data_receivers[0].data_id; - assert_eq!(output_data_receivers[0].receiver_id.as_ref(), "near_2"); + assert_eq!(output_data_receivers[0].receiver_id, "near_2"); }, actions, a0, Action::CreateAccount(CreateAccountAction{}), {}, @@ -929,7 +929,7 @@ fn test_create_account_add_key_call_delete_key_delete_account() { assert_eq!(delete_key_action.public_key, signer_new_account.public_key); }, a6, Action::DeleteAccount(DeleteAccountAction{beneficiary_id}), { - assert_eq!(beneficiary_id.as_ref(), "near_2"); + assert_eq!(beneficiary_id, "near_2"); } => [r2, r3, ref1] ); @@ -1000,7 +1000,7 @@ fn test_transfer_64len_hex() { assert_eq!(function_call_action.deposit, 0); } => [r1, ref0] ); - assert_receipts!(group, "near_1" => r1 @ account_id.as_ref(), + assert_receipts!(group, "near_1" => r1 @ account_id.as_str(), ReceiptEnum::Action(ActionReceipt{actions, ..}), {}, actions, a0, Action::Transfer(TransferAction{deposit}), { @@ -1066,7 +1066,7 @@ fn test_create_transfer_64len_hex_fail() { assert_eq!(function_call_action.deposit, 0); } => [r1, ref0] ); - assert_receipts!(group, "near_1" => r1 @ account_id.as_ref(), + assert_receipts!(group, "near_1" => r1 @ account_id.as_str(), ReceiptEnum::Action(ActionReceipt{actions, ..}), {}, actions, a0, Action::CreateAccount(CreateAccountAction{}), {}, diff --git a/test-utils/runtime-tester/src/fuzzing.rs b/test-utils/runtime-tester/src/fuzzing.rs index c13c29851be..3a1a8db71ec 100644 --- a/test-utils/runtime-tester/src/fuzzing.rs +++ b/test-utils/runtime-tester/src/fuzzing.rs @@ -245,7 +245,8 @@ impl TransactionConfig { } }; - let signer = scope.function_call_signer(u, &signer_account, &receiver_account.id)?; + let signer = + scope.function_call_signer(u, &signer_account, receiver_account.id.as_str())?; let mut receiver_functions = vec![]; if let Some(contract_id) = receiver_account.deployed_contract { diff --git a/tools/state-viewer/src/state_dump.rs b/tools/state-viewer/src/state_dump.rs index 9ed04e46b86..820e9ddc1c3 100644 --- a/tools/state-viewer/src/state_dump.rs +++ b/tools/state-viewer/src/state_dump.rs @@ -150,7 +150,7 @@ pub fn state_dump_redis( if let Some(sr) = StateRecord::from_raw_key_value(key, value) { if let StateRecord::Account { account_id, account } = &sr { println!("Account: {}", account_id); - let redis_key = account_id.as_ref().as_bytes(); + let redis_key = account_id.as_bytes(); redis_connection.zadd( [b"account:", redis_key].concat(), block_hash.as_ref(), @@ -166,8 +166,7 @@ pub fn state_dump_redis( if let StateRecord::Data { account_id, data_key, value } = &sr { println!("Data: {}", account_id); - let redis_key = - [account_id.as_ref().as_bytes(), b":", data_key.as_ref()].concat(); + let redis_key = [account_id.as_bytes(), b":", data_key.as_ref()].concat(); redis_connection.zadd( [b"data:", redis_key.as_slice()].concat(), block_hash.as_ref(), @@ -183,7 +182,7 @@ pub fn state_dump_redis( if let StateRecord::Contract { account_id, code } = &sr { println!("Contract: {}", account_id); - let redis_key = [b"code:", account_id.as_ref().as_bytes()].concat(); + let redis_key = [b"code:", account_id.as_bytes()].concat(); redis_connection.zadd(redis_key.clone(), block_hash.as_ref(), block_height)?; let value_vec: &[u8] = code.as_ref(); redis_connection.set( @@ -320,6 +319,7 @@ mod test { use crate::state_dump::state_dump; use near_primitives::hash::CryptoHash; use near_primitives::validator_signer::InMemoryValidatorSigner; + use near_primitives_core::account::id::AccountIdRef; fn setup( epoch_length: NumBlocks, @@ -629,7 +629,7 @@ mod test { .into_iter() .map(|r| r.account_id) .collect::>(), - vec!["test0".parse().unwrap()] + vec!["test0"] ); validate_genesis(&new_genesis).unwrap(); } @@ -915,7 +915,7 @@ mod test { .iter() .map(|x| x.account_id.clone()) .collect::>(), - vec!["test1".parse().unwrap()] + vec!["test1"] ); let mut stake = HashMap::::new(); @@ -925,7 +925,10 @@ mod test { } }); - assert_eq!(stake.get("test0").unwrap_or(&(0 as Balance)), &(0 as Balance)); + assert_eq!( + stake.get(AccountIdRef::new_or_panic("test0")).unwrap_or(&(0 as Balance)), + &(0 as Balance) + ); validate_genesis(&new_genesis).unwrap(); }