Skip to content

Commit

Permalink
feat: Separate light and heavy gas costs (core) (#1483)
Browse files Browse the repository at this point in the history
This PR is a subset of #1470.
It contains only the changes required for fuel-core crates and
chainspec, including upgrading to `fuel-vm` v0.41.

---------

Co-authored-by: xgreenx <xgreenx9999@gmail.com>
  • Loading branch information
Brandon Vrooman and xgreenx committed Nov 14, 2023
1 parent 3503e53 commit be5e4b1
Show file tree
Hide file tree
Showing 20 changed files with 1,212 additions and 551 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Description of the upcoming release here.
- [#1408](https://github.com/FuelLabs/fuel-core/pull/1408): Update gas benchmarks for storage opcodes to use a pre-populated database to get more accurate worst-case costs.

#### Breaking
- [#1470](https://github.com/FuelLabs/fuel-core/pull/1470): Divide `DependentCost` into "light" and "heavy" operations.
- [#1464](https://github.com/FuelLabs/fuel-core/pull/1464): Avoid possible truncation of higher bits. It may invalidate the code that truncated higher bits causing different behavior on 32-bit vs. 64-bit systems. The change affects some endpoints that now require lesser integers.
- [#1432](https://github.com/FuelLabs/fuel-core/pull/1432): All subscriptions and requests have a TTL now. So each subscription lifecycle is limited in time. If the subscription is closed because of TTL, it means that you subscribed after your transaction had been dropped by the network.
- [#1407](https://github.com/FuelLabs/fuel-core/pull/1407): The recipient is a `ContractId` instead of `Address`. The block producer should deploy its contract to receive the transaction fee. The collected fee is zero until the recipient contract is set.
Expand Down
32 changes: 16 additions & 16 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fuel-core-tests = { version = "0.0.0", path = "./tests" }
fuel-core-xtask = { version = "0.0.0", path = "./xtask" }

# Fuel dependencies
fuel-vm-private = { version = "0.40.0", package = "fuel-vm", default-features = false }
fuel-vm-private = { version = "0.41.0", package = "fuel-vm", default-features = false }

# Common dependencies
anyhow = "1.0"
Expand Down
113 changes: 60 additions & 53 deletions benches/src/bin/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,17 @@ impl Default for State {
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
struct Costs(HashMap<String, Cost>);

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum DependentCost {
LightOperation { base: u64, units_per_gas: u64 },
HeavyOperation { base: u64, gas_per_unit: u64 },
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
enum Cost {
pub enum Cost {
Relative(u64),
Dependent {
base: u64,
dep_per_unit: u64,
},
DependentAll {
samples: Vec<Sample>,
dep_per_unit: u64,
},
Dependent(DependentCost),
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
Expand Down Expand Up @@ -423,17 +422,34 @@ impl State {
serde_yaml::Value::Number(i) => {
format!("\n{}{}: {},", indent, name, i.as_u64().unwrap())
}
serde_yaml::Value::Mapping(m) => {
format!(
"\n{}{}: DependentCost {{\n{} base: {},\n{} dep_per_unit: {},\n{}}},",
indent,
name,
indent,
m.get("base").unwrap().as_u64().unwrap(),
indent,
m.get("dep_per_unit").unwrap().as_u64().unwrap(),
indent,
)
serde_yaml::Value::Tagged(m) => {
let tag = &m.tag;
let m = &m.value;
if tag.to_string().contains("HeavyOperation") {
let output = format!(
r"
{}: DependentCost::HeavyOperation {{
base: {},
gas_per_unit: {},
}},",
name,
m.get("base").unwrap().as_u64().unwrap(),
m.get("gas_per_unit").unwrap().as_u64().unwrap(),
);
output
} else {
let output = format!(
r"
{}: DependentCost::LightOperation {{
base: {},
units_per_gas: {},
}},",
name,
m.get("base").unwrap().as_u64().unwrap(),
m.get("units_per_gas").unwrap().as_u64().unwrap(),
);
output
}
}
_ => unreachable!(),
}
Expand Down Expand Up @@ -531,35 +547,14 @@ impl State {
})
.collect::<Vec<_>>();

if all {
let iter = dependent_groups.into_iter().map(|(name, x_y)| {
groups.remove(&name);
let samples = x_y
.iter()
.map(|(x, y)| Sample {
throughput: *x,
time: *y,
})
.collect();
let (_, dep_per_unit) = dependent_cost(&name, x_y);
(
name,
Cost::DependentAll {
samples,
dep_per_unit,
},
)
});
costs.0.extend(iter);
} else {
let iter = dependent_groups.into_iter().map(|(name, x_y)| {
groups.remove(&name);

let (base, dep_per_unit) = dependent_cost(&name, x_y);
(name, Cost::Dependent { base, dep_per_unit })
});
costs.0.extend(iter);
}
let iter = dependent_groups.into_iter().map(|(name, x_y)| {
groups.remove(&name);

let cost = Cost::Dependent(dependent_cost(&name, x_y));
(name, cost)
});
costs.0.extend(iter);

(
Self {
all,
Expand Down Expand Up @@ -630,7 +625,7 @@ fn linear_regression(x_y: Vec<(u64, u64)>) -> f64 {
sq_x / sum_x_y
}

fn dependent_cost(name: &String, x_y: Vec<(u64, u64)>) -> (u64, u64) {
fn dependent_cost(name: &String, x_y: Vec<(u64, u64)>) -> DependentCost {
const NEAR_LINEAR: f64 = 0.1;

#[derive(PartialEq, Eq)]
Expand Down Expand Up @@ -691,7 +686,7 @@ fn dependent_cost(name: &String, x_y: Vec<(u64, u64)>) -> (u64, u64) {
Type::Exp
};

match expected_type {
let (base, amount): (u64, f64) = match expected_type {
Type::Linear => {
// The time of the first point is a base.
// The minimal charge per element is the worse scenario
Expand All @@ -703,7 +698,7 @@ fn dependent_cost(name: &String, x_y: Vec<(u64, u64)>) -> (u64, u64) {
.map(|p| p.amount())
.min_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap();
(base, amount as u64)
(base, amount)
}
Type::Logarithm | Type::Exp => {
if expected_type == Type::Exp {
Expand Down Expand Up @@ -733,7 +728,19 @@ fn dependent_cost(name: &String, x_y: Vec<(u64, u64)>) -> (u64, u64) {
.map(|p| p.amount())
.min_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap_or(last);
(base.y, amount as u64)
(base.y, amount)
}
};

if amount > 1.0 {
DependentCost::LightOperation {
base,
units_per_gas: amount as u64,
}
} else {
DependentCost::HeavyOperation {
base,
gas_per_unit: (1.0 / amount) as u64,
}
}
}
Expand Down

0 comments on commit be5e4b1

Please sign in to comment.