Skip to content

Commit 26af13e

Browse files
authored
EIP-7516: BLOBBASEFEE opcode (#721)
* feat(Cancun): EIP-7516 BLOBBASEFEE opcode * Update crates/interpreter/src/instructions/host_env.rs Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> * rename blobfee to baseblobfee * some renamings * rename and doc
1 parent f72eaa0 commit 26af13e

File tree

5 files changed

+184
-29
lines changed

5 files changed

+184
-29
lines changed

bins/revme/src/statetest/runner.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,11 @@ pub fn execute_test_suite(
190190
unit.env.parent_blob_gas_used,
191191
unit.env.parent_excess_blob_gas,
192192
) {
193-
env.block.excess_blob_gas = Some(calc_excess_blob_gas(
194-
parent_blob_gas_used.to(),
195-
parent_excess_blob_gas.to(),
196-
));
193+
env.block
194+
.set_blob_excess_gas_and_price(calc_excess_blob_gas(
195+
parent_blob_gas_used.to(),
196+
parent_excess_blob_gas.to(),
197+
));
197198
}
198199

199200
// tx env

crates/interpreter/src/instructions/host_env.rs

+10
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,13 @@ pub fn blob_hash<SPEC: Spec>(interpreter: &mut Interpreter, host: &mut dyn Host)
6868
None => U256::ZERO,
6969
};
7070
}
71+
72+
/// EIP-7516: BLOBBASEFEE opcode
73+
pub fn blob_basefee<SPEC: Spec>(interpreter: &mut Interpreter, host: &mut dyn Host) {
74+
check!(interpreter, CANCUN);
75+
gas!(interpreter, gas::BASE);
76+
push!(
77+
interpreter,
78+
U256::from(host.env().block.get_blob_gasprice().unwrap_or_default())
79+
);
80+
}

crates/interpreter/src/instructions/opcode.rs

