Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove intermediary block bloom filters #1395

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions evm/spec/cpulogic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ \subsection{Kernel}
\item the previous transaction number: $t_n$,
\item the gas used before executing the current transaction: $g\_u_0$,
\item the gas used after executing the current transaction: $g\_u_1$,
\item the block bloom filter before executing the current transaction: $b\_f_0$
\item the block bloom filter after executing the current transaction: $b\_f_1$,
\item the state, transaction and receipts MPTs before executing the current transaction: $\texttt{tries}_0$,
\item the hash of all MPTs before executing the current transaction: $\texttt{digests}_0$,
\item the hash of all MPTs after executing the current transaction: $\texttt{digests}_1$,
Expand All @@ -31,7 +29,6 @@ \subsection{Kernel}
\paragraph*{Initialization:} The first step consists in initializing:
\begin{itemize}
\item The shift table: it maps the number of bit shifts $s$ with its shifted value $1 << s$. Note that $0 \leq s \leq 255$.
\item The block bloom filter: the current block bloom filter is initialized with $b\_f_0$.
\item The initial MPTs: the initial state, transaction and receipt tries $\texttt{tries}_0$ are loaded from memory and hashed. The hashes are then compared to $\texttt{digests}\_0$.
\item We load the transaction number $t\_n$ and the current gas used $g\_u_0$ from memory.
\end{itemize}
Expand All @@ -40,15 +37,14 @@ \subsection{Kernel}

The processing of the transaction returns a boolean ``success'' that indicates whether the transaction was executed successfully, along with the leftover gas.

The following step is then to update the receipts MPT. Here, we update the transaction's bloom filter and the block bloom filter. We store ``success'', the leftover gas, the transaction bloom filter and the logs in memory. We also store some additional information that facilitates the RLP encoding of the receipts later.
The following step is then to update the receipts MPT. Here, we update the transaction's bloom filter. We store ``success'', the leftover gas, the transaction bloom filter and the logs in memory. We also store some additional information that facilitates the RLP encoding of the receipts later.

If there are any withdrawals, they are performed at this stage.

Finally, once the three MPTs have been updated, we need to carry out final checks:
\begin{itemize}
\item the gas used after the execution is equal to $g\_u_1$,
\item the new transaction number is $n+1$ if there was a transaction,
\item the updated block bloom filter is equal to $b\_f_1$,
\item the three MPTs are hashed and checked against $\texttt{digests}_1$.
\end{itemize}
Once those final checks are performed, the program halts.
Expand Down
Binary file modified evm/spec/zkevm.pdf
Binary file not shown.
17 changes: 2 additions & 15 deletions evm/src/cpu/kernel/asm/bloom_filter.asm
Original file line number Diff line number Diff line change
Expand Up @@ -147,26 +147,13 @@ logs_bloom_end:
PUSH 7 SUB
PUSH 1 SWAP1 SHL
// Updates the current txn bloom filter.
// stack: one_shifted_by_index, byte_index, byte_bit_index
DUP2 DUP1
// stack: byte_index, byte_index, one_shifted_by_index, byte_index, byte_bit_index
// load bloom_byte from current txn bloom filter
%mload_kernel(@SEGMENT_TXN_BLOOM)
%stack (old_bloom_byte, byte_index, one_shifted_by_index) -> (old_bloom_byte, one_shifted_by_index, byte_index, one_shifted_by_index)
OR
// stack: new_bloom_byte, byte_index, one_shifted_by_index, byte_index, byte_bit_index
SWAP1
%mstore_kernel(@SEGMENT_TXN_BLOOM)
// stack: one_shifted_by_index, byte_index, byte_bit_index

// Updates the block bloom filter.
SWAP2 POP DUP1
%mload_kernel(@SEGMENT_BLOCK_BLOOM)
%mload_kernel(@SEGMENT_TXN_BLOOM)
// stack: old_bloom_byte, byte_index, one_shifted_by_index
DUP3 OR
// stack: new_bloom_byte, byte_index, one_shifted_by_index
SWAP1
%mstore_kernel(@SEGMENT_BLOCK_BLOOM)
%mstore_kernel(@SEGMENT_TXN_BLOOM)
// stack: one_shifted_by_index
POP
// stack: empty
Expand Down
64 changes: 0 additions & 64 deletions evm/src/cpu/kernel/asm/main.asm
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ global main:
// Initialise the shift table
%shift_table_init

// Initialize the block bloom filter
%initialize_block_bloom

