Skip to content

Commit

Permalink
[pallet-revive] implement the base fee API (#6964)
Browse files Browse the repository at this point in the history
This PR implements the base fee syscall API method. Currently this is
implemented as a compile time constant in the revive compiler, returning
0. However, since this is an opocde, if we ever need to implement it for
compatibility reasons with
[EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md),
it would break already deployed contracts. Thus we provide a syscall
method instead.

---------

Signed-off-by: xermicus <[email protected]>
Signed-off-by: Cyrill Leutwiler <[email protected]>
Co-authored-by: command-bot <>
  • Loading branch information
xermicus authored Dec 19, 2024
1 parent ade1f75 commit 243b751
Show file tree
Hide file tree
Showing 8 changed files with 602 additions and 464 deletions.
15 changes: 15 additions & 0 deletions prdoc/pr_6964.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
title: '[pallet-revive] implement the base fee API'
doc:
- audience: Runtime Dev
description: This PR implements the base fee syscall API method. Currently this
is implemented as a compile time constant in the revive compiler, returning 0.
However, since this is an opocde, if we ever need to implement it for compatibility
reasons with [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md),
it would break already deployed contracts. Thus we provide a syscall method instead.
crates:
- name: pallet-revive-fixtures
bump: minor
- name: pallet-revive
bump: minor
- name: pallet-revive-uapi
bump: minor
36 changes: 36 additions & 0 deletions substrate/frame/revive/fixtures/contracts/base_fee.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Returns the base fee back to the caller.
#![no_std]
#![no_main]

extern crate common;
use uapi::{HostFn, HostFnImpl as api, ReturnFlags};

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn deploy() {}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {
let mut buf = [0; 32];
api::base_fee(&mut buf);
api::return_value(ReturnFlags::empty(), &buf);
}
12 changes: 12 additions & 0 deletions substrate/frame/revive/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,18 @@ mod benchmarks {
assert_eq!(result.unwrap(), u64::from(GAS_PRICE));
}

#[benchmark(pov_mode = Measured)]
fn seal_base_fee() {
build_runtime!(runtime, memory: [[1u8;32], ]);
let result;
#[block]
{
result = runtime.bench_base_fee(memory.as_mut_slice(), 0);
}
assert_ok!(result);
assert_eq!(U256::from_little_endian(&memory[..]), U256::zero());
}

#[benchmark(pov_mode = Measured)]
fn seal_block_number() {
build_runtime!(runtime, memory: [[0u8;32], ]);
Expand Down
18 changes: 18 additions & 0 deletions substrate/frame/revive/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4382,6 +4382,24 @@ fn gas_price_api_works() {
});
}

#[test]
fn base_fee_api_works() {
let (code, _) = compile_module("base_fee").unwrap();

ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);

// Create fixture: Constructor does nothing
let Contract { addr, .. } =
builder::bare_instantiate(Code::Upload(code)).build_and_unwrap_contract();

// Call the contract: It echoes back the value returned by the base fee API.
let received = builder::bare_call(addr).build_and_unwrap_result();
assert_eq!(received.flags, ReturnFlags::empty());
assert_eq!(U256::from_little_endian(received.data[..].try_into().unwrap()), U256::zero());
});
}

#[test]
fn call_data_size_api_works() {
let (code, _) = compile_module("call_data_size").unwrap();
Expand Down
17 changes: 17 additions & 0 deletions substrate/frame/revive/src/wasm/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ pub enum RuntimeCosts {
BlockHash,
/// Weight of calling `seal_gas_price`.
GasPrice,
/// Weight of calling `seal_base_fee`.
BaseFee,
/// Weight of calling `seal_now`.
Now,
/// Weight of calling `seal_gas_limit`.
Expand Down Expand Up @@ -481,6 +483,7 @@ impl<T: Config> Token<T> for RuntimeCosts {
BlockNumber => T::WeightInfo::seal_block_number(),
BlockHash => T::WeightInfo::seal_block_hash(),
GasPrice => T::WeightInfo::seal_gas_price(),
BaseFee => T::WeightInfo::seal_base_fee(),
Now => T::WeightInfo::seal_now(),
GasLimit => T::WeightInfo::seal_gas_limit(),
WeightToFee => T::WeightInfo::seal_weight_to_fee(),
Expand Down Expand Up @@ -1575,6 +1578,20 @@ pub mod env {
Ok(GAS_PRICE.into())
}

/// Returns the simulated ethereum `BASEFEE` value.
/// See [`pallet_revive_uapi::HostFn::base_fee`].
#[stable]
fn base_fee(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> {
self.charge_gas(RuntimeCosts::BaseFee)?;
Ok(self.write_fixed_sandbox_output(
memory,
out_ptr,
&U256::zero().to_little_endian(),
false,
already_charged,
)?)
}

/// Load the latest block timestamp into the supplied buffer
/// See [`pallet_revive_uapi::HostFn::now`].
#[stable]
Expand Down
Loading

0 comments on commit 243b751

Please sign in to comment.