+114-11
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ opcodes! {
151151
0x47 => SELFBALANCE => host::selfbalance::<SPEC>,
152152
0x48 => BASEFEE => host_env::basefee::<SPEC>,
153153
0x49 => BLOBHASH => host_env::blob_hash::<SPEC>,
154-
// 0x4A
154+
0x4A => BLOBBASEFEE => host_env::blob_basefee::<SPEC>,
155155
// 0x4B
156156
// 0x4C
157157
// 0x4D
@@ -333,7 +333,7 @@ opcodes! {
333333
// 0xF9
334334
0xFA => STATICCALL => host::static_call::<SPEC>,
335335
// 0xFB
336-
// 0xF
336+
// 0xFC
337337
0xFD => REVERT => control::revert::<SPEC>,
338338
0xFE => INVALID => control::invalid,
339339
0xFF => SELFDESTRUCT => host::selfdestruct::<SPEC>,
@@ -498,7 +498,10 @@ const fn opcode_gas_info(opcode: u8, spec: SpecId) -> OpInfo {
498498
MULMOD => OpInfo::gas(gas::MID),
499499
EXP => OpInfo::dynamic_gas(),
500500
SIGNEXTEND => OpInfo::gas(gas::LOW),
501-
501+
0x0C => OpInfo::none(),
502+
0x0D => OpInfo::none(),
503+
0x0E => OpInfo::none(),
504+
0x0F => OpInfo::none(),
502505
LT => OpInfo::gas(gas::VERYLOW),
503506
GT => OpInfo::gas(gas::VERYLOW),
504507
SLT => OpInfo::gas(gas::VERYLOW),
@@ -525,9 +528,24 @@ const fn opcode_gas_info(opcode: u8, spec: SpecId) -> OpInfo {
525528
} else {
526529
0
527530
}),
528-
531+
0x1E => OpInfo::none(),
532+
0x1F => OpInfo::none(),
529533
KECCAK256 => OpInfo::dynamic_gas(),
530-
534+
0x21 => OpInfo::none(),
535+
0x22 => OpInfo::none(),
536+
0x23 => OpInfo::none(),
537+
0x24 => OpInfo::none(),
538+
0x25 => OpInfo::none(),
539+
0x26 => OpInfo::none(),
540+
0x27 => OpInfo::none(),
541+
0x28 => OpInfo::none(),
542+
0x29 => OpInfo::none(),
543+
0x2A => OpInfo::none(),
544+
0x2B => OpInfo::none(),
545+
0x2C => OpInfo::none(),
546+
0x2D => OpInfo::none(),
547+
0x2E => OpInfo::none(),
548+
0x2F => OpInfo::none(),
531549
ADDRESS => OpInfo::gas(gas::BASE),
532550
BALANCE => OpInfo::dynamic_gas(),
533551
ORIGIN => OpInfo::gas(gas::BASE),
@@ -594,7 +612,16 @@ const fn opcode_gas_info(opcode: u8, spec: SpecId) -> OpInfo {
594612
} else {
595613
0
596614
}),
597-
615+
BLOBBASEFEE => OpInfo::gas(if SpecId::enabled(spec, SpecId::CANCUN) {
616+
gas::BASE
617+
} else {
618+
0
619+
}),
620+
0x4B => OpInfo::none(),
621+
0x4C => OpInfo::none(),
622+
0x4D => OpInfo::none(),
623+
0x4E => OpInfo::none(),
624+
0x4F => OpInfo::none(),
598625
POP => OpInfo::gas(gas::BASE),
599626
MLOAD => OpInfo::gas(gas::VERYLOW),
600627
MSTORE => OpInfo::gas(gas::VERYLOW),
@@ -697,21 +724,97 @@ const fn opcode_gas_info(opcode: u8, spec: SpecId) -> OpInfo {
697724
LOG2 => OpInfo::dynamic_gas(),
698725
LOG3 => OpInfo::dynamic_gas(),
699726
LOG4 => OpInfo::dynamic_gas(),
700-
727+
0xA5 => OpInfo::none(),
728+
0xA6 => OpInfo::none(),
729+
0xA7 => OpInfo::none(),
730+
0xA8 => OpInfo::none(),
731+
0xA9 => OpInfo::none(),
732+
0xAA => OpInfo::none(),
733+
0xAB => OpInfo::none(),
734+
0xAC => OpInfo::none(),
735+
0xAD => OpInfo::none(),
736+
0xAE => OpInfo::none(),
737+
0xAF => OpInfo::none(),
738+
0xB0 => OpInfo::none(),
739+
0xB1 => OpInfo::none(),
740+
0xB2 => OpInfo::none(),
741+
0xB3 => OpInfo::none(),
742+
0xB4 => OpInfo::none(),
743+
0xB5 => OpInfo::none(),
744+
0xB6 => OpInfo::none(),
745+
0xB7 => OpInfo::none(),
746+
0xB8 => OpInfo::none(),
747+
0xB9 => OpInfo::none(),
748+
0xBA => OpInfo::none(),
749+
0xBB => OpInfo::none(),
750+
0xBC => OpInfo::none(),
751+
0xBD => OpInfo::none(),
752+
0xBE => OpInfo::none(),
753+
0xBF => OpInfo::none(),
754+
0xC0 => OpInfo::none(),
755+
0xC1 => OpInfo::none(),
756+
0xC2 => OpInfo::none(),
757+
0xC3 => OpInfo::none(),
758+
0xC4 => OpInfo::none(),
759+
0xC5 => OpInfo::none(),
760+
0xC6 => OpInfo::none(),
761+
0xC7 => OpInfo::none(),
762+
0xC8 => OpInfo::none(),
763+
0xC9 => OpInfo::none(),
764+
0xCA => OpInfo::none(),
765+
0xCB => OpInfo::none(),
766+
0xCC => OpInfo::none(),
767+
0xCD => OpInfo::none(),
768+
0xCE => OpInfo::none(),
769+
0xCF => OpInfo::none(),
770+
0xD0 => OpInfo::none(),
771+
0xD1 => OpInfo::none(),
772+
0xD2 => OpInfo::none(),
773+
0xD3 => OpInfo::none(),
774+
0xD4 => OpInfo::none(),
775+
0xD5 => OpInfo::none(),
776+
0xD6 => OpInfo::none(),
777+
0xD7 => OpInfo::none(),
778+
0xD8 => OpInfo::none(),
779+
0xD9 => OpInfo::none(),
780+
0xDA => OpInfo::none(),
781+
0xDB => OpInfo::none(),
782+
0xDC => OpInfo::none(),
783+
0xDD => OpInfo::none(),
784+
0xDE => OpInfo::none(),
785+
0xDF => OpInfo::none(),
786+
0xE0 => OpInfo::none(),
787+
0xE1 => OpInfo::none(),
788+
0xE2 => OpInfo::none(),
789+
0xE3 => OpInfo::none(),
790+
0xE4 => OpInfo::none(),
791+
0xE5 => OpInfo::none(),
792+
0xE6 => OpInfo::none(),
793+
0xE7 => OpInfo::none(),
794+
0xE8 => OpInfo::none(),
795+
0xE9 => OpInfo::none(),
796+
0xEA => OpInfo::none(),
797+
0xEB => OpInfo::none(),
798+
0xEC => OpInfo::none(),
799+
0xED => OpInfo::none(),
800+
0xEE => OpInfo::none(),
801+
0xEF => OpInfo::none(),
701802
CREATE => OpInfo::gas_block_end(0),
702803
CALL => OpInfo::gas_block_end(0),
703804
CALLCODE => OpInfo::gas_block_end(0),
704805
RETURN => OpInfo::gas_block_end(0),
705806
DELEGATECALL => OpInfo::gas_block_end(0),
706807
CREATE2 => OpInfo::gas_block_end(0),
707-
808+
0xF6 => OpInfo::none(),
809+
0xF7 => OpInfo::none(),
810+
0xF8 => OpInfo::none(),
811+
0xF9 => OpInfo::none(),
708812
STATICCALL => OpInfo::gas_block_end(0),
709-
813+
0xFB => OpInfo::none(),
814+
0xFC => OpInfo::none(),
710815
REVERT => OpInfo::gas_block_end(0),
711816
INVALID => OpInfo::gas_block_end(0),
712817
SELFDESTRUCT => OpInfo::gas_block_end(0),
713-
714-
_ => OpInfo::none(),
715818
}
716819
}
717820