// Second, load all MPT data from the prover.
PUSH hash_initial_tries
%jump(load_all_mpts)
Expand Down Expand Up @@ -67,68 +64,7 @@ global hash_final_tries:
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_AFTER) %assert_eq
DUP3 %mload_global_metadata(@GLOBAL_METADATA_TXN_NUMBER_AFTER) %assert_eq
%pop3
%check_metadata_block_bloom
%mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) %assert_eq
%mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER) %assert_eq
%mpt_hash_receipt_trie %mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_AFTER) %assert_eq
%jump(halt)

initialize_block_bloom:
// stack: retdest
PUSH 0 PUSH 8 PUSH 0

initialize_bloom_loop:
// stack: i, len, offset, retdest
DUP2 DUP2 EQ %jumpi(initialize_bloom_loop_end)
PUSH 32 // Bloom word length
// stack: word_len, i, len, offset, retdest
// Load the next `block_bloom_before` word.
DUP2 %add_const(8) %mload_kernel(@SEGMENT_GLOBAL_BLOCK_BLOOM)
// stack: bloom_word, word_len, i, len, offset, retdest
DUP5 PUSH @SEGMENT_BLOCK_BLOOM PUSH 0 // Bloom word address in SEGMENT_BLOCK_BLOOM
%mstore_unpacking
// stack: new_offset, i, len, old_offset, retdest
SWAP3 POP %increment
// stack: i, len, new_offset, retdest
%jump(initialize_bloom_loop)

initialize_bloom_loop_end:
// stack: len, len, offset, retdest
%pop3
JUMP

%macro initialize_block_bloom
// stack: (empty)
PUSH %%after
%jump(initialize_block_bloom)
%%after:
%endmacro

check_metadata_block_bloom:
// stack: retdest
PUSH 0 PUSH 8 PUSH 0

check_bloom_loop:
// stack: i, len, offset, retdest
DUP2 DUP2 EQ %jumpi(check_bloom_loop_end)
PUSH 32 // Bloom word length
// stack: word_len, i, len, offset, retdest
DUP4 PUSH @SEGMENT_BLOCK_BLOOM PUSH 0
%mload_packing
// stack: bloom_word, i, len, offset, retdest
DUP2 %add_const(16) %mload_kernel(@SEGMENT_GLOBAL_BLOCK_BLOOM) %assert_eq
// stack: i, len, offset, retdest
%increment SWAP2 %add_const(32) SWAP2
// stack: i+1, len, new_offset, retdest
%jump(check_bloom_loop)

check_bloom_loop_end:
// stack: len, len, offset, retdest
%pop3
JUMP

%macro check_metadata_block_bloom
PUSH %%after
%jump(check_metadata_block_bloom)
%%after:
%endmacro
12 changes: 0 additions & 12 deletions evm/src/cpu/kernel/tests/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ fn test_process_receipt() -> Result<()> {
);
interpreter.set_txn_field(NormalizedTxnField::GasLimit, U256::from(5000));
interpreter.set_memory_segment(Segment::TxnBloom, vec![0.into(); 256]);
interpreter.set_memory_segment(Segment::BlockBloom, vec![0.into(); 256]);
interpreter.set_memory_segment(Segment::Logs, vec![0.into()]);
interpreter.set_global_metadata_field(GlobalMetadata::LogsPayloadLen, 58.into());
interpreter.set_global_metadata_field(GlobalMetadata::LogsLen, U256::from(1));
Expand Down Expand Up @@ -265,7 +264,6 @@ fn test_receipt_bloom_filter() -> Result<()> {
logs.extend(cur_data);
// The Bloom filter initialization is required for this test to ensure we have the correct length for the filters. Otherwise, some trailing zeroes could be missing.
interpreter.set_memory_segment(Segment::TxnBloom, vec![0.into(); 256]); // Initialize transaction Bloom filter.
interpreter.set_memory_segment(Segment::BlockBloom, vec![0.into(); 256]); // Initialize block Bloom filter.
interpreter.set_memory_segment(Segment::LogsData, logs);
interpreter.set_memory_segment(Segment::Logs, vec![0.into()]);
interpreter.set_global_metadata_field(GlobalMetadata::LogsLen, U256::from(1));
Expand Down Expand Up @@ -327,15 +325,6 @@ fn test_receipt_bloom_filter() -> Result<()> {

assert_eq!(second_bloom_bytes, second_loaded_bloom);

// Check the final block Bloom.
let block_bloom = hex!("00000000000000000000000000000000000000000000000000800000000000000040000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000008000000000000000000000000000000000000000001000000080008000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000500000000000000000000000000000002000040000000000000000000000000000000000000000000000008000000000000000000000100000000000000000000000000020000000000008000000000000000000000000").to_vec();
let loaded_block_bloom: Vec<u8> = interpreter
.get_memory_segment(Segment::BlockBloom)
.into_iter()
.map(|elt| elt.0[0] as u8)
.collect();

assert_eq!(block_bloom, loaded_block_bloom);
Ok(())
}

Expand Down Expand Up @@ -570,7 +559,6 @@ fn test_bloom_two_logs() -> Result<()> {
];
let mut interpreter = Interpreter::new_with_kernel(logs_bloom, initial_stack);
interpreter.set_memory_segment(Segment::TxnBloom, vec![0.into(); 256]); // Initialize transaction Bloom filter.
interpreter.set_memory_segment(Segment::BlockBloom, vec![0.into(); 256]); // Initialize block Bloom filter.
interpreter.set_memory_segment(Segment::LogsData, logs);
interpreter.set_memory_segment(Segment::Logs, vec![0.into(), 4.into()]);
interpreter.set_global_metadata_field(GlobalMetadata::LogsLen, U256::from(2));
Expand Down
29 changes: 0 additions & 29 deletions evm/src/fixed_recursive_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,19 +744,6 @@ where

// Connect lhs `gas_used_after` with rhs `gas_used_before`.
builder.connect(lhs.gas_used_after, rhs.gas_used_before);

// Connect the `block_bloom` in public values to the lhs and rhs values correctly.
for (&limb0, &limb1) in pvs.block_bloom_after.iter().zip(&rhs.block_bloom_after) {
builder.connect(limb0, limb1);
}
for (&limb0, &limb1) in pvs.block_bloom_before.iter().zip(&lhs.block_bloom_before) {
builder.connect(limb0, limb1);
}

// Connect lhs `block_bloom_after` with rhs `block_bloom_before`.
for (&limb0, &limb1) in lhs.block_bloom_after.iter().zip(&rhs.block_bloom_before) {
builder.connect(limb0, limb1);
}
}

