Skip to content

Commit

Permalink
fix: refine cycles cost calculation (#143)
Browse files Browse the repository at this point in the history
* Refine cycles cost calculation

* Update tests

* Fix

* Rename for clarity

* Update unit test

* Update Cargo.lock
  • Loading branch information
rvanasa authored Jan 23, 2024
1 parent 72741c7 commit 0b5c52d
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 15 deletions.
4 changes: 2 additions & 2 deletions e2e/motoko/Main.mo
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ shared ({ caller = installer }) actor class Main() {

let canisterDetails = [
// (`canister module`, `debug name`, `nodes in subnet`, `expected cycles for JSON-RPC call`)
(EvmRpcCanister, "default", 13, 65_923_200),
(EvmRpcFidicuaryCanister, "fiduciary", 28, 141_988_430),
(EvmRpcCanister, "default", 13, 61_898_400),
(EvmRpcFidicuaryCanister, "fiduciary", 28, 133_319_630),
];
for ((canister, name, nodesInSubnet, expectedCycles) in canisterDetails.vals()) {
Debug.print("Testing " # name # " canister...");
Expand Down
33 changes: 22 additions & 11 deletions src/accounting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ pub fn get_http_request_cost(
+ INGRESS_OVERHEAD_BYTES;
let base_cost = INGRESS_MESSAGE_RECEIVED_COST
+ INGRESS_MESSAGE_BYTE_RECEIVED_COST * ingress_bytes
+ HTTP_OUTCALL_REQUEST_COST
+ HTTP_OUTCALL_BYTE_RECEIVED_COST * (ingress_bytes + max_response_bytes as u128);
+ HTTP_OUTCALL_REQUEST_BASE_COST
+ HTTP_OUTCALL_REQUEST_COST_PER_BYTE * payload_size_bytes as u128
+ HTTP_OUTCALL_RESPONSE_COST_PER_BYTE * max_response_bytes as u128;
base_cost * (nodes_in_subnet as u128) / NODES_IN_DEFAULT_SUBNET as u128
}

Expand Down Expand Up @@ -80,7 +81,7 @@ fn test_request_cost() {
1000,
);
let estimated_cost_10_extra_bytes = base_cost
+ 10 * (INGRESS_MESSAGE_BYTE_RECEIVED_COST + HTTP_OUTCALL_BYTE_RECEIVED_COST)
+ 10 * (INGRESS_MESSAGE_BYTE_RECEIVED_COST + HTTP_OUTCALL_REQUEST_COST_PER_BYTE)
* nodes_in_subnet as u128
/ NODES_IN_DEFAULT_SUBNET as u128;
// Request body with 10 additional bytes should be within 1 cycle of expected cost (due to rounding)
Expand Down Expand Up @@ -155,15 +156,25 @@ fn test_candid_rpc_cost() {
let provider = PROVIDERS.with(|providers| providers.borrow().get(&provider_id).unwrap());

// Default subnet
assert_eq!(get_candid_rpc_cost(&provider, 0, 0), 54767387);
assert_eq!(get_candid_rpc_cost(&provider, 123, 123), 59170787);
assert_eq!(get_candid_rpc_cost(&provider, 123, 4567890), 47563947587);
assert_eq!(get_candid_rpc_cost(&provider, 890, 4567890), 47583429387);
assert_eq!(
[
get_candid_rpc_cost(&provider, 0, 0),
get_candid_rpc_cost(&provider, 123, 123),
get_candid_rpc_cost(&provider, 123, 4567890),
get_candid_rpc_cost(&provider, 890, 4567890),
],
[51064987, 54828787, 47559605587, 47575098987]
);

// Fiduciary subnet
UNSTABLE_SUBNET_SIZE.with(|n| *n.borrow_mut() = NODES_IN_FIDUCIARY_SUBNET);
assert_eq!(get_candid_rpc_cost(&provider, 0, 0), 117960525);
assert_eq!(get_candid_rpc_cost(&provider, 123, 123), 127444772);
assert_eq!(get_candid_rpc_cost(&provider, 123, 4567890), 102445425572);
assert_eq!(get_candid_rpc_cost(&provider, 890, 4567890), 102487386372);
assert_eq!(
[
get_candid_rpc_cost(&provider, 0, 0),
get_candid_rpc_cost(&provider, 123, 123),
get_candid_rpc_cost(&provider, 123, 4567890),
get_candid_rpc_cost(&provider, 890, 4567890),
],
[109986125, 118092772, 102436073572, 102469443972]
);
}
5 changes: 3 additions & 2 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use cketh_common::eth_rpc_client::providers::{EthMainnetService, EthSepoliaServi
pub const INGRESS_OVERHEAD_BYTES: u128 = 100;
pub const INGRESS_MESSAGE_RECEIVED_COST: u128 = 1_200_000;
pub const INGRESS_MESSAGE_BYTE_RECEIVED_COST: u128 = 2_000;
pub const HTTP_OUTCALL_REQUEST_COST: u128 = 49_140_000;
pub const HTTP_OUTCALL_BYTE_RECEIVED_COST: u128 = 10_400;
pub const HTTP_OUTCALL_REQUEST_BASE_COST: u128 = 49_140_000;
pub const HTTP_OUTCALL_REQUEST_COST_PER_BYTE: u128 = 5_200;
pub const HTTP_OUTCALL_RESPONSE_COST_PER_BYTE: u128 = 10_400;

// Minimum number of bytes charged for a URL; improves consistency of costs between providers
pub const RPC_URL_MIN_COST_BYTES: u32 = 256;
Expand Down

0 comments on commit 0b5c52d

Please sign in to comment.