Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: enforce that account_ids are valid in FunctionCallPermission #7139

Merged
merged 2 commits into from
Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions chain/chain/src/tests/simple_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn build_chain() {
// cargo insta test --accept -p near-chain --features nightly -- tests::simple_chain::build_chain
let hash = chain.head().unwrap().last_block_hash;
if cfg!(feature = "nightly") {
insta::assert_display_snapshot!(hash, @"AzXEGtscMJaA5td3Nxdrmv2eC3SaYD2spydh3WDbRjAh");
insta::assert_display_snapshot!(hash, @"FxxmGH4peXwKR5C9YiSKjX7nWVg3zBuvjp9k5bTF1yDs");
} else {
insta::assert_display_snapshot!(hash, @"6sAno2uEwwQ5yiDscePWY8HWmRJLpGNv39uoff3BCpxT");
}
Expand Down Expand Up @@ -68,7 +68,7 @@ fn build_chain() {

let hash = chain.head().unwrap().last_block_hash;
if cfg!(feature = "nightly") {
insta::assert_display_snapshot!(hash, @"BkaWorGLVNsKyzS1HXXur1sNYDhSCssNvAnbP1TtW2az");
insta::assert_display_snapshot!(hash, @"43q5wcc9rdsocY2Htbk7vT88x6zkka5Vr17CQJUTkT9n");
} else {
insta::assert_display_snapshot!(hash, @"Fn9MgjUx6VXhPYNqqDtf2C9kBVveY2vuSLXNLZUNJCqK");
}
Expand Down
54 changes: 54 additions & 0 deletions core/primitives-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ pub struct VMLimitConfig {
/// If present, stores max number of locals declared globally in one contract
#[serde(skip_serializing_if = "Option::is_none")]
pub max_locals_per_contract: Option<u64>,
/// Whether to enforce account_id well-formedness where it wasn't enforced
/// historically.
#[serde(default = "AccountIdValidityRulesVersion::v0")]
pub account_id_validity_rules_version: AccountIdValidityRulesVersion,
}

fn wasmer2_stack_limit_default() -> i32 {
Expand Down Expand Up @@ -154,6 +158,55 @@ impl<'de> Deserialize<'de> for StackLimiterVersion {
}
}

#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum AccountIdValidityRulesVersion {
/// Skip account ID validation according to legacy rules.
V0,
/// Limit `receiver_id` in `FunctionCallPermission` to be a valid account ID.
V1,
}

impl AccountIdValidityRulesVersion {
fn v0() -> AccountIdValidityRulesVersion {
AccountIdValidityRulesVersion::V0
}
fn repr(self) -> u32 {
match self {
AccountIdValidityRulesVersion::V0 => 0,
AccountIdValidityRulesVersion::V1 => 1,
}
}
fn from_repr(repr: u32) -> Option<AccountIdValidityRulesVersion> {
let res = match repr {
0 => AccountIdValidityRulesVersion::V0,
1 => AccountIdValidityRulesVersion::V1,
_ => return None,
};
Some(res)
}
}

impl Serialize for AccountIdValidityRulesVersion {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.repr().serialize(serializer)
}
}

impl<'de> Deserialize<'de> for AccountIdValidityRulesVersion {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
u32::deserialize(deserializer).and_then(|repr| {
AccountIdValidityRulesVersion::from_repr(repr)
.ok_or_else(|| serde::de::Error::custom("invalid account_id_validity_rules"))
})
}
}

