Skip to content

Commit

Permalink
feat: stabilize limiting functions number in a contract (near#5361)
Browse files Browse the repository at this point in the history
Stabilize limiting functions number in a contract to 10_000: near#4954

While discussing near#4826, we found that both contract compilation and function call require a lot of time, if number of wasm functions in it is huge. Even if we fix contract size, function number still makes a big difference.

To mitigate this issue, we limit number of functions in a contract. This shouldn't affect current mainnet contracts because maximal number of functions is ~5k.

## Test plan

* http://nayduck.near.org/#/run/2223
* existing tests
  • Loading branch information
Longarithm authored Nov 20, 2021
1 parent 076fb3e commit cd575e5
Show file tree
Hide file tree
Showing 15 changed files with 28 additions and 243 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
### Protocol Changes

* Further lower regular_op_cost from 2_207_874 to 822_756.
* Limit number of wasm functions in one contract to 10_000. [#4954](https://github.com/near/nearcore/pull/4954)

## `1.22.0` []
## `1.22.0` [11-15-2021]

### Protocol Changes
* Upgrade from Wasmer 0 to Wasmer 2, bringing better performance and reliability. [#4934](https://github.com/near/nearcore/pull/4934)
Expand Down
8 changes: 7 additions & 1 deletion chain/jsonrpc/res/rpc_errors_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@
"GasInstrumentation",
"StackHeightInstrumentation",
"Instantiate",
"Memory"
"Memory",
"TooManyFunctions"
],
"props": {}
},
Expand Down Expand Up @@ -350,6 +351,11 @@
"subtypes": [],
"props": {}
},
"TooManyFunctions": {
"name": "TooManyFunctions",
"subtypes": [],
"props": {}
},
"TotalLogLengthExceeded": {
"name": "TotalLogLengthExceeded",
"subtypes": [],
Expand Down
3 changes: 1 addition & 2 deletions core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ protocol_feature_block_header_v3 = []
protocol_feature_alt_bn128 = ["near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"]
protocol_feature_chunk_only_producers = ["protocol_feature_block_header_v3"]
protocol_feature_routing_exchange_algorithm = ["near-primitives-core/protocol_feature_routing_exchange_algorithm"]
protocol_feature_limit_contract_functions_number = []
nightly_protocol_features = ["nightly_protocol", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_chunk_only_producers", "protocol_feature_routing_exchange_algorithm", "protocol_feature_limit_contract_functions_number"]
nightly_protocol_features = ["nightly_protocol", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_chunk_only_producers", "protocol_feature_routing_exchange_algorithm"]
nightly_protocol = []

[dev-dependencies]
Expand Down
6 changes: 1 addition & 5 deletions core/primitives/src/runtime/config_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ static CONFIGS: &[(ProtocolVersion, &[u8])] = &[
(42, include_config!("42.json")),
(48, include_config!("48.json")),
(49, include_config!("49.json")),
#[cfg(feature = "protocol_feature_limit_contract_functions_number")]
(123, include_config!("123.json")),
];

pub static INITIAL_TESTNET_CONFIG: &[u8] = include_config!("29_testnet.json");
Expand Down Expand Up @@ -118,9 +116,7 @@ mod tests {
"FF2Qg5qSM6iWQjD5ZyzEhdAV2g5MyQKXGYh4kyt8mMcE",
"97UzHtVFBc4235jdur3DgNSUGNfGQfzRDLmAkYdZ19Re",
"C6uw6BoeXr3KoKpVP34hBA7TqoywMbwMtJgqbTpPCiSB",
"9pnVZ23PC8YAJ966RtEBrQ3sw7DUn8a19arEpq3f8AhF",
#[cfg(feature = "protocol_feature_limit_contract_functions_number")]
"AFpppR4PmSe4YBWzcyyH8vzLCeDbzfTRjeCGPVrmpPJj",
"2cuq2HvuHT7Z27LUbgEtMxP2ejqrHK34J2V1GL1joiMn",
];
let actual_hashes = CONFIGS
.iter()
Expand Down
12 changes: 5 additions & 7 deletions core/primitives/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ pub enum ProtocolFeature {
/// Lowers the cost of wasm instruction due to switch to faster,
/// compiler-intrinsics based gas counter.
LowerRegularOpCost2,
/// Limit number of wasm functions in one contract. See
/// <https://github.com/near/nearcore/pull/4954> for more details.
LimitContractFunctionsNumber,

// nightly features
#[cfg(feature = "protocol_feature_block_header_v3")]
Expand All @@ -127,10 +130,6 @@ pub enum ProtocolFeature {
ChunkOnlyProducers,
#[cfg(feature = "protocol_feature_routing_exchange_algorithm")]
RoutingExchangeAlgorithm,
/// Limit number of wasm functions in one contract. See
/// <https://github.com/near/nearcore/pull/4954> for more details.
#[cfg(feature = "protocol_feature_limit_contract_functions_number")]
LimitContractFunctionsNumber,
}

/// Current latest stable version of the protocol.
Expand Down Expand Up @@ -164,7 +163,8 @@ impl ProtocolFeature {
| ProtocolFeature::LowerDataReceiptAndEcrecoverBaseCost
| ProtocolFeature::LowerRegularOpCost
| ProtocolFeature::SimpleNightshade => 48,
ProtocolFeature::LowerRegularOpCost2 => 49,
ProtocolFeature::LowerRegularOpCost2
| ProtocolFeature::LimitContractFunctionsNumber => 49,

// Nightly features
#[cfg(feature = "protocol_feature_alt_bn128")]
Expand All @@ -175,8 +175,6 @@ impl ProtocolFeature {
ProtocolFeature::ChunkOnlyProducers => 115,
#[cfg(feature = "protocol_feature_routing_exchange_algorithm")]
ProtocolFeature::RoutingExchangeAlgorithm => 117,
#[cfg(feature = "protocol_feature_limit_contract_functions_number")]
ProtocolFeature::LimitContractFunctionsNumber => 123,
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ protocol_feature_alt_bn128 = [
]
protocol_feature_block_header_v3 = ["near-primitives/protocol_feature_block_header_v3", "near-chain/protocol_feature_block_header_v3", "near-store/protocol_feature_block_header_v3"]
protocol_feature_chunk_only_producers = ["near-client/protocol_feature_chunk_only_producers"]
protocol_feature_limit_contract_functions_number = ["near-primitives/protocol_feature_limit_contract_functions_number", "near-vm-runner/protocol_feature_limit_contract_functions_number"]
nightly_protocol_features = ["nearcore/nightly_protocol_features", "protocol_feature_alt_bn128", "protocol_feature_block_header_v3", "protocol_feature_limit_contract_functions_number"]
nightly_protocol_features = ["nearcore/nightly_protocol_features", "protocol_feature_alt_bn128", "protocol_feature_block_header_v3"]
nightly_protocol = ["nearcore/nightly_protocol"]
sandbox = ["near-network/sandbox", "near-chain/sandbox", "node-runtime/sandbox", "near-client/sandbox"]
no_cache = ["nearcore/no_cache"]
no_cache = ["nearcore/no_cache"]
20 changes: 7 additions & 13 deletions integration-tests/tests/client/process_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use near_primitives::hash::{hash, CryptoHash};
use near_primitives::merkle::verify_hash;
use near_primitives::receipt::DelayedReceiptIndices;
use near_primitives::runtime::config::RuntimeConfig;
#[cfg(not(feature = "protocol_feature_block_header_v3"))]
use near_primitives::runtime::config_store::RuntimeConfigStore;
use near_primitives::shard_layout::ShardUId;
#[cfg(not(feature = "protocol_feature_block_header_v3"))]
Expand All @@ -57,7 +58,7 @@ use near_primitives::types::validator_stake::ValidatorStake;
use near_primitives::types::{AccountId, BlockHeight, EpochId, NumBlocks, ProtocolVersion};
use near_primitives::utils::to_timestamp;
use near_primitives::validator_signer::{InMemoryValidatorSigner, ValidatorSigner};
#[cfg(feature = "protocol_feature_limit_contract_functions_number")]
#[cfg(not(feature = "protocol_feature_block_header_v3"))]
use near_primitives::version::ProtocolFeature;
use near_primitives::version::PROTOCOL_VERSION;
use near_primitives::views::{
Expand Down Expand Up @@ -3192,15 +3193,12 @@ fn test_validator_stake_host_function() {
}

// Check that we can't call a contract exceeding functions number limit after upgrade.
#[cfg(not(feature = "protocol_feature_block_header_v3"))]
#[test]
fn test_limit_contract_functions_number_upgrade() {
let functions_number_limit: u32 = 10_000;

#[cfg(feature = "protocol_feature_limit_contract_functions_number")]
let old_protocol_version = ProtocolFeature::LimitContractFunctionsNumber.protocol_version() - 1;
#[cfg(not(feature = "protocol_feature_limit_contract_functions_number"))]
let old_protocol_version = PROTOCOL_VERSION - 1;

let new_protocol_version = old_protocol_version + 1;

// Prepare TestEnv with a contract at the old protocol version.
Expand Down Expand Up @@ -3288,14 +3286,10 @@ fn test_limit_contract_functions_number_upgrade() {
};

assert!(matches!(old_outcome.status, FinalExecutionStatus::SuccessValue(_)));
if cfg!(feature = "protocol_feature_limit_contract_functions_number") {
assert!(matches!(
new_outcome.status,
FinalExecutionStatus::Failure(TxExecutionError::ActionError(_))
));
} else {
assert!(matches!(new_outcome.status, FinalExecutionStatus::SuccessValue(_)));
}
assert!(matches!(
new_outcome.status,
FinalExecutionStatus::Failure(TxExecutionError::ActionError(_))
));
}

mod access_key_nonce_range_tests {
Expand Down
3 changes: 1 addition & 2 deletions nearcore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ protocol_feature_alt_bn128 = ["near-primitives/protocol_feature_alt_bn128", "nod
protocol_feature_block_header_v3 = ["near-epoch-manager/protocol_feature_block_header_v3", "near-store/protocol_feature_block_header_v3", "near-primitives/protocol_feature_block_header_v3", "near-chain/protocol_feature_block_header_v3", "near-client/protocol_feature_block_header_v3"]
protocol_feature_chunk_only_producers = ["protocol_feature_block_header_v3", "near-chain-configs/protocol_feature_chunk_only_producers", "near-epoch-manager/protocol_feature_chunk_only_producers", "near-chain/protocol_feature_chunk_only_producers", "near-client/protocol_feature_chunk_only_producers", "node-runtime/protocol_feature_chunk_only_producers", "near-rosetta-rpc/protocol_feature_chunk_only_producers"]
protocol_feature_routing_exchange_algorithm = ["near-primitives/protocol_feature_routing_exchange_algorithm", "near-chain/protocol_feature_routing_exchange_algorithm", "near-network/protocol_feature_routing_exchange_algorithm", "near-client/protocol_feature_routing_exchange_algorithm", "near-jsonrpc/protocol_feature_routing_exchange_algorithm"]
protocol_feature_limit_contract_functions_number = ["near-primitives/protocol_feature_limit_contract_functions_number", "near-vm-runner/protocol_feature_limit_contract_functions_number"]
nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protocol_features", "near-client/nightly_protocol_features", "near-epoch-manager/nightly_protocol_features", "near-store/nightly_protocol_features", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_chunk_only_producers", "protocol_feature_routing_exchange_algorithm", "protocol_feature_limit_contract_functions_number"]
nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protocol_features", "near-client/nightly_protocol_features", "near-epoch-manager/nightly_protocol_features", "near-store/nightly_protocol_features", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_chunk_only_producers", "protocol_feature_routing_exchange_algorithm"]
nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_protocol"]

# Force usage of a specific wasm vm irrespective of protocol version.
Expand Down
192 changes: 0 additions & 192 deletions nearcore/res/runtime_configs/123.json

This file was deleted.

3 changes: 2 additions & 1 deletion nearcore/res/runtime_configs/49.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@
"max_length_storage_key": 4194304,
"max_length_storage_value": 4194304,
"max_promises_per_function_call_action": 1024,
"max_number_input_data_dependencies": 128
"max_number_input_data_dependencies": 128,
"max_functions_number_per_contract": 10000
}
},
"account_creation_config": {
Expand Down
1 change: 0 additions & 1 deletion runtime/near-vm-errors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ near-rpc-error-macro = { path = "../../tools/rpctypegen/macro", version = "0.1.0
[features]
dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"]
protocol_feature_alt_bn128 = []
protocol_feature_limit_contract_functions_number = []

[package.metadata.workspaces]
independent = true
Loading

0 comments on commit cd575e5

Please sign in to comment.