Skip to content

Commit

Permalink
add storage cost for deferred call
Browse files Browse the repository at this point in the history
  • Loading branch information
modship committed Oct 16, 2024
1 parent 46fccbe commit 8ebf906
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 17 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ massa_versioning = { path = "./massa-versioning" }
massa_wallet = { path = "./massa-wallet" }

# Massa projects dependencies
massa-proto-rs = { git = "https://github.com/massalabs/massa-proto-rs", "rev" = "1cce8ec75e0df66af6ce3c5a86350adaea8ac463" }
massa-sc-runtime = { git = "https://github.com/massalabs/massa-sc-runtime", "rev" = "f5fd64c9e05c6d7cc01a30d1ef1dc0c202456a4b" }
massa-proto-rs = { git = "https://github.com/massalabs/massa-proto-rs", "rev" = "67c331c10a1a3f0a9985b3b16c50e31d63074b83" }
massa-sc-runtime = { git = "https://github.com/massalabs/massa-sc-runtime", "rev" = "7289367b2cb490ae1c6c74190d6d36b8d65b30cf" }


peernet = { git = "https://github.com/massalabs/PeerNet", "rev" = "04b05ddd320fbe76cc858115af7b5fc28bdb8310" }
Expand Down
2 changes: 2 additions & 0 deletions massa-api-exports/src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ pub struct DeferredCallsQuoteRequest {
pub target_slot: Slot,
/// The maximum gas requested.
pub max_gas_request: u64,
/// Size of parameters
pub params_size: u64,
}

/// The response to a request for a deferred call quote.
Expand Down
1 change: 1 addition & 0 deletions massa-api/src/public.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,7 @@ impl MassaRpcServer for API<Public> {
.map(|call| ExecutionQueryRequestItem::DeferredCallQuote {
target_slot: call.target_slot,
max_gas_request: call.max_gas_request,
params_size: call.params_size,
})
.collect();

Expand Down
5 changes: 4 additions & 1 deletion massa-deferred-calls/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use massa_models::{
DEFERRED_CALL_GLOBAL_OVERBOOKING_PENALTY, DEFERRED_CALL_MAX_ASYNC_GAS,
DEFERRED_CALL_MAX_FUTURE_SLOTS, DEFERRED_CALL_MAX_POOL_CHANGES, DEFERRED_CALL_MIN_GAS_COST,
DEFERRED_CALL_MIN_GAS_INCREMENT, DEFERRED_CALL_SLOT_OVERBOOKING_PENALTY,
MAX_FUNCTION_NAME_LENGTH, MAX_PARAMETERS_SIZE, THREAD_COUNT,
LEDGER_COST_PER_BYTE, MAX_FUNCTION_NAME_LENGTH, MAX_PARAMETERS_SIZE, THREAD_COUNT,
},
};
use serde::Deserialize;
Expand Down Expand Up @@ -37,6 +37,8 @@ pub struct DeferredCallsConfig {
pub max_pool_changes: u64,

pub max_gas: u64,

pub ledger_cost_per_byte: Amount,
}