impl VMConfig {
pub fn test() -> VMConfig {
VMConfig {
Expand Down Expand Up @@ -234,6 +287,7 @@ impl VMLimitConfig {
// necessary (they only take constant operands indicating the local to access), which
// is 4 bytes worth of code for each local.
max_locals_per_contract: Some(max_contract_size / 4),
account_id_validity_rules_version: AccountIdValidityRulesVersion::V1,
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions core/primitives-core/src/parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ pub enum Parameter {
MaxFunctionsNumberPerContract,
Wasmer2StackLimit,
MaxLocalsPerContract,
AccountIdValidityRulesVersion,
}

#[derive(
Expand Down Expand Up @@ -303,6 +304,7 @@ impl Parameter {
Parameter::MaxFunctionsNumberPerContract,
Parameter::Wasmer2StackLimit,
Parameter::MaxLocalsPerContract,
Parameter::AccountIdValidityRulesVersion,
]
.iter()
}
Expand Down
2 changes: 2 additions & 0 deletions core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"]
protocol_feature_chunk_only_producers = []
protocol_feature_fix_staking_threshold = []
protocol_feature_fix_contract_loading_cost = []
protocol_feature_account_id_in_function_call_permission = []
nightly = [
"nightly_protocol",
"protocol_feature_chunk_only_producers",
"protocol_feature_fix_staking_threshold",
"protocol_feature_fix_contract_loading_cost",
"protocol_feature_account_id_in_function_call_permission",
]
nightly_protocol = []

Expand Down
1 change: 1 addition & 0 deletions core/primitives/res/runtime_configs/130.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
account_id_validity_rules_version: 0 -> 1
2 changes: 2 additions & 0 deletions core/primitives/res/runtime_configs/parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,5 @@ max_length_storage_key: 4_194_304
max_length_storage_value: 4_194_304
max_promises_per_function_call_action: 1_024
max_number_input_data_dependencies: 128
stack_limiter_version: 0
account_id_validity_rules_version: 0
2 changes: 1 addition & 1 deletion core/primitives/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ pub enum ActionsValidationError {
/// Integer overflow during a compute.
IntegerOverflow,
/// Invalid account ID.
InvalidAccountId { account_id: AccountId },
InvalidAccountId { account_id: String },
/// The size of the contract code exceeded the limit in a DeployContract action.
ContractSizeExceeded { size: u64, limit: u64 },
/// The length of the method name exceeded the limit in a Function Call action.
Expand Down
2 changes: 2 additions & 0 deletions core/primitives/src/runtime/config_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ static CONFIG_DIFFS: &[(ProtocolVersion, &str)] = &[
// Increased deployment costs, increased wasmer2 stack_limit, added limiting of contract locals,
// set read_cached_trie_node cost, decrease storage key limit
(53, include_config!("53.txt")),
#[cfg(feature = "protocol_feature_account_id_in_function_call_permission")]
(130, include_config!("130.txt")),
];

/// Testnet parameters for versions <= 29, which (incorrectly) differed from mainnet parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ expression: store.get_config(*version)
"max_length_storage_value": 4194304,
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ expression: store.get_config(*version)
"max_length_storage_value": 4194304,
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ expression: store.get_config(*version)
"max_length_storage_value": 4194304,
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ expression: store.get_config(*version)
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ expression: store.get_config(*version)
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ expression: store.get_config(*version)
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ expression: store.get_config(*version)
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000,
"wasmer2_stack_limit": 204800,
"max_locals_per_contract": 1000000
"max_locals_per_contract": 1000000,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ expression: store.get_config(*version)
"max_length_storage_value": 4194304,
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ expression: store.get_config(*version)
"max_length_storage_value": 4194304,
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ expression: store.get_config(*version)
"max_length_storage_value": 4194304,
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ expression: store.get_config(*version)
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ expression: store.get_config(*version)
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ expression: store.get_config(*version)
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000,
"wasmer2_stack_limit": 102400
"wasmer2_stack_limit": 102400,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ expression: store.get_config(*version)
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000,
"wasmer2_stack_limit": 204800,
"max_locals_per_contract": 1000000
"max_locals_per_contract": 1000000,
"account_id_validity_rules_version": 0
}
},
"account_creation_config": {
Expand Down
7 changes: 6 additions & 1 deletion core/primitives/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ pub enum ProtocolFeature {
/// Charge for contract loading before it happens.
#[cfg(feature = "protocol_feature_fix_contract_loading_cost")]
FixContractLoadingCost,
/// Charge for contract loading before it happens.
#[cfg(feature = "protocol_feature_account_id_in_function_call_permission")]
AccountIdInFunctionCallPermission,
}

/// Both, outgoing and incoming tcp connections to peers, will be rejected if `peer's`
Expand All @@ -176,7 +179,7 @@ const STABLE_PROTOCOL_VERSION: ProtocolVersion = 55;
cfg_if::cfg_if! {
if #[cfg(feature = "nightly_protocol")] {
/// Current latest nightly version of the protocol.
pub const PROTOCOL_VERSION: ProtocolVersion = 129;
pub const PROTOCOL_VERSION: ProtocolVersion = 130;
} else if #[cfg(feature = "shardnet")] {
/// Protocol version for shardnet.
pub const PROTOCOL_VERSION: ProtocolVersion = 100;
Expand Down Expand Up @@ -247,6 +250,8 @@ impl ProtocolFeature {
ProtocolFeature::FixStakingThreshold => 126,
#[cfg(feature = "protocol_feature_fix_contract_loading_cost")]
ProtocolFeature::FixContractLoadingCost => 129,
#[cfg(feature = "protocol_feature_account_id_in_function_call_permission")]
ProtocolFeature::AccountIdInFunctionCallPermission => 130,
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,14 @@ protocol_feature_chunk_only_producers = [
"near-client/protocol_feature_chunk_only_producers",
"near-primitives/protocol_feature_chunk_only_producers",
]
protocol_feature_account_id_in_function_call_permission = [
"near-primitives/protocol_feature_account_id_in_function_call_permission"
]
nightly = [
"nightly_protocol",
"nearcore/nightly",
"protocol_feature_chunk_only_producers",
"protocol_feature_account_id_in_function_call_permission",
]
nightly_protocol = ["nearcore/nightly_protocol"]
sandbox = [
Expand Down
Loading