Skip to content

Commit

Permalink
update the change to restrict the creation of top level accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
bowenwang1996 committed Jul 31, 2023
1 parent 62367ed commit 6a1ec44
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 110 deletions.
40 changes: 0 additions & 40 deletions core/account-id/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,6 @@ impl AccountId {
!self.is_system() && !self.contains('.')
}

/// Returns `true` if the account id can be viewed as an Ethereum address directly
///
/// See [Ethereum account](https://ethereum.org/en/developers/docs/accounts/) for more details.
///
/// ## Examples
/// ```
/// use near_account_id::AccountId;
///
/// let eth_addr: AccountId = "0x06012c8cf97bead5deae237070f9587f8e7a266d".parse().unwrap();
/// assert!(eth_addr.is_ethereum_address());
///
/// let non_eth_addr: AccountId = "0x".parse().unwrap();
/// assert!(!non_eth_addr.is_ethereum_address());
/// ```
pub fn is_ethereum_address(&self) -> bool {
self.starts_with("0x") && self.len() == 42
}

/// 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).
Expand Down Expand Up @@ -738,28 +720,6 @@ mod tests {
}
}

#[test]
fn test_is_ethereum_address() {
let valid_ethereum_addresses = &[
"0x06012c8cf97bead5deae237070f9587f8e7a266d",
"0x5e97870f263700f46aa00d967821199b9bc5a120",
"0x0000000000000000000000000000000000000000",
];
for account_id in valid_ethereum_addresses {
assert!(account_id.parse::<AccountId>().unwrap().is_ethereum_address());
}

let non_ethereum_addresses = &[
"alice.near",
"near",
"0x",
"20782e20662e64666420482123494b6b6c677573646b6c66676a646b6c736667",
];
for account_id in non_ethereum_addresses {
assert!(!account_id.parse::<AccountId>().unwrap().is_ethereum_address());
}
}