fn add_agg_child(
Expand Down Expand Up @@ -928,15 +915,6 @@ where
x.block_metadata.block_gas_used,
x.extra_block_data.gas_used_after,
);

for (&limb0, &limb1) in x
.block_metadata
.block_bloom
.iter()
.zip(&x.extra_block_data.block_bloom_after)
{
builder.connect(limb0, limb1);
}
}

fn connect_initial_values_block(builder: &mut CircuitBuilder<F, D>, x: &PublicValuesTarget)
Expand All @@ -948,11 +926,6 @@ where
// The initial gas used is 0.
builder.assert_zero(x.extra_block_data.gas_used_before);

// The initial bloom filter is all zeroes.
for t in x.extra_block_data.block_bloom_before {
builder.assert_zero(t);
}

// The transactions and receipts tries are empty at the beginning of the block.
let initial_trie = HashedPartialTrie::from(Node::Empty).hash();

Expand Down Expand Up @@ -1058,8 +1031,6 @@ where
txn_number_after: rhs_public_values.extra_block_data.txn_number_after,
gas_used_before: lhs_public_values.extra_block_data.gas_used_before,
gas_used_after: rhs_public_values.extra_block_data.gas_used_after,
block_bloom_before: lhs_public_values.extra_block_data.block_bloom_before,
block_bloom_after: rhs_public_values.extra_block_data.block_bloom_after,
},
block_metadata: rhs_public_values.block_metadata,
block_hashes: rhs_public_values.block_hashes,
Expand Down
31 changes: 1 addition & 30 deletions evm/src/generation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ use crate::witness::util::mem_write_log;
pub struct GenerationInputs {
pub txn_number_before: U256,
pub gas_used_before: U256,
pub block_bloom_before: [U256; 8],
pub gas_used_after: U256,
pub block_bloom_after: [U256; 8],

// A None would yield an empty proof, otherwise this contains the encoding of a transaction.
pub signed_txn: Option<Vec<u8>>,
Expand Down Expand Up @@ -174,32 +172,7 @@ fn apply_metadata_and_tries_memops<F: RichField + Extendable<D>, const D: usize>
metadata.block_bloom[i],
)
}));
// Write the block's bloom filter before the current transaction.
ops.extend(
(0..8)
.map(|i| {
mem_write_log(
channel,
MemoryAddress::new(0, Segment::GlobalBlockBloom, i + 8),
state,
inputs.block_bloom_before[i],
)
})
.collect::<Vec<_>>(),
);
// Write the block's bloom filter after the current transaction.
ops.extend(
(0..8)
.map(|i| {
mem_write_log(
channel,
MemoryAddress::new(0, Segment::GlobalBlockBloom, i + 16),
state,
inputs.block_bloom_after[i],
)
})
.collect::<Vec<_>>(),
);

