revm_interpreter/instructions/
block_info.rs

1use crate::{
2    interpreter_types::{InterpreterTypes, RuntimeFlag, StackTr},
3    Host,
4};
5use primitives::{hardfork::SpecId::*, U256};
6
7use crate::InstructionContext;
8
9/// EIP-1344: ChainID opcode
10pub fn chainid<WIRE: InterpreterTypes, H: Host + ?Sized>(context: InstructionContext<'_, H, WIRE>) {
11    check!(context.interpreter, ISTANBUL);
12    //gas!(context.interpreter, gas::BASE);
13    push!(context.interpreter, context.host.chain_id());
14}
15
16/// Implements the COINBASE instruction.
17///
18/// Pushes the current block's beneficiary address onto the stack.
19pub fn coinbase<WIRE: InterpreterTypes, H: Host + ?Sized>(
20    context: InstructionContext<'_, H, WIRE>,
21) {
22    //gas!(context.interpreter, gas::BASE);
23    push!(
24        context.interpreter,
25        context.host.beneficiary().into_word().into()
26    );
27}
28
29/// Implements the TIMESTAMP instruction.
30///
31/// Pushes the current block's timestamp onto the stack.
32pub fn timestamp<WIRE: InterpreterTypes, H: Host + ?Sized>(
33    context: InstructionContext<'_, H, WIRE>,
34) {
35    //gas!(context.interpreter, gas::BASE);
36    push!(context.interpreter, context.host.timestamp());
37}
38
39/// Implements the NUMBER instruction.
40///
41/// Pushes the current block number onto the stack.
42pub fn block_number<WIRE: InterpreterTypes, H: Host + ?Sized>(
43    context: InstructionContext<'_, H, WIRE>,
44) {
45    //gas!(context.interpreter, gas::BASE);
46    push!(context.interpreter, U256::from(context.host.block_number()));
47}
48
49/// Implements the DIFFICULTY/PREVRANDAO instruction.
50///
51/// Pushes the block difficulty (pre-merge) or prevrandao (post-merge) onto the stack.
52pub fn difficulty<WIRE: InterpreterTypes, H: Host + ?Sized>(
53    context: InstructionContext<'_, H, WIRE>,
54) {
55    //gas!(context.interpreter, gas::BASE);
56    if context
57        .interpreter
58        .runtime_flag
59        .spec_id()
60        .is_enabled_in(MERGE)
61    {
62        // Unwrap is safe as this fields is checked in validation handler.
63        push!(context.interpreter, context.host.prevrandao().unwrap());
64    } else {
65        push!(context.interpreter, context.host.difficulty());
66    }
67}
68
69/// Implements the GASLIMIT instruction.
70///
71/// Pushes the current block's gas limit onto the stack.
72pub fn gaslimit<WIRE: InterpreterTypes, H: Host + ?Sized>(
73    context: InstructionContext<'_, H, WIRE>,
74) {
75    //gas!(context.interpreter, gas::BASE);
76    push!(context.interpreter, context.host.gas_limit());
77}
78
79/// EIP-3198: BASEFEE opcode
80pub fn basefee<WIRE: InterpreterTypes, H: Host + ?Sized>(context: InstructionContext<'_, H, WIRE>) {
81    check!(context.interpreter, LONDON);
82    //gas!(context.interpreter, gas::BASE);
83    push!(context.interpreter, context.host.basefee());
84}
85
86/// EIP-7516: BLOBBASEFEE opcode
87pub fn blob_basefee<WIRE: InterpreterTypes, H: Host + ?Sized>(
88    context: InstructionContext<'_, H, WIRE>,
89) {
90    check!(context.interpreter, CANCUN);
91    //gas!(context.interpreter, gas::BASE);
92    push!(context.interpreter, context.host.blob_gasprice());
93}