#[test]
#[cfg(feature = "arbitrary")]
fn test_arbitrary() {
Expand Down
7 changes: 3 additions & 4 deletions core/primitives-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protocol_feature_fix_contract_loading_cost = []
protocol_feature_reject_blocks_with_outdated_protocol_version = []
protocol_feature_simple_nightshade_v2 = []
protocol_feature_block_header_v4 = []
protocol_feature_ethereum_address = []
protocol_feature_restrict_tla = []

nightly = [
"nightly_protocol",
Expand All @@ -46,8 +46,7 @@ nightly = [
"protocol_feature_fix_staking_threshold",
"protocol_feature_reject_blocks_with_outdated_protocol_version",
"protocol_feature_simple_nightshade_v2",
"protocol_feature_ethereum_address",
"protocol_feature_restrict_tla",
]

nightly_protocol = [
]
nightly_protocol = []
8 changes: 4 additions & 4 deletions core/primitives-core/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ pub enum ProtocolFeature {
SimpleNightshadeV2,
#[cfg(feature = "protocol_feature_block_header_v4")]
BlockHeaderV4,
#[cfg(feature = "protocol_feature_ethereum_address")]
EthereumAddress,
#[cfg(feature = "protocol_feature_restrict_tla")]
RestrictTLA,
}

impl ProtocolFeature {
Expand Down Expand Up @@ -180,8 +180,8 @@ impl ProtocolFeature {
ProtocolFeature::SimpleNightshadeV2 => 135,
#[cfg(feature = "protocol_feature_block_header_v4")]
ProtocolFeature::BlockHeaderV4 => 138,
#[cfg(feature = "protocol_feature_ethereum_address")]
ProtocolFeature::EthereumAddress => 139,
#[cfg(feature = "protocol_feature_restrict_tla")]
ProtocolFeature::RestrictTLA => 139,
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ protocol_feature_simple_nightshade_v2 = [
protocol_feature_block_header_v4 = [
"near-primitives-core/protocol_feature_block_header_v4",
]
protocol_feature_ethereum_address = [
"near-primitives-core/protocol_feature_ethereum_address",
protocol_feature_restrict_tla = [
"near-primitives-core/protocol_feature_restrict_tla",
]
nightly = [
"nightly_protocol",
"protocol_feature_ethereum_address",
"protocol_feature_restrict_tla",
"protocol_feature_block_header_v4",
"protocol_feature_fix_contract_loading_cost",
"protocol_feature_fix_staking_threshold",
Expand Down
4 changes: 1 addition & 3 deletions integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ protocol_feature_reject_blocks_with_outdated_protocol_version = [
protocol_feature_simple_nightshade_v2 = [
"near-primitives/protocol_feature_simple_nightshade_v2",
]
protocol_feature_ethereum_address = [
"nearcore/protocol_feature_ethereum_address",
]
protocol_feature_restrict_tla = ["nearcore/protocol_feature_restrict_tla"]

nightly = [
"nightly_protocol",
Expand Down
10 changes: 6 additions & 4 deletions integration-tests/src/tests/standard_cases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,16 +665,18 @@ pub fn test_create_account_failure_already_exists(node: impl Node) {
);
}

pub fn test_create_ethereum_address(node: impl Node) {
pub fn test_create_top_level_account(node: impl Node) {
let account_id = &node.account_id().unwrap();
let node_user = node.user();
let valid_ethereum_addresses = [
let top_level_accounts = [
"0x06012c8cf97bead5deae237070f9587f8e7a266d",
"0x5e97870f263700f46aa00d967821199b9bc5a120",
"0x0000000000000000000000000000000000000000",
"alice",
"thisisaveryverylongtoplevelaccount"
];
for (_, address) in valid_ethereum_addresses.iter().enumerate() {
let new_account_id = address.parse::<AccountId>().unwrap();
for (_, id) in top_level_accounts.iter().enumerate() {
let new_account_id = id.parse::<AccountId>().unwrap();
let transaction_result = node_user
.create_account(account_id.clone(), new_account_id.clone(), node.signer().public_key(), 0)
.unwrap();
Expand Down
7 changes: 3 additions & 4 deletions integration-tests/src/tests/standard_cases/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,8 @@ fn test_storage_read_write_costs_runtime() {
}

#[test]
#[cfg(feature = "protocol_feature_ethereum_address")]
fn test_create_ethereum_address_runtime() {
#[cfg(feature = "protocol_feature_restrict_tla")]
fn test_create_top_level_account_runtime() {
let node = create_runtime_node();
let runtime_config = node.client.as_ref().read().unwrap().runtime_config.clone();
test_create_ethereum_address(node);
test_create_top_level_account(node);
}
8 changes: 4 additions & 4 deletions nearcore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ protocol_feature_fix_contract_loading_cost = [
protocol_feature_simple_nightshade_v2 = [
"near-primitives/protocol_feature_simple_nightshade_v2",
]
protocol_feature_ethereum_address = [
"near-primitives/protocol_feature_ethereum_address",
"node-runtime/protocol_feature_ethereum_address",
protocol_feature_restrict_tla = [
"near-primitives/protocol_feature_restrict_tla",
"node-runtime/protocol_feature_restrict_tla",
]

serialize_all_state_changes = ["near-store/serialize_all_state_changes"]
nightly = [
"nightly_protocol",
"protocol_feature_ethereum_address",
"protocol_feature_restrict_tla",
"protocol_feature_fix_contract_loading_cost",
"protocol_feature_fix_staking_threshold",
"protocol_feature_simple_nightshade_v2",
Expand Down
8 changes: 5 additions & 3 deletions runtime/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ near-store.workspace = true
near-vm-runner.workspace = true

[features]
protocol_feature_ethereum_address = ["near-primitives/protocol_feature_ethereum_address"]
protocol_feature_restrict_tla = [
"near-primitives/protocol_feature_restrict_tla",
]
nightly = [
"nightly_protocol",
"near-chain-configs/nightly",
"near-o11y/nightly",
"near-primitives/nightly",
"near-store/nightly",
"near-vm-runner/nightly",
"protocol_feature_ethereum_address",
"protocol_feature_restrict_tla",
]
default = []
nightly_protocol = [
Expand All @@ -48,7 +50,7 @@ nightly_protocol = [
"near-primitives/nightly_protocol",
"near-store/nightly_protocol",
"near-vm-runner/nightly_protocol",
"protocol_feature_ethereum_address",
"protocol_feature_restrict_tla",
]
no_cpu_compatibility_checks = ["near-vm-runner/no_cpu_compatibility_checks"]

Expand Down
87 changes: 46 additions & 41 deletions runtime/runtime/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,21 @@ pub(crate) fn action_create_account(
current_protocol_version: ProtocolVersion,
) {
if account_id.is_top_level() {
if account_id.len() < account_creation_config.min_allowed_top_level_account_length as usize
&& predecessor_id != &account_creation_config.registrar_account_id
{
let old_condition_for_error = account_id.len()
< account_creation_config.min_allowed_top_level_account_length as usize
&& predecessor_id != &account_creation_config.registrar_account_id;
let new_condition_for_error = !account_id.is_implicit()
&& predecessor_id != &account_creation_config.registrar_account_id;
let is_error = if checked_feature!(
"protocol_feature_restrict_tla",
RestrictTLA,
current_protocol_version
) {
new_condition_for_error
} else {
old_condition_for_error
};
if is_error {
// A short top-level account ID can only be created registrar account.
result.result = Err(ActionErrorKind::CreateAccountOnlyByRegistrar {
account_id: account_id.clone(),
Expand All @@ -396,25 +408,6 @@ pub(crate) fn action_create_account(
}
.into());
return;
} else if checked_feature!(
"protocol_feature_ethereum_address",
EthereumAddress,
current_protocol_version
) {
if account_id.is_ethereum_address()
&& predecessor_id != &account_creation_config.registrar_account_id
{
// An Ethereum address can only be created by the registrar account
result.result = Err(ActionErrorKind::CreateAccountOnlyByRegistrar {
account_id: account_id.clone(),
registrar_account_id: account_creation_config.registrar_account_id.clone(),
predecessor_id: predecessor_id.clone(),
}
.into());
return;
}
} else {
// OK: Valid top-level Account ID
}
} else if !account_id.is_sub_account_of(predecessor_id) {
// The sub-account can only be created by its root account. E.g. `alice.near` only by `near`
Expand Down Expand Up @@ -1021,6 +1014,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "protocol_feature_restrict_tla"))]
fn test_create_account_valid_top_level_long() {
let account_id = "bob_near_long_name".parse().unwrap();
let predecessor_id = "alice.near".parse().unwrap();
Expand Down Expand Up @@ -1063,6 +1057,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "protocol_feature_restrict_tla"))]
fn test_create_account_invalid_short_top_level() {
let account_id = "bob".parse::<AccountId>().unwrap();
let predecessor_id = "near".parse::<AccountId>().unwrap();
Expand All @@ -1082,6 +1077,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "protocol_feature_restrict_tla"))]
fn test_create_account_valid_short_top_level_len_allowed() {
let account_id = "bob".parse().unwrap();
let predecessor_id = "near".parse().unwrap();
Expand All @@ -1090,25 +1086,34 @@ mod tests {
}

#[test]
#[cfg(feature = "protocol_feature_ethereum_address")]
fn test_create_ethereum_address() {
let account_id: AccountId = "0x32400084c286cf3e17e7b677ea9583e60a000324".parse().unwrap();
let predecessor_id: AccountId = "near".parse().unwrap();
let action_result = test_action_create_account(account_id.clone(), predecessor_id.clone(), 32);
assert_eq!(
action_result.result,
Err(ActionError {
index: None,
kind: ActionErrorKind::CreateAccountOnlyByRegistrar {
account_id: account_id.clone(),
registrar_account_id: "registrar".parse().unwrap(),
predecessor_id: predecessor_id,
},
})
);
let registrar_account_id: AccountId = "registrar".parse().unwrap();
let action_result = test_action_create_account(account_id, registrar_account_id, 32);
assert!(action_result.result.is_ok());
#[cfg(feature = "protocol_feature_restrict_tla")]
fn test_create_top_level_account_restriction() {
let account_ids = [
"0x32400084c286cf3e17e7b677ea9583e60a000324",
"thisisaveryverylongtoplevelaccount",
"32400084c286cf3e17e7b677ea9583e60a000324",
"000000000000000000000000000000000000000000000000000000000000000"
];
for id in &account_ids {
let account_id: AccountId = id.parse().unwrap();
let predecessor_id: AccountId = "near".parse().unwrap();
let action_result =
test_action_create_account(account_id.clone(), predecessor_id.clone(), 32);
assert_eq!(
action_result.result,
Err(ActionError {
index: None,
kind: ActionErrorKind::CreateAccountOnlyByRegistrar {
account_id: account_id.clone(),
registrar_account_id: "registrar".parse().unwrap(),
predecessor_id: predecessor_id,
},
})
);
let registrar_account_id: AccountId = "registrar".parse().unwrap();
let action_result = test_action_create_account(account_id, registrar_account_id, 32);
assert!(action_result.result.is_ok());
}
}

fn test_delete_large_account(
Expand Down

0 comments on commit 6a1ec44

Please sign in to comment.