// Write previous block hashes.
ops.extend(
(0..256)
Expand Down Expand Up @@ -284,8 +257,6 @@ pub fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
txn_number_after,
gas_used_before: inputs.gas_used_before,
gas_used_after,
block_bloom_before: inputs.block_bloom_before,
block_bloom_after: inputs.block_bloom_after,
};

let public_values = PublicValues {
Expand Down
8 changes: 0 additions & 8 deletions evm/src/get_challenges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,6 @@ fn observe_extra_block_data<
challenger.observe_element(u256_to_u32(extra_data.txn_number_after)?);
challenger.observe_element(u256_to_u32(extra_data.gas_used_before)?);
challenger.observe_element(u256_to_u32(extra_data.gas_used_after)?);
for i in 0..8 {
challenger.observe_elements(&u256_limbs(extra_data.block_bloom_before[i]));
}
for i in 0..8 {
challenger.observe_elements(&u256_limbs(extra_data.block_bloom_after[i]));
}

Ok(())
}
Expand All @@ -134,8 +128,6 @@ fn observe_extra_block_data_target<
challenger.observe_element(extra_data.txn_number_after);
challenger.observe_element(extra_data.gas_used_before);
challenger.observe_element(extra_data.gas_used_after);
challenger.observe_elements(&extra_data.block_bloom_before);
challenger.observe_elements(&extra_data.block_bloom_after);
}

fn observe_block_hashes<
Expand Down
29 changes: 11 additions & 18 deletions evm/src/memory/segments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,25 @@ pub(crate) enum Segment {
SelfDestructList = 25,
/// Contains the bloom filter of a transaction.
TxnBloom = 26,
/// Contains the computed bloom filter of a block.
BlockBloom = 27,
/// Contains the final block bloom, and the block bloom filters before and after the current transaction.
/// The first eight elements are `block_metadata.block_bloom`. The next eight are `block_bloom_before`,
/// and the last eight are `block_bloom_after.
GlobalBlockBloom = 28,
/// Contains the bloom filter present in the block header.
GlobalBlockBloom = 27,
/// List of log pointers pointing to the LogsData segment.
Logs = 29,
LogsData = 30,
Logs = 28,
LogsData = 29,
/// Journal of state changes. List of pointers to `JournalData`. Length in `GlobalMetadata`.
Journal = 31,
JournalData = 32,
JournalCheckpoints = 33,
Journal = 30,
JournalData = 31,
JournalCheckpoints = 32,
/// List of addresses that have been touched in the current transaction.
TouchedAddresses = 34,
TouchedAddresses = 33,
/// List of checkpoints for the current context. Length in `ContextMetadata`.
ContextCheckpoints = 35,
ContextCheckpoints = 34,
/// List of 256 previous block hashes.
BlockHashes = 36,
BlockHashes = 35,
}

impl Segment {
pub(crate) const COUNT: usize = 37;
pub(crate) const COUNT: usize = 36;

pub(crate) fn all() -> [Self; Self::COUNT] {
[
Expand Down Expand Up @@ -103,7 +99,6 @@ impl Segment {
Self::AccessedStorageKeys,
Self::SelfDestructList,
Self::TxnBloom,
Self::BlockBloom,
Self::GlobalBlockBloom,
Self::Logs,
Self::LogsData,
Expand Down Expand Up @@ -146,7 +141,6 @@ impl Segment {
Segment::AccessedStorageKeys => "SEGMENT_ACCESSED_STORAGE_KEYS",
Segment::SelfDestructList => "SEGMENT_SELFDESTRUCT_LIST",
Segment::TxnBloom => "SEGMENT_TXN_BLOOM",
Segment::BlockBloom => "SEGMENT_BLOCK_BLOOM",
Segment::GlobalBlockBloom => "SEGMENT_GLOBAL_BLOCK_BLOOM",
Segment::Logs => "SEGMENT_LOGS",
Segment::LogsData => "SEGMENT_LOGS_DATA",
Expand Down Expand Up @@ -189,7 +183,6 @@ impl Segment {
Segment::SelfDestructList => 256,
Segment::TxnBloom => 8,
Segment::GlobalBlockBloom => 256,
Segment::BlockBloom => 8,
Segment::Logs => 256,
Segment::LogsData => 256,
Segment::Journal => 256,
Expand Down
Loading
Loading