Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Commit 9d93c0a

Browse files
authored
Feat/##1369 withdraw from beacon chain part 1 - pi circuit (#1634)
### Description 1st part of #1369, mainly on pi circuit integration ### Issue Link #1369 ### Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update ### Contents - `Withdrawal` struct definition and `WdTable` implementation - adding `withdrawals` and `withdrawal_root` in block struct - `wd_table` assignment in pi circuit
1 parent ed866f0 commit 9d93c0a

File tree

32 files changed

+1149
-254
lines changed

32 files changed

+1149
-254
lines changed

bus-mapping/src/circuit_input_builder.rs

+7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod input_state_ref;
99
#[cfg(test)]
1010
mod tracer_tests;
1111
mod transaction;
12+
mod withdrawal;
1213

1314
use self::access::gen_state_access_trace;
1415
use crate::{
@@ -36,6 +37,7 @@ use itertools::Itertools;
3637
use log::warn;
3738
use std::{collections::HashMap, ops::Deref};
3839
pub use transaction::{Transaction, TransactionContext};
40+
pub use withdrawal::{Withdrawal, WithdrawalContext};
3941

4042
/// Circuit Setup Parameters
4143
#[derive(Debug, Clone, Copy)]
@@ -47,6 +49,8 @@ pub struct FixedCParams {
4749
// TODO: evm_rows: Maximum number of rows in the EVM Circuit
4850
/// Maximum number of txs in the Tx Circuit
4951
pub max_txs: usize,
52+
/// Maximum number of withdrawals in the Withdrawal Circuit
53+
pub max_withdrawals: usize,
5054
/// Maximum number of bytes from all txs calldata in the Tx Circuit
5155
pub max_calldata: usize,
5256
/// Max ammount of rows that the CopyCircuit can have.
@@ -89,6 +93,7 @@ impl Default for FixedCParams {
8993
FixedCParams {
9094
max_rws: 1000,
9195
max_txs: 1,
96+
max_withdrawals: 1,
9297
max_calldata: 256,
9398
// TODO: Check whether this value is correct or we should increase/decrease based on
9499
// this lib tests
@@ -370,6 +375,7 @@ impl CircuitInputBuilder<DynamicCParams> {
370375
// Compute subcircuits parameters
371376
let c_params = {
372377
let max_txs = eth_block.transactions.len();
378+
let max_withdrawals = eth_block.withdrawals.as_ref().unwrap().len();
373379
let max_bytecode = self.code_db.num_rows_required_for_bytecode_table();
374380

375381
let max_calldata = eth_block
@@ -411,6 +417,7 @@ impl CircuitInputBuilder<DynamicCParams> {
411417
FixedCParams {
412418
max_rws: max_rws_after_padding,
413419
max_txs,
420+
max_withdrawals,
414421
max_calldata,
415422
max_copy_rows,
416423
max_exp_steps,

bus-mapping/src/circuit_input_builder/block.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
//! Block-related utility module
22
3-
use super::{execution::ExecState, transaction::Transaction, CopyEvent, ExecStep, ExpEvent};
3+
use super::{
4+
execution::ExecState, transaction::Transaction, CopyEvent, ExecStep, ExpEvent, Withdrawal,
5+
};
46
use crate::{
57
operation::{OperationContainer, RWCounter},
68
Error,
79
};
8-
use eth_types::{evm_unimplemented, Address, Word};
10+
use eth_types::{evm_unimplemented, Address, Word, H256};
11+
use itertools::Itertools;
912
use std::collections::HashMap;
1013

1114
/// Context of a [`Block`] which can mutate in a [`Transaction`].
@@ -148,6 +151,30 @@ impl Block {
148151
&mut self.txs
149152
}
150153

154+
/// Return the list of withdrawals of this block.
155+
pub fn withdrawals(&self) -> Vec<Withdrawal> {
156+
let eth_withdrawals = self.eth_block.withdrawals.clone().unwrap();
157+
eth_withdrawals
158+
.iter()
159+
.map({
160+
|w| {
161+
Withdrawal::new(
162+
w.index.as_u64(),
163+
w.validator_index.as_u64(),
164+
w.address,
165+
w.amount.as_u64(),
166+
)
167+
.unwrap()
168+
}
169+
})
170+
.collect_vec()
171+
}
172+
173+
/// Return root of withdrawals of this block
174+
pub fn withdrawals_root(&self) -> H256 {
175+
self.eth_block.withdrawals_root.unwrap_or_default()
176+
}
177+
151178
/// Push a copy event to the block.
152179
pub fn add_copy_event(&mut self, event: CopyEvent) {
153180
self.copy_events.push(event);

bus-mapping/src/circuit_input_builder/tracer_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use mock::{
2222
use pretty_assertions::assert_eq;
2323
use std::collections::HashSet;
2424

25-
// Helper struct that contains a CircuitInputBuilder, a particuar tx and a
25+
// Helper struct that contains a CircuitInputBuilder, a particular tx and a
2626
// particular execution step so that we can easily get a
2727
// CircuitInputStateRef to have a context in order to get the error at a
2828
// given step.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//! Withdrawal & WithdrawalContext utility module.
2+
3+
use eth_types::Address;
4+
5+
use crate::Error;
6+
7+
/// Context of a [`Withdrawal`].
8+
#[derive(Debug, Default)]
9+
pub struct WithdrawalContext {
10+
/// Unique identifier of a withdrawal. This value starts from 0 and then increases
11+
/// monotonically.
12+
id: u64,
13+
}
14+
15+
impl WithdrawalContext {
16+
/// Return id of this withdrawal.
17+
pub fn id(&self) -> u64 {
18+
self.id
19+
}
20+
}
21+
22+
/// Result of the parsing of an Ethereum Withdrawal.
23+
#[derive(Debug, Copy, Clone, Default)]
24+
pub struct Withdrawal {
25+
/// Unique identifier of a withdrawal in the whole history of withdrawals.
26+
pub id: u64,
27+
/// Unique identifier of a validator.
28+
pub validator_id: u64,
29+
/// Address to be withdrawn to.
30+
pub address: Address,
31+
/// Withdrawal amount in Gwei.
32+
pub amount: u64,
33+
}
34+
35+
impl Withdrawal {
36+
/// Create a new Self
37+
pub fn new(id: u64, validator_id: u64, address: Address, amount: u64) -> Result<Self, Error> {
38+
Ok(Self {
39+
id,
40+
validator_id,
41+
address,
42+
amount,
43+
})
44+
}
45+
/// Return the amount in this withdrawal
46+
pub fn amount_in_wei(&self) -> u64 {
47+
self.amount * (10 ^ 9)
48+
}
49+
50+
/// Constructor for padding withdrawal in withdrawal circuit
51+
pub fn padding_withdrawal(id: usize) -> Self {
52+
Self {
53+
id: id as u64,
54+
..Default::default()
55+
}
56+
}
57+
}

circuit-benchmarks/src/pi_circuit.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ mod tests {
3434
const BENCHMARK_ID: &str = "Pi Circuit";
3535

3636
const MAX_TXS: usize = 10;
37+
const MAX_WITHDRAWALS: usize = 10;
3738
const MAX_CALLDATA: usize = 128;
3839

3940
let degree: u32 = var("DEGREE")
@@ -42,7 +43,7 @@ mod tests {
4243
.expect("Cannot parse DEGREE env var as u32");
4344

4445
let public_data = generate_publicdata(MAX_TXS);
45-
let circuit = PiCircuit::<Fr>::new(MAX_TXS, MAX_CALLDATA, public_data);
46+
let circuit = PiCircuit::<Fr>::new(MAX_TXS, MAX_WITHDRAWALS, MAX_CALLDATA, public_data);
4647
let public_inputs = circuit.instance();
4748
let instance: Vec<&[Fr]> = public_inputs.iter().map(|input| &input[..]).collect();
4849
let instances = &[&instance[..]];

circuit-benchmarks/src/super_circuit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ mod tests {
8181

8282
let circuits_params = FixedCParams {
8383
max_txs: 1,
84+
max_withdrawals: 1,
8485
max_calldata: 32,
8586
max_rws: 256,
8687
max_copy_rows: 256,

eth-types/src/geth_types.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,20 @@ impl BlockConstants {
134134
}
135135
}
136136

137+
/// Definition of all of the constants related to an Ethereum withdrawal.
138+
#[derive(Debug, Default, Clone, Serialize)]
139+
pub struct Withdrawal {
140+
/// Unique identifier of a withdrawal. This value starts from 0 and then increases
141+
/// monotonically.
142+
pub id: u64,
143+
/// Unique identifier of a validator.
144+
pub validator_id: u64,
145+
/// Address to be withdrawn to.
146+
pub address: Address,
147+
/// Withdrawal amount in Gwei.
148+
pub amount: u64,
149+
}
150+
137151
/// Definition of all of the constants related to an Ethereum transaction.
138152
#[derive(Debug, Default, Clone, Serialize)]
139153
pub struct Transaction {
@@ -322,7 +336,7 @@ pub struct GethData {
322336
/// chain id
323337
pub chain_id: Word,
324338
/// history hashes contains most recent 256 block hashes in history, where
325-
/// the lastest one is at history_hashes[history_hashes.len() - 1].
339+
/// the latest one is at history_hashes[history_hashes.len() - 1].
326340
pub history_hashes: Vec<Word>,
327341
/// Block from geth
328342
pub eth_block: Block<crate::Transaction>,

external-tracer/src/lib.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
//! This module generates traces by connecting to an external tracer
22
33
use eth_types::{
4-
geth_types::{Account, BlockConstants, Transaction},
4+
geth_types::{Account, BlockConstants, Transaction, Withdrawal},
55
Address, Error, GethExecTrace, Word,
66
};
77
use serde::Serialize;
88
use std::collections::HashMap;
99

10-
/// Configuration structure for `geth_utlis::trace`
10+
/// Configuration structure for `geth_utils::trace`
1111
#[derive(Debug, Default, Clone, Serialize)]
1212
pub struct TraceConfig {
1313
/// chain id
1414
pub chain_id: Word,
1515
/// history hashes contains most recent 256 block hashes in history, where
16-
/// the lastest one is at history_hashes[history_hashes.len() - 1].
16+
/// the latest one is at history_hashes[history_hashes.len() - 1].
1717
pub history_hashes: Vec<Word>,
1818
/// block constants
1919
pub block_constants: BlockConstants,
2020
/// accounts
2121
pub accounts: HashMap<Address, Account>,
2222
/// transaction
2323
pub transactions: Vec<Transaction>,
24+
/// withdrawal
25+
pub withdrawals: Vec<Withdrawal>,
2426
/// logger
2527
pub logger_config: LoggerConfig,
2628
}

integration-tests/src/integration_test_circuits.rs

+3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ const TEST_MOCK_RANDOMNESS: u64 = 0x100;
5050

5151
/// MAX_TXS
5252
const MAX_TXS: usize = 4;
53+
/// MAX_WITHDRAWALS
54+
const MAX_WITHDRAWALS: usize = 4;
5355
/// MAX_CALLDATA
5456
const MAX_CALLDATA: usize = 512;
5557
/// MAX_RWS
@@ -68,6 +70,7 @@ const MAX_KECCAK_ROWS: usize = 38000;
6870
const CIRCUITS_PARAMS: FixedCParams = FixedCParams {
6971
max_rws: MAX_RWS,
7072
max_txs: MAX_TXS,
73+
max_withdrawals: MAX_WITHDRAWALS,
7174
max_calldata: MAX_CALLDATA,
7275
max_bytecode: MAX_BYTECODE,
7376
max_copy_rows: MAX_COPY_ROWS,

integration-tests/tests/circuit_input_builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ async fn test_circuit_input_builder_block(block_num: u64) {
1818
FixedCParams {
1919
max_rws: 16384,
2020
max_txs: 1,
21+
max_withdrawals: 1,
2122
max_calldata: 4000,
2223
max_bytecode: 4000,
2324
max_copy_rows: 16384,

mock/src/block.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! Mock Block definition and builder related methods.
22
3-
use crate::{MockTransaction, MOCK_BASEFEE, MOCK_CHAIN_ID, MOCK_DIFFICULTY, MOCK_GASLIMIT};
3+
use crate::{
4+
withdrawal::MockWithdrawal, MockTransaction, MOCK_BASEFEE, MOCK_CHAIN_ID, MOCK_DIFFICULTY,
5+
MOCK_GASLIMIT,
6+
};
47
use eth_types::{Address, Block, Bytes, Hash, Transaction, Word, H64, U64};
58
use ethers_core::{
69
types::{Bloom, OtherFields},
@@ -37,6 +40,7 @@ pub struct MockBlock {
3740
seal_fields: Vec<Bytes>,
3841
uncles: Vec<Hash>,
3942
pub(crate) transactions: Vec<MockTransaction>,
43+
pub(crate) withdrawals: Vec<MockWithdrawal>,
4044
size: Word,
4145
// This field is handled here as we assume that all block txs have the same ChainId.
4246
// Also, the field is stored in the block_table since we don't have a chain_config
@@ -71,6 +75,7 @@ impl Default for MockBlock {
7175
seal_fields: Vec::new(),
7276
uncles: Vec::new(),
7377
transactions: Vec::new(),
78+
withdrawals: Vec::new(),
7479
size: Word::zero(),
7580
chain_id: *MOCK_CHAIN_ID,
7681
}
@@ -109,8 +114,13 @@ impl From<MockBlock> for Block<Transaction> {
109114
.collect::<Vec<Transaction>>(),
110115
size: Some(mock.size),
111116
other: OtherFields::default(),
112-
withdrawals_root: None,
113-
withdrawals: None,
117+
withdrawals_root: mock.withdrawal_hash,
118+
withdrawals: Some(
119+
mock.withdrawals
120+
.iter_mut()
121+
.map(|mock_wd| mock_wd.to_owned().into())
122+
.collect(),
123+
),
114124
}
115125
}
116126
}
@@ -143,8 +153,13 @@ impl From<MockBlock> for Block<()> {
143153
transactions: vec![],
144154
size: Some(mock.size),
145155
other: OtherFields::default(),
146-
withdrawals_root: None,
147-
withdrawals: None,
156+
withdrawals_root: mock.withdrawal_hash,
157+
withdrawals: Some(
158+
mock.withdrawals
159+
.iter()
160+
.map(|mock_wd| mock_wd.to_owned().into())
161+
.collect(),
162+
),
148163
}
149164
}
150165
}

mock/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ mod account;
99
mod block;
1010
mod sha3;
1111
pub mod test_ctx;
12+
pub mod test_ctx2;
1213
mod transaction;
14+
mod withdrawal;
1315

1416
pub(crate) use account::MockAccount;
1517
pub(crate) use block::MockBlock;
1618
pub use sha3::Sha3CodeGen;
1719
pub use test_ctx::TestContext;
20+
pub use test_ctx2::TestContext2;
1821
pub use transaction::{AddrOrWallet, MockTransaction, CORRECT_MOCK_TXS};
1922

2023
/// Mock block gas limit

0 commit comments

Comments
 (0)