impl Default for DeferredCallsConfig {
Expand All @@ -54,6 +56,7 @@ impl Default for DeferredCallsConfig {
global_overbooking_penalty: DEFERRED_CALL_GLOBAL_OVERBOOKING_PENALTY,
slot_overbooking_penalty: DEFERRED_CALL_SLOT_OVERBOOKING_PENALTY,
call_cst_gas_cost: DEFERRED_CALL_CST_GAS_COST,
ledger_cost_per_byte: LEDGER_COST_PER_BYTE,
}
}
}
3 changes: 2 additions & 1 deletion massa-execution-exports/src/mapping_grpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ pub fn to_querystate_filter(
"target slot is required".to_string(),
))?
.into(),
max_gas_request: value.max_gas_request,
max_gas_request: value.max_gas,
params_size: value.params_size,
})
}
exec::RequestItem::DeferredCallInfo(info) => {
Expand Down
2 changes: 2 additions & 0 deletions massa-execution-exports/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ pub enum ExecutionQueryRequestItem {
target_slot: Slot,
/// gas request
max_gas_request: u64,
/// params size
params_size: u64,
},
/// get info of deferred calls
DeferredCallInfo(DeferredCallId),
Expand Down
11 changes: 8 additions & 3 deletions massa-execution-worker/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,15 +1140,20 @@ impl ExecutionContext {
self.speculative_deferred_calls.advance_slot(current_slot)
}

/// Get the price it would cost to reserve "gas" at target slot "slot".
/// Get the price it would cost to reserve "gas" with params at target slot "slot".
pub fn deferred_calls_compute_call_fee(
&self,
target_slot: Slot,
max_gas_request: u64,
current_slot: Slot,
params_size: u64,
) -> Result<Amount, ExecutionError> {
self.speculative_deferred_calls
.compute_call_fee(target_slot, max_gas_request, current_slot)
self.speculative_deferred_calls.compute_call_fee(
target_slot,
max_gas_request,
current_slot,
params_size,
)
}

pub fn deferred_call_register(
Expand Down
7 changes: 6 additions & 1 deletion massa-execution-worker/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,13 @@ impl ExecutionController for ExecutionControllerImpl {
ExecutionQueryRequestItem::DeferredCallQuote {
target_slot,
max_gas_request,
params_size,
} => {
let result = execution_lock.deferred_call_quote(target_slot, max_gas_request);
let result = execution_lock.deferred_call_quote(
target_slot,
max_gas_request,
params_size,
);
Ok(ExecutionQueryResponseItem::DeferredCallQuote(
result.0, result.1, result.2, result.3,
))
Expand Down
8 changes: 7 additions & 1 deletion massa-execution-worker/src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2442,12 +2442,18 @@ impl ExecutionState {
&self,
target_slot: Slot,
max_request_gas: u64,
params_size: u64,
) -> (Slot, u64, bool, Amount) {
let gas_request =
max_request_gas.saturating_add(self.config.deferred_calls_config.call_cst_gas_cost);
let context = context_guard!(self);

match context.deferred_calls_compute_call_fee(target_slot, gas_request, context.slot) {
match context.deferred_calls_compute_call_fee(
target_slot,
gas_request,
context.slot,
params_size,
) {
Ok(fee) => (target_slot, gas_request, true, fee),
Err(_) => (target_slot, gas_request, false, Amount::zero()),
}
Expand Down
11 changes: 9 additions & 2 deletions massa-execution-worker/src/interface_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,7 @@ impl Interface for InterfaceImpl {
&self,
target_slot: (u64, u8),
gas_limit: u64,
params_size: u64,
) -> Result<(bool, u64)> {
// write-lock context

Expand All @@ -1357,7 +1358,12 @@ impl Interface for InterfaceImpl {
let gas_request =
gas_limit.saturating_add(self.config.deferred_calls_config.call_cst_gas_cost);

match context.deferred_calls_compute_call_fee(target_slot, gas_request, current_slot) {
match context.deferred_calls_compute_call_fee(
target_slot,
gas_request,
current_slot,
params_size,
) {
Ok(fee) => Ok((true, fee.to_raw())),
Err(_) => Ok((false, 0)),
}
Expand Down Expand Up @@ -1402,7 +1408,8 @@ impl Interface for InterfaceImpl {
}

// check fee, slot, gas
let (available, fee_raw) = self.get_deferred_call_quote(target_slot, max_gas)?;
let (available, fee_raw) =
self.get_deferred_call_quote(target_slot, max_gas, params.len() as u64)?;
if !available {
bail!("The Deferred call cannot be registered. Ensure that the target slot is not before/at the current slot nor too far in the future, and that it has at least max_gas available gas.");
}
Expand Down
73 changes: 70 additions & 3 deletions massa-execution-worker/src/speculative_deferred_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ impl SpeculativeDeferredCallRegistry {
target_slot: Slot,
max_gas_request: u64,
current_slot: Slot,
params_size: u64,
) -> Result<Amount, ExecutionError> {
// Check that the slot is not in the past
if target_slot <= current_slot {
Expand Down Expand Up @@ -450,6 +451,12 @@ impl SpeculativeDeferredCallRegistry {
));
}

if params_size > self.config.max_parameter_size.into() {
return Err(ExecutionError::DeferredCallsError(
"Parameters size is too big.".into(),
));
}

// We perform Dynamic Pricing of slot gas booking using a Proportional-Integral controller (https://en.wikipedia.org/wiki/Proportional–integral–derivative_controller).
// It regulates the average slot async gas usage towards `target_async_gas` by adjusting fees.

Expand Down Expand Up @@ -486,10 +493,22 @@ impl SpeculativeDeferredCallRegistry {
self.config.slot_overbooking_penalty, // total_initial_coin_supply/10000
)?;

// Storage cost for the parameters
let storage_cost = self
.config
.ledger_cost_per_byte
.checked_mul_u64(params_size)
.ok_or_else(|| {
ExecutionError::DeferredCallsError(
"overflow when calculating storage cost".to_string(),
)
})?;

// return the fee
Ok(integral_fee
.saturating_add(global_overbooking_fee)
.saturating_add(slot_overbooking_fee))
.saturating_add(slot_overbooking_fee)
.saturating_add(storage_cost))
}

/// Register a new call
Expand Down Expand Up @@ -562,13 +581,13 @@ impl SpeculativeDeferredCallRegistry {

#[cfg(test)]
mod tests {
use std::sync::Arc;
use std::{str::FromStr, sync::Arc};

use massa_db_exports::{MassaDBConfig, MassaDBController};
use massa_db_worker::MassaDB;
use massa_deferred_calls::{config::DeferredCallsConfig, DeferredCallRegistry};
use massa_final_state::MockFinalStateController;
use massa_models::{config::THREAD_COUNT, slot::Slot};
use massa_models::{amount::Amount, config::THREAD_COUNT, slot::Slot};
use parking_lot::RwLock;
use tempfile::TempDir;

Expand Down Expand Up @@ -627,6 +646,7 @@ mod tests {
period: 1,
thread: 1,
},
1_000
)
.is_err());

Expand All @@ -642,6 +662,7 @@ mod tests {
period: 5,
thread: 1,
},
1000
)
.is_err());

Expand All @@ -658,9 +679,55 @@ mod tests {
period: 1,
thread: 1,
},
1000
)
.is_err());

// params too big
assert!(speculative
.compute_call_fee(
good_slot,
1_000_000,
Slot {
period: 1,
thread: 1,
},
50_000_000
)
.is_err());

// no params
assert_eq!(
speculative
.compute_call_fee(
good_slot,
200_000,
Slot {
period: 1,
thread: 1,
},
0,
)
.unwrap(),
Amount::from_str("0.000000079").unwrap()
);

// 10Ko params size
assert_eq!(
speculative
.compute_call_fee(
good_slot,
200_000,
Slot {
period: 1,
thread: 1,
},
10_000,
)
.unwrap(),
Amount::from_str("1.000000079").unwrap()
);

// TODO : add more tests with different values and check the results of the fee
}
}
6 changes: 5 additions & 1 deletion massa-node/base_config/openrpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2155,14 +2155,18 @@
"type": "object",
"required": [
"target_slot",
"max_gas_request"
"max_gas_request",
"params_size"
],
"properties": {
"target_slot": {
"$ref": "#/components/schemas/Slot"
},
"max_gas_request": {
"type": "number"
},
"params_size": {
"type": "number"
}
}
},
Expand Down
1 change: 1 addition & 0 deletions massa-node/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ async fn launch(
global_overbooking_penalty: DEFERRED_CALL_GLOBAL_OVERBOOKING_PENALTY,
slot_overbooking_penalty: DEFERRED_CALL_SLOT_OVERBOOKING_PENALTY,
call_cst_gas_cost: DEFERRED_CALL_CST_GAS_COST,
ledger_cost_per_byte: LEDGER_COST_PER_BYTE,
};
let final_state_config = FinalStateConfig {
ledger_config: ledger_config.clone(),
Expand Down

0 comments on commit 8ebf906

Please sign in to comment.