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

runtime: Stabilise NEP264 #6564

Merged
merged 10 commits into from
Apr 15, 2022
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
### Protocol Changes

* Enable access key nonce range for implicit accounts to prevent tx hash collisions [#5482](https://github.com/near/nearcore/pull/5482)
* Include `promise_batch_action_function_call_weight` host function on the runtime. [#6285](https://github.com/near/nearcore/pull/6285) [#6536](https://github.com/near/nearcore/pull/6536)

### Non-protocol Changes

Expand Down
1 change: 0 additions & 1 deletion core/primitives-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ serde_json = "1"
default = []
protocol_feature_alt_bn128 = []
protocol_feature_routing_exchange_algorithm = []
protocol_feature_function_call_weight = []
protocol_feature_chunk_nodes_cache = []
deepsize_feature = [
"deepsize",
Expand Down
2 changes: 0 additions & 2 deletions core/primitives-core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ pub type Gas = u64;

/// Weight of unused gas to distribute to scheduled function call actions.
/// Used in `promise_batch_action_function_call_weight` host function.
#[cfg(feature = "protocol_feature_function_call_weight")]
#[derive(Clone, Debug, PartialEq)]
pub struct GasWeight(pub u64);

/// Result from a gas distribution among function calls with ratios.
#[cfg(feature = "protocol_feature_function_call_weight")]
#[must_use]
#[non_exhaustive]
#[derive(Debug, PartialEq)]
Expand Down
2 changes: 0 additions & 2 deletions core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ protocol_feature_chunk_only_producers = []
protocol_feature_routing_exchange_algorithm = ["near-primitives-core/protocol_feature_routing_exchange_algorithm"]
protocol_feature_access_key_nonce_for_implicit_accounts = []
protocol_feature_fix_staking_threshold = []
protocol_feature_function_call_weight = ["near-primitives-core/protocol_feature_function_call_weight"]
protocol_feature_chunk_nodes_cache = ["near-primitives-core/protocol_feature_chunk_nodes_cache"]
nightly_protocol_features = [
"nightly_protocol",
Expand All @@ -55,7 +54,6 @@ nightly_protocol_features = [
"protocol_feature_routing_exchange_algorithm",
"protocol_feature_access_key_nonce_for_implicit_accounts",
"protocol_feature_fix_staking_threshold",
"protocol_feature_function_call_weight",
"protocol_feature_chunk_nodes_cache",
]
nightly_protocol = []
Expand Down
5 changes: 1 addition & 4 deletions core/primitives/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ pub enum ProtocolFeature {
/// alpha is min stake ratio
#[cfg(feature = "protocol_feature_fix_staking_threshold")]
FixStakingThreshold,
#[cfg(feature = "protocol_feature_function_call_weight")]
FunctionCallWeight,
/// Ensure caching all nodes in the chunk for which touching trie node cost was charged. Charge for each such node
/// only once per chunk at the first access time.
Expand Down Expand Up @@ -225,7 +224,7 @@ impl ProtocolFeature {
ProtocolFeature::SynchronizeBlockChunkProduction
| ProtocolFeature::CorrectStackLimit => 50,
ProtocolFeature::AccessKeyNonceForImplicitAccounts => 51,
ProtocolFeature::IncreaseDeploymentCost => 53,
ProtocolFeature::IncreaseDeploymentCost | ProtocolFeature::FunctionCallWeight => 53,

// Nightly features
#[cfg(feature = "protocol_feature_alt_bn128")]
Expand All @@ -236,8 +235,6 @@ impl ProtocolFeature {
ProtocolFeature::RoutingExchangeAlgorithm => 117,
#[cfg(feature = "protocol_feature_fix_staking_threshold")]
ProtocolFeature::FixStakingThreshold => 126,
#[cfg(feature = "protocol_feature_function_call_weight")]
ProtocolFeature::FunctionCallWeight => 127,
#[cfg(feature = "protocol_feature_chunk_nodes_cache")]
ProtocolFeature::ChunkNodesCache => 128,
}
Expand Down
5 changes: 5 additions & 0 deletions runtime/near-test-contracts/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ fn try_main() -> Result<(), Error> {
&["--features", "base_protocol"],
"test_contract_rs_base_protocol",
)?;
build_contract(
"./test-contract-rs",
&["--features", "protocol_feature_function_call_weight"],
"test_contract_rs_function_call_weight",
)?;
mina86 marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
}

Expand Down
5 changes: 5 additions & 0 deletions runtime/near-test-contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ pub fn rs_contract_base_protocol() -> &'static [u8] {
CONTRACT.get_or_init(|| read_contract("test_contract_rs_base_protocol.wasm")).as_slice()
}

pub fn function_call_weight_rs_contract() -> &'static [u8] {
static CONTRACT: OnceCell<Vec<u8>> = OnceCell::new();
CONTRACT.get_or_init(|| read_contract("test_contract_rs_function_call_weight.wasm")).as_slice()
}

pub fn nightly_rs_contract() -> &'static [u8] {
static CONTRACT: OnceCell<Vec<u8>> = OnceCell::new();
CONTRACT.get_or_init(|| read_contract("nightly_test_contract_rs.wasm")).as_slice()
Expand Down
1 change: 1 addition & 0 deletions runtime/near-test-contracts/test-contract-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ members = []
[features]
nightly_protocol_features = ["protocol_feature_alt_bn128"]
protocol_feature_alt_bn128 = []
protocol_feature_function_call_weight = []
base_protocol = []
82 changes: 82 additions & 0 deletions runtime/near-test-contracts/test-contract-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ extern "C" {
amount_ptr: u64,
gas: u64,
);
#[cfg(feature = "protocol_feature_function_call_weight")]
fn promise_batch_action_function_call_weight(
promise_index: u64,
method_name_len: u64,
method_name_ptr: u64,
arguments_len: u64,
arguments_ptr: u64,
amount_ptr: u64,
gas: u64,
gas_weight: u64,
);
fn promise_batch_action_transfer(promise_index: u64, amount_ptr: u64);
fn promise_batch_action_stake(
promise_index: u64,
Expand Down Expand Up @@ -141,6 +152,7 @@ extern "C" {
fn storage_iter_prefix(prefix_len: u64, prefix_ptr: u64) -> u64;
fn storage_iter_range(start_len: u64, start_ptr: u64, end_len: u64, end_ptr: u64) -> u64;
fn storage_iter_next(iterator_id: u64, key_register_id: u64, value_register_id: u64) -> u64;
fn gas(ops: u32);
// #################
// # Validator API #
// #################
Expand Down Expand Up @@ -771,6 +783,76 @@ fn call_promise() {
}
}

#[cfg(feature = "protocol_feature_function_call_weight")]
#[no_mangle]
fn attach_unspent_gas_but_burn_all_gas() {
unsafe {
let account_id = "alice.near";
let promise_idx = promise_batch_create(account_id.len() as u64, account_id.as_ptr() as u64);

let method_name = "f";
let arguments_ptr = 0;
let arguments_len = 0;
let amount = 1u128;
let gas_fixed = 0;
let gas_weight = 1;
promise_batch_action_function_call_weight(
promise_idx,
method_name.len() as u64,
method_name.as_ptr() as u64,
arguments_ptr,
arguments_len,
&amount as *const u128 as u64,
gas_fixed,
gas_weight,
);
loop {
gas(10_000);
}
}
}

#[cfg(feature = "protocol_feature_function_call_weight")]
#[no_mangle]
fn attach_unspent_gas_but_use_all_gas() {
unsafe {
let account_id = "alice.near";
let promise_idx = promise_batch_create(account_id.len() as u64, account_id.as_ptr() as u64);

let method_name = "f";
let arguments_ptr = 0;
let arguments_len = 0;
let amount = 1u128;
let gas_fixed = 0;
let gas_weight = 1;
promise_batch_action_function_call_weight(
promise_idx,
method_name.len() as u64,
method_name.as_ptr() as u64,
arguments_ptr,
arguments_len,
&amount as *const u128 as u64,
gas_fixed,
gas_weight,
);

let promise_idx = promise_batch_create(account_id.len() as u64, account_id.as_ptr() as u64);

let gas_fixed = 10u64.pow(14);
let gas_weight = 0;
promise_batch_action_function_call_weight(
promise_idx,
method_name.len() as u64,
method_name.as_ptr() as u64,
arguments_ptr,
arguments_len,
&amount as *const u128 as u64,
gas_fixed,
gas_weight,
);
}
}

#[cfg(not(feature = "base_protocol"))]
#[no_mangle]
fn do_ripemd() {
Expand Down
4 changes: 0 additions & 4 deletions runtime/near-vm-logic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ protocol_feature_alt_bn128 = [
"near-primitives-core/protocol_feature_alt_bn128",
"near-vm-errors/protocol_feature_alt_bn128",
]
protocol_feature_function_call_weight = [
"near-primitives/protocol_feature_function_call_weight",
"near-primitives-core/protocol_feature_function_call_weight",
]
protocol_feature_chunk_nodes_cache = ["near-primitives/protocol_feature_chunk_nodes_cache"]

# Use this feature to enable counting of fees and costs applied.
Expand Down
59 changes: 10 additions & 49 deletions runtime/near-vm-logic/src/logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use near_primitives_core::runtime::fees::{
use near_primitives_core::types::{
AccountId, Balance, EpochHeight, Gas, ProtocolVersion, StorageUsage,
};
#[cfg(feature = "protocol_feature_function_call_weight")]
use near_primitives_core::types::{GasDistribution, GasWeight};
use near_vm_errors::InconsistentStateError;
use near_vm_errors::{HostError, VMLogicError};
Expand Down Expand Up @@ -1570,24 +1569,15 @@ impl<'a> VMLogic<'a> {
amount_ptr: u64,
gas: Gas,
) -> Result<()> {
let append_action_fn = |vm: &mut Self, receipt_idx, method_name, arguments, amount, gas| {
vm.receipt_manager.append_action_function_call(
receipt_idx,
method_name,
arguments,
amount,
gas,
)
};
self.internal_promise_batch_action_function_call(
self.promise_batch_action_function_call_weight(
promise_idx,
method_name_len,
method_name_ptr,
arguments_len,
arguments_ptr,
amount_ptr,
gas,
append_action_fn,
0,
)
}

Expand Down Expand Up @@ -1627,7 +1617,6 @@ impl<'a> VMLogic<'a> {
/// `amount_ptr + 16` points outside the memory of the guest or host returns
/// `MemoryAccessViolation`.
/// * If called as view function returns `ProhibitedInView`.
#[cfg(feature = "protocol_feature_function_call_weight")]
pub fn promise_batch_action_function_call_weight(
&mut self,
promise_idx: u64,
Expand All @@ -1638,39 +1627,6 @@ impl<'a> VMLogic<'a> {
amount_ptr: u64,
gas: Gas,
gas_weight: u64,
) -> Result<()> {
let append_action_fn = |vm: &mut Self, receipt_idx, method_name, arguments, amount, gas| {
vm.receipt_manager.append_action_function_call_weight(
receipt_idx,
method_name,
arguments,
amount,
gas,
GasWeight(gas_weight),
)
};
self.internal_promise_batch_action_function_call(
promise_idx,
method_name_len,
method_name_ptr,
arguments_len,
arguments_ptr,
amount_ptr,
gas,
append_action_fn,
)
}

fn internal_promise_batch_action_function_call(
&mut self,
promise_idx: u64,
method_name_len: u64,
method_name_ptr: u64,
arguments_len: u64,
arguments_ptr: u64,
amount_ptr: u64,
gas: Gas,
append_action_fn: impl FnOnce(&mut Self, u64, Vec<u8>, Vec<u8>, u128, u64) -> Result<()>,
) -> Result<()> {
self.gas_counter.pay_base(base)?;
if self.context.is_view() {
Expand Down Expand Up @@ -1706,7 +1662,14 @@ impl<'a> VMLogic<'a> {

self.deduct_balance(amount)?;

append_action_fn(self, receipt_idx, method_name, arguments, amount, gas)
self.receipt_manager.append_action_function_call_weight(
receipt_idx,
method_name,
arguments,
amount,
gas,
GasWeight(gas_weight),
)
}

/// Appends `Transfer` action to the batch of actions for the given promise pointed by
Expand Down Expand Up @@ -2670,9 +2633,7 @@ impl<'a> VMLogic<'a> {
/// If `FunctionCallWeight` protocol feature (127) is enabled, unused gas will be
/// distributed to functions that specify a gas weight. If there are no functions with
/// a gas weight, the outcome will contain unused gas as usual.
#[cfg_attr(not(feature = "protocol_feature_function_call_weight"), allow(unused_mut))]
pub fn compute_outcome_and_distribute_gas(mut self) -> VMOutcome {
#[cfg(feature = "protocol_feature_function_call_weight")]
if !self.context.is_view() {
// Distribute unused gas to scheduled function calls
let unused_gas = self.gas_counter.unused_gas();
Expand Down
Loading