Skip to content

Commit 364ffbf

Browse files
committed
Merge branch 'main' into advise-random
2 parents 29dbc60 + 93832c0 commit 364ffbf

File tree

16 files changed

+109
-44
lines changed

16 files changed

+109
-44
lines changed

.github/workflows/main_prover.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ jobs:
9999
ETHREX_PROPOSER_BLOCK_TIME=12000 \
100100
ETHREX_COMMITTER_COMMIT_TIME=30000 \
101101
ETHREX_WATCHER_WATCH_INTERVAL=1000 \
102+
ETHREX_COMMITTER_FIRST_WAKE_UP_TIME=60000 \
102103
ETHREX_BLOCK_PRODUCER_BASE_FEE_VAULT_ADDRESS=0x000c0d6b7c4516a5b274c51ea331a9410fe69127 \
103104
ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_VAULT_ADDRESS=0xd5d2a85751b6F158e5b9B8cD509206A865672362 \
104105
ETHREX_BLOCK_PRODUCER_OPERATOR_FEE_PER_GAS=1000000000 \

.github/workflows/tag_release.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ jobs:
293293
- name: Checkout code
294294
uses: actions/checkout@v4
295295

296+
- name: Free Disk Space
297+
uses: ./.github/actions/free-disk
298+
296299
- name: Format name
297300
run: |
298301
# For branch builds (main) we want docker images tagged as 'main'. For tag pushes

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### 2025-11-13
66

