Skip to content

Commit 101dcd0

Browse files
committed
feat: count the base "block open" fee against memory retention
This effectively removes the memory retention fee from newly opened blocks. The cross-over point is ~44MiB.... This will save about 4.4K gas per 1K block opened (about 2% of the total gas value). Not much, but it helps a bit.
1 parent 969de36 commit 101dcd0

1 file changed

Lines changed: 27 additions & 12 deletions

File tree

fvm/src/gas/price_list.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,9 @@ lazy_static! {
225225
block_open: ScalingCost {
226226
// This was benchmarked (#1264) at 187440 gas/read.
227227
flat: Gas::new(187440),
228-
// It costs takes about 0.562 ns/byte (5.6gas) to "read" from a client. However, that
228+
// It costs takes about 0.567 ns/byte (5.7gas) to "read" from a client. However, that
229229
// includes one allocation and memory copy, which we charge for separately.
230-
//
231-
// We disable this charge now because it's entirely covered by the "memory retention"
232-
// cost. If we do drop the memory retention cost, we need to re-enable this.
233-
/* scale: Gas::from_milligas(3200), */
234-
scale: Gas::zero(),
230+
scale: Gas::from_milligas(3300),
235231
},
236232

237233
block_persist_storage: ScalingCost {
@@ -717,16 +713,22 @@ impl PriceList {
717713
pub fn on_block_open_per_byte(&self, data_size: usize) -> GasCharge {
718714
// These are the actual compute costs involved.
719715
let compute = self.block_allocate.apply(data_size) + self.block_memcpy.apply(data_size);
720-
let block_open = self.block_open.scale * data_size;
716+
// We've already charged the "base" before we tried to open it, so now we just need to
717+
// charge the variable amount.
718+
let block_open_variable = self.block_open.scale * data_size;
721719

722720
// But we need to make sure we charge at least the memory retention cost.
723721
let retention_min = self.block_memory_retention_minimum.apply(data_size);
724-
let retention_surcharge = (retention_min - (compute + block_open)).max(Gas::zero());
722+
// To compute the memory retention surcharge, we need to know how much we've charged for
723+
// this block so far
724+
let total_charged = compute + self.block_open.flat + block_open_variable;
725+
let retention_surcharge = (retention_min - total_charged).max(Gas::zero());
725726
GasCharge::new(
726727
"OnBlockOpenPerByte",
727728
compute,
728-
// We charge the `block_open` fee as "extra" to make sure the FVM benchmarks still work.
729-
block_open + retention_surcharge,
729+
// We charge the `block_open_variable` fee as "extra" to make sure the FVM benchmarks
730+
// still work.
731+
block_open_variable + retention_surcharge,
730732
)
731733
}
732734

@@ -1233,10 +1235,23 @@ impl Rules for WasmGasPrices {
12331235
#[test]
12341236
fn test_read_write() {
12351237
// The math for these operations is complicated, so we explicitly test to make sure we're
1236-
// getting the expected 10 gas/byte.
1238+
// getting the expected rates.
1239+
1240+
// For small blocks, we expect the block open cost to be 5.7gas/byte.
12371241
assert_eq!(
12381242
HYGGE_PRICES.on_block_open_per_byte(10).total(),
1239-
Gas::new(100)
1243+
Gas::new(57)
1244+
);
1245+
1246+
// For very large blocks, the memory retention fee should dominate and the total gas used should
1247+
// equal the number of bytes times the memory retention fee.
1248+
const SIZE: usize = 1_000_000_000;
1249+
assert_eq!(
1250+
HYGGE_PRICES.on_block_open_per_byte(SIZE).total()
1251+
+ HYGGE_PRICES.on_block_open_base().total(),
1252+
HYGGE_PRICES.block_memory_retention_minimum.apply(SIZE)
12401253
);
1254+
1255+
// For new blocks, the memory retention fee always dominates.
12411256
assert_eq!(HYGGE_PRICES.on_block_create(10).total(), Gas::new(100));
12421257
}

0 commit comments

Comments
 (0)