Skip to main content

revm_interpreter/instructions/
block_info.rs

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