7+
- Use specialized DUP implementation [#5324](https://github.com/lambdaclass/ethrex/pull/5324)
78
- Avoid recalculating blob base fee while preparing transactions [#5328](https://github.com/lambdaclass/ethrex/pull/5328)
89
- Use BlobDB for account_codes column family [#5300](https://github.com/lambdaclass/ethrex/pull/5300)
910

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ For instructions on how to get started using ethrex L1 and/or L2, please refer t
1616

1717
This client supports running in two different modes:
1818

19-
- As a regular Ethereum execution client
20-
- As a multi-prover ZK-Rollup (supporting SP1, RISC Zero and TEEs), where block execution is proven and the proof sent to an L1 network for verification, thus inheriting the L1's security. Support for based sequencing is currently in the works.
21-
22-
We call the first one ethrex L1 and the second one ethrex L2.
19+
* **ethrex L1** - As a regular Ethereum execution client
20+
* **ethrex L2** - As a multi-prover ZK-Rollup (supporting SP1, RISC Zero and TEEs), where block execution is proven and the proof sent to an L1 network for verification, thus inheriting the L1's security. Support for based sequencing is currently in the works.
2321

2422
## Philosophy
2523

crates/common/types/tx_fields.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ pub struct AuthorizationTuple {
3636
pub chain_id: U256,
3737
#[rkyv(with = crate::rkyv_utils::H160Wrapper)]
3838
pub address: Address,
39+
#[serde(
40+
default,
41+
deserialize_with = "crate::serde_utils::u64::deser_hex_or_dec_str"
42+
)]
3943
pub nonce: u64,
4044
#[rkyv(with = crate::rkyv_utils::U256Wrapper)]
4145
pub y_parity: U256,

crates/vm/levm/src/call_frame.rs

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ use ethrex_common::{Address, U256};
1111
use ethrex_common::{H256, types::Code};
1212
use std::{collections::HashMap, fmt};
1313

14+
/// [`u64`]s that make up a [`U256`]
15+
const U64_PER_U256: usize = U256::MAX.0.len();
16+
1417
#[derive(Clone, PartialEq, Eq)]
1518
/// The EVM uses a stack-based architecture and does not use registers like some other VMs.
1619
///
@@ -85,7 +88,7 @@ impl Stack {
8588
std::ptr::copy_nonoverlapping(
8689
value.0.as_ptr(),
8790
self.values.get_unchecked_mut(next_offset).0.as_mut_ptr(),
88-
4,
91+
U64_PER_U256,
8992
);
9093
}
9194
self.offset = next_offset;
@@ -111,7 +114,7 @@ impl Stack {
111114
.get_unchecked_mut(next_offset)
112115
.0
113116
.as_mut_ptr()
114-
.cast() = [0u64; 4];
117+
.cast() = [0u64; U64_PER_U256];
115118
}
116119
self.offset = next_offset;
117120

@@ -131,18 +134,6 @@ impl Stack {
131134
self.offset == self.values.len()
132135
}
133136

134-
pub fn get(&self, index: usize) -> Result<&U256, ExceptionalHalt> {
135-
// The following index cannot fail because `self.offset` is known to be within
136-
// `STACK_LIMIT`.
137-
#[expect(unsafe_code)]
138-
unsafe {
139-
self.values
140-
.get_unchecked(self.offset..)
141-
.get(index)
142-
.ok_or(ExceptionalHalt::StackUnderflow)
143-
}
144-
}
145-
146137
#[inline(always)]
147138
pub fn swap<const N: usize>(&mut self) -> Result<(), ExceptionalHalt> {
148139
// Compile-time check that ensures `self.offset + N` is safe,
@@ -164,6 +155,36 @@ impl Stack {
164155
pub fn clear(&mut self) {
165156
self.offset = STACK_LIMIT;
166157
}
158+
159+
/// Pushes a copy of the value at depth N
160+
#[inline]
161+
pub fn dup<const N: usize>(&mut self) -> Result<(), ExceptionalHalt> {
162+
// Compile-time check that ensures `self.offset + N` is safe,
163+
// since self.offset is bounded by STACK_LIMIT
164+
const {
165+
assert!(STACK_LIMIT.checked_add(N).is_some());
166+
}
167+
#[expect(clippy::arithmetic_side_effects)]
168+
let index = self.offset + N;
169+
if index >= self.values.len() {
170+
return Err(ExceptionalHalt::StackUnderflow);
171+
}
172+
173+
self.offset = self
174+
.offset
175+
.checked_sub(1)
176+
.ok_or(ExceptionalHalt::StackOverflow)?;
177+
178+
#[expect(unsafe_code, reason = "index < size, offset-1 >= 0")]
179+
unsafe {
180+
std::ptr::copy_nonoverlapping(
181+
self.values.get_unchecked_mut(index).0.as_mut_ptr(),
182+
self.values.get_unchecked_mut(self.offset).0.as_mut_ptr(),
183+
U64_PER_U256,
184+
);
185+
}
186+
Ok(())
187+
}
167188
}
168189

169190
impl Default for Stack {

crates/vm/levm/src/opcode_handlers/dup.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@ use crate::{
1010
impl<'a> VM<'a> {
1111
// DUP operation
1212
pub fn op_dup<const N: usize>(&mut self) -> Result<OpcodeResult, VMError> {
13-
let current_call_frame = &mut self.current_call_frame;
1413
// Increase the consumed gas
15-
current_call_frame.increase_consumed_gas(gas_cost::DUPN)?;
14+
self.current_call_frame
15+
.increase_consumed_gas(gas_cost::DUPN)?;
1616

17-
// Get the value at the specified depth
18-
let value_at_depth = *current_call_frame.stack.get(N)?;
19-
20-
// Push the duplicated value onto the stack
21-
current_call_frame.stack.push(value_at_depth)?;
17+
// Duplicate the value at the specified depth
18+
self.current_call_frame.stack.dup::<N>()?;
2219

2320
Ok(OpcodeResult::Continue)
2421
}

docs/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Introduction
44

55
- [Getting started](./getting-started/README.md)
6-
- [Hardware requirements]()
6+
- [Hardware requirements](./getting-started/hardware_requirements.md)
77
- [Installation](./getting-started/installation/README.md)
88
- [Binary distribution](./getting-started/installation/binary_distribution.md)
99
- [Package manager](./getting-started/installation/package_manager.md)

docs/getting-started/README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
Ethrex is a minimalist, stable, modular and fast implementation of the Ethereum protocol in [Rust](https://www.rust-lang.org/).
44
The client supports running in two different modes:
55

6-
- As a regular Ethereum execution client
7-
- As a multi-prover ZK-Rollup (supporting SP1, RISC Zero and TEEs), where block execution is proven and the proof sent to an L1 network for verification, thus inheriting the L1's security. Support for based sequencing is currently in the works.
8-
9-
We call the first one "ethrex L1" and the second one "ethrex L2".
6+
* **ethrex L1** - As a regular Ethereum execution client
7+
* **ethrex L2** - As a multi-prover ZK-Rollup (supporting SP1, RISC Zero and TEEs), where block execution is proven and the proof sent to an L1 network for verification, thus inheriting the L1's security. Support for based sequencing is currently in the works.
108

119
## Quickstart L1
1210

@@ -17,14 +15,14 @@ Follow these steps to sync an ethrex node on the Hoodi testnet.
1715
Install ethrex and lighthouse:
1816

1917
```sh
20-
# install lightouse and ethrex
21-
brew install lambdaclass/tap/ethrex
22-
brew install lighthouse
23-
2418
# create secrets directory and jwt secret
2519
mkdir -p ethereum/secrets/
2620
cd ethereum/
2721
openssl rand -hex 32 | tr -d "\n" | tee ./secrets/jwt.hex
22+
23+
# install lightouse and ethrex
24+
brew install lambdaclass/tap/ethrex
25+
brew install lighthouse
2826
```
2927

3028
On one terminal:
@@ -43,6 +41,9 @@ lighthouse bn --network hoodi --execution-endpoint http://localhost:8551 --execu
4341

4442
Install ethrex and lighthouse:
4543

44+
> [!NOTE]
45+
> Go to https://github.com/sigp/lighthouse/releases/ and use the latest package there and replace that in the below commands
46+
4647
```sh
4748
# create secrets directory and jwt secret
4849
mkdir -p ethereum/secrets/
@@ -52,10 +53,11 @@ openssl rand -hex 32 | tr -d "\n" | tee ./secrets/jwt.hex
5253
# install lightouse and ethrex
5354
curl -L https://github.com/lambdaclass/ethrex/releases/latest/download/ethrex-linux-x86_64 -o ethrex
5455
chmod +x ethrex
55-
curl -LO https://github.com/sigp/lighthouse/releases/download/v7.1.0/lighthouse-v7.1.0-x86_64-unknown-linux-gnu.tar.gz
56-
tar -xvf lighthouse-v7.1.0-x86_64-unknown-linux-gnu.tar.gz
56+
curl -LO https://github.com/sigp/lighthouse/releases/download/v8.0.0/lighthouse-v8.0.0-x86_64-unknown-linux-gnu.tar.gz
57+
tar -xvf lighthouse-v8.0.0-x86_64-unknown-linux-gnu.tar.gz
5758
```
5859

60+
5961
On one terminal:
6062

6163
```sh
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Hardware Requirements
2+
3+
> NOTE: The guidance in this document applies to running an L1 (Ethereum) node. L2 deployments (sequencers, provers and related infra) have different hardware profiles and operational requirements — see the "L2" section below for details.
4+
5+
Hardware requirements depend primarily on the **network** you’re running — for example, **Hoodi**, **Sepolia**, or **Mainnet**.
6+
7+
## General Recommendations
8+
9+
Across all networks, the following apply:
10+
11+
- **Disk Type:** Use **high-performance NVMe SSDs**. For multi-disk setups, **software RAID 0** is recommended to maximize speed and capacity. **Avoid hardware RAID**, which can limit NVMe performance.
12+
- **RAM:** Sufficient memory minimizes sync bottlenecks and improves stability under load.
13+
- **CPU:** 4-8 Cores.
14+
- x86-64 bit Processors must be compatible with the instruction set AVX2.
15+
16+
17+
---
18+
19+
## Disk and Memory Requirements by Network
20+
21+
22+
23+
| Network | Disk (Minimum) | Disk (Recommended) | RAM (Minimum) | RAM (Recommended) |
24+
|------|------------------|--------------------|----------------|-------------------|
25+
| **Ethereum Mainnet** | 500 GB | 1 TB | 32 GB | 64 GB |
26+
| **Ethereum Sepolia** | 200 GB | 400 GB| 32 GB | 64 GB |
27+
| **Ethereum Hoodi** | 50 GB | 100 GB | 32 GB | 64 GB |
28+
29+
---
30+
31+
## L2
32+
33+
TBD
34+

0 commit comments

Comments
 (0)