crates/primitives/src/env.rs

+52-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
2-
alloc::vec::Vec, calc_blob_fee, Account, InvalidHeader, InvalidTransaction, Spec, SpecId, B160,
3-
B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_BLOB_NUMBER_PER_BLOCK, MAX_INITCODE_SIZE, U256,
2+
alloc::vec::Vec, calc_blob_gasprice, Account, InvalidHeader, InvalidTransaction, Spec, SpecId,
3+
B160, B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_BLOB_NUMBER_PER_BLOCK, MAX_INITCODE_SIZE, U256,
44
VERSIONED_HASH_VERSION_KZG,
55
};
66
use bytes::Bytes;
@@ -28,12 +28,10 @@ pub struct BlockEnv {
2828
pub timestamp: U256,
2929
/// The gas limit of the block.
3030
pub gas_limit: U256,
31-
3231
/// The base fee per gas, added in the London upgrade with [EIP-1559].
3332
///
3433
/// [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559
3534
pub basefee: U256,
36-
3735
/// The difficulty of the block.
3836
///
3937
/// Unused after the Paris (AKA the merge) upgrade, and replaced by `prevrandao`.
@@ -46,24 +44,67 @@ pub struct BlockEnv {
4644
///
4745
/// [EIP-4399]: https://eips.ethereum.org/EIPS/eip-4399
4846
pub prevrandao: Option<B256>,
49-
50-
/// Excess blob gas. See also [`calc_excess_blob_gas`](crate::calc_excess_blob_gas).
47+
/// Excess blob gas and blob gasprice.
48+
/// See also [`calc_excess_blob_gas`](crate::calc_excess_blob_gas)
49+
/// and [`calc_blob_gasprice`](crate::calc_blob_gasprice).
5150
///
5251
/// Incorporated as part of the Cancun upgrade via [EIP-4844].
5352
///
5453
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
55-
pub excess_blob_gas: Option<u64>,
54+
pub blob_excess_gas_and_price: Option<BlobExcessGasAndPrice>,
55+
}
56+
57+
/// Structure holding block blob excess gas and it calculates blob fee.
58+
///
59+
/// Incorporated as part of the Cancun upgrade via [EIP-4844].
60+
///
61+
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
62+
#[derive(Clone, Debug, PartialEq, Eq)]
63+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
64+
pub struct BlobExcessGasAndPrice {
65+
pub excess_blob_gas: u64,
66+
pub blob_gasprice: u64,
67+
}
68+
69+
impl BlobExcessGasAndPrice {
70+
/// Takes excess blob gas and calculated blob fee with [`calc_blob_fee`]
71+
pub fn new(excess_blob_gas: u64) -> Self {
72+
let blob_gasprice = calc_blob_gasprice(excess_blob_gas);
73+
Self {
74+
excess_blob_gas,
75+
blob_gasprice,
76+
}
77+
}
5678
}
5779

5880
impl BlockEnv {
59-
/// See [EIP-4844] and [`Env::calc_data_fee`].
81+
/// Takes `blob_excess_gas` saves it inside env
82+
/// and calculates `blob_fee` with [`BlobGasAndFee`].
83+
pub fn set_blob_excess_gas_and_price(&mut self, excess_blob_gas: u64) {
84+
self.blob_excess_gas_and_price = Some(BlobExcessGasAndPrice::new(excess_blob_gas));
85+
}
86+
/// See [EIP-4844] and [`crate::calc_blob_gasprice`].
6087
///
6188
/// Returns `None` if `Cancun` is not enabled. This is enforced in [`Env::validate_block_env`].
6289
///
6390
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
6491
#[inline]
6592
pub fn get_blob_gasprice(&self) -> Option<u64> {
66-
self.excess_blob_gas.map(calc_blob_fee)
93+
self.blob_excess_gas_and_price
94+
.as_ref()
95+
.map(|a| a.blob_gasprice)
96+
}
97+
98+
/// Return `blob_excess_gas` header field. See [EIP-4844].
99+
///
100+
/// Returns `None` if `Cancun` is not enabled. This is enforced in [`Env::validate_block_env`].
101+
///
102+
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
103+
#[inline]
104+
pub fn get_blob_excess_gas(&self) -> Option<u64> {
105+
self.blob_excess_gas_and_price
106+
.as_ref()
107+
.map(|a| a.excess_blob_gas)
67108
}
68109
}
69110

@@ -342,7 +383,7 @@ impl Default for BlockEnv {
342383
basefee: U256::ZERO,
343384
difficulty: U256::ZERO,
344385
prevrandao: Some(B256::zero()),
345-
excess_blob_gas: Some(0),
386+
blob_excess_gas_and_price: Some(BlobExcessGasAndPrice::new(0)),
346387
}
347388
}
348389
}
@@ -397,7 +438,7 @@ impl Env {
397438
return Err(InvalidHeader::PrevrandaoNotSet);
398439
}
399440
// `excess_blob_gas` is required for Cancun
400-
if SPEC::enabled(SpecId::CANCUN) && self.block.excess_blob_gas.is_none() {
441+
if SPEC::enabled(SpecId::CANCUN) && self.block.blob_excess_gas_and_price.is_none() {
401442
return Err(InvalidHeader::ExcessBlobGasNotSet);
402443
}
403444
Ok(())

crates/primitives/src/utilities.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ pub fn calc_excess_blob_gas(parent_excess_blob_gas: u64, parent_blob_gas_used: u
4141
(parent_excess_blob_gas + parent_blob_gas_used).saturating_sub(TARGET_BLOB_GAS_PER_BLOCK)
4242
}
4343

44-
/// Calculates the blobfee from the header's excess blob gas field.
44+
/// Calculates the blob gasprice from the header's excess blob gas field.
4545
///
4646
/// See also [the EIP-4844 helpers](https://eips.ethereum.org/EIPS/eip-4844#helpers).
4747
#[inline]
48-
pub fn calc_blob_fee(excess_blob_gas: u64) -> u64 {
48+
pub fn calc_blob_gasprice(excess_blob_gas: u64) -> u64 {
4949
fake_exponential(
5050
MIN_BLOB_GASPRICE,
5151
excess_blob_gas,
@@ -174,7 +174,7 @@ mod tests {
174174
#[test]
175175
fn test_calc_blob_fee() {
176176
for &(excess, expected) in &[(0, 1), (2314057, 1), (2314058, 2), (10 * 1024 * 1024, 23)] {
177-
let actual = calc_blob_fee(excess);
177+
let actual = calc_blob_gasprice(excess);
178178
assert_eq!(actual, expected, "test: {excess}");
179179
}
180180
}

0 commit comments

Comments
 (0)