Skip to content

Commit

Permalink
Keep record of events from L1 in Block Header (#1769)
Browse files Browse the repository at this point in the history
closes FuelLabs/fuel-core#1741

This PR introduces a new field on the block header generated section
called `event_inbox_root`. This is calculated after execution by adding
all the hashes of the events from the L1 relayer to a merkle tree and
generating the root.

Also renamed the message receipt root to `message_outbox_root` to keep
up the theme.
  • Loading branch information
crypto523 committed Mar 22, 2024
1 parent 45fafe5 commit 380dd0d
Show file tree
Hide file tree
Showing 22 changed files with 141 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Description of the upcoming release here.
### Changed

#### Breaking
- [#1769](https://github.com/FuelLabs/fuel-core/pull/1769): Include new field on header for the merkle root of imported events. Rename other message root field.
- [#1768](https://github.com/FuelLabs/fuel-core/pull/1768): Moved `ContractsInfo` table to the off-chain database. Removed `salt` field from the `ContractConfig`.
- [#1761](https://github.com/FuelLabs/fuel-core/pull/1761): Adjustments to the upcoming testnet configs:
- Decreased the max size of the contract/predicate/script to be 100KB.
Expand Down
6 changes: 5 additions & 1 deletion crates/client/assets/schema.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,11 @@ type Header {
"""
Merkle root of message receipts in this block.
"""
messageReceiptRoot: Bytes32!
messageOutboxRoot: Bytes32!
"""
Merkle root of inbox events in this block.
"""
eventInboxRoot: Bytes32!
"""
Fuel block height.
"""
Expand Down
3 changes: 2 additions & 1 deletion crates/client/src/client/schema/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ pub struct Header {
pub transactions_count: U64,
pub message_receipt_count: U64,
pub transactions_root: Bytes32,
pub message_receipt_root: Bytes32,
pub message_outbox_root: Bytes32,
pub event_inbox_root: Bytes32,
pub height: U32,
pub prev_root: Bytes32,
pub time: Tai64Timestamp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ query($height: U32) {
transactionsCount
messageReceiptCount
transactionsRoot
messageReceiptRoot
messageOutboxRoot
eventInboxRoot
height
prevRoot
time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ query($id: BlockId) {
transactionsCount
messageReceiptCount
transactionsRoot
messageReceiptRoot
messageOutboxRoot
eventInboxRoot
height
prevRoot
time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ query($after: String, $before: String, $first: Int, $last: Int) {
transactionsCount
messageReceiptCount
transactionsRoot
messageReceiptRoot
messageOutboxRoot
eventInboxRoot
height
prevRoot
time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ query {
transactionsCount
messageReceiptCount
transactionsRoot
messageReceiptRoot
messageOutboxRoot
eventInboxRoot
height
prevRoot
time
Expand Down
6 changes: 4 additions & 2 deletions crates/client/src/client/types/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ pub struct Header {
pub transactions_count: u64,
pub message_receipt_count: u64,
pub transactions_root: MerkleRoot,
pub message_receipt_root: MerkleRoot,
pub message_outbox_root: MerkleRoot,
pub event_inbox_root: MerkleRoot,
pub height: u32,
pub prev_root: MerkleRoot,
pub time: Tai64,
Expand Down Expand Up @@ -77,7 +78,8 @@ impl From<schema::block::Header> for Header {
transactions_count: value.transactions_count.into(),
message_receipt_count: value.message_receipt_count.into(),
transactions_root: value.transactions_root.into(),
message_receipt_root: value.message_receipt_root.into(),
message_outbox_root: value.message_outbox_root.into(),
event_inbox_root: value.event_inbox_root.into(),
height: value.height.into(),
prev_root: value.prev_root.into(),
time: value.time.0,
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/database/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ mod tests {
},
};
let block = PartialFuelBlock::new(header, vec![]);
block.generate(&[])
block.generate(&[], Default::default())
})
.collect::<Vec<_>>();

Expand Down
37 changes: 37 additions & 0 deletions crates/fuel-core/src/executor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[allow(clippy::arithmetic_side_effects)]
#[allow(clippy::cast_possible_truncation)]
#[allow(non_snake_case)]
#[cfg(test)]
mod tests {
use crate as fuel_core;
Expand Down Expand Up @@ -2953,6 +2954,7 @@ mod tests {
},
StorageAsMut,
};
use fuel_core_types::fuel_merkle::binary::root_calculator::MerkleRootCalculator;

fn database_with_genesis_block(da_block_height: u64) -> Database<OnChain> {
let mut db = Database::default();
Expand Down Expand Up @@ -3099,6 +3101,41 @@ mod tests {
Ok(())
}

#[test]
fn execute_without_commit__block_producer_includes_correct_inbox_event_merkle_root(
) {
// given
let genesis_da_height = 3u64;
let on_chain_db = database_with_genesis_block(genesis_da_height);
let mut relayer_db = Database::<Relayer>::default();
let block_height = 1u32;
let relayer_da_height = 10u64;
let mut root_calculator = MerkleRootCalculator::new();
for da_height in (genesis_da_height + 1)..=relayer_da_height {
let mut message = Message::default();
message.set_da_height(da_height.into());
message.set_nonce(da_height.into());
root_calculator.push(message.id().as_ref());
add_message_to_relayer(&mut relayer_db, message);
}
let producer = create_relayer_executor(on_chain_db, relayer_db);
let block = test_block(block_height.into(), relayer_da_height.into(), 0);

// when
let (result, _) = producer
.execute_without_commit(
ExecutionTypes::Production(block.into()),
Default::default(),
)
.unwrap()
.into();

// then
let expected = root_calculator.root().into();
let actual = result.block.header().application().event_inbox_root;
assert_eq!(actual, expected);
}

#[test]
fn block_producer_does_not_take_messages_for_the_same_height() {
let genesis_da_height = 1u64;
Expand Down
8 changes: 4 additions & 4 deletions crates/fuel-core/src/query/message/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ async fn can_build_message_proof() {
generated: Default::default(),
},
}
.generate(&[], &[]);
.generate(&[], &[], Default::default());
let commit_block = CompressedBlock::test(commit_block_header, vec![]);
let message_block_header = PartialBlockHeader {
application: ApplicationHeader {
Expand All @@ -157,7 +157,7 @@ async fn can_build_message_proof() {
generated: Default::default(),
},
}
.generate(&[], &message_ids);
.generate(&[], &message_ids, Default::default());
let message_block = CompressedBlock::test(message_block_header, TXNS.to_vec());

let block_proof = MerkleProof {
Expand Down Expand Up @@ -213,8 +213,8 @@ async fn can_build_message_proof() {
.unwrap()
.unwrap();
assert_eq!(
proof.message_block_header.message_receipt_root,
message_block.header().message_receipt_root
proof.message_block_header.message_outbox_root,
message_block.header().message_outbox_root
);
assert_eq!(
proof.message_block_header.height(),
Expand Down
9 changes: 7 additions & 2 deletions crates/fuel-core/src/schema/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,13 @@ impl Header {
}

/// Merkle root of message receipts in this block.
async fn message_receipt_root(&self) -> Bytes32 {
self.0.message_receipt_root.into()
async fn message_outbox_root(&self) -> Bytes32 {
self.0.message_outbox_root.into()
}

/// Merkle root of inbox events in this block.
async fn event_inbox_root(&self) -> Bytes32 {
self.0.event_inbox_root.into()
}

/// Fuel block height.
Expand Down
11 changes: 6 additions & 5 deletions crates/fuel-core/src/service/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ fn cleanup_genesis_progress(
pub fn create_genesis_block(config: &Config) -> Block {
let block_height = config.state_reader.block_height();
let da_block_height = config.state_reader.da_block_height();
let transactions = vec![];
let message_ids = &[];
let events = Default::default();
Block::new(
PartialBlockHeader {
application: ApplicationHeader::<Empty> {
Expand All @@ -171,17 +174,15 @@ pub fn create_genesis_block(config: &Config) -> Block {
generated: Empty,
},
consensus: ConsensusHeader::<Empty> {
// The genesis is a first block, so previous root is zero.
prev_root: Bytes32::zeroed(),
// The block height at genesis.
height: block_height,
time: fuel_core_types::tai64::Tai64::UNIX_EPOCH,
generated: Empty,
},
},
// Genesis block doesn't have any transaction.
vec![],
&[],
transactions,
message_ids,
events,
)
}

Expand Down
2 changes: 1 addition & 1 deletion crates/services/consensus_module/poa/src/verifier/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn correct() -> Input {
..Default::default()
},
};
let block_header = partial_header.generate(&txs, &[]);
let block_header = partial_header.generate(&txs, &[], Default::default());

Input {
block_header_merkle_root: [2u8; 32],
Expand Down
11 changes: 10 additions & 1 deletion crates/services/executor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ use fuel_core_types::{
RegId,
Word,
},
fuel_merkle::binary::root_calculator::MerkleRootCalculator,
fuel_tx::{
field::{
InputContract,
Expand Down Expand Up @@ -304,6 +305,7 @@ pub struct ExecutionData {
events: Vec<ExecutorEvent>,
changes: Changes,
pub skipped_transactions: Vec<(TxId, ExecutorError)>,
event_inbox_root: Bytes32,
}

/// Per-block execution options
Expand Down Expand Up @@ -499,12 +501,13 @@ where
skipped_transactions,
events,
changes,
event_inbox_root,
..
} = execution_data;

// Now that the transactions have been executed, generate the full header.

let block = block.generate(&message_ids[..]);
let block = block.generate(&message_ids[..], event_inbox_root);

let finalized_block_id = block.id();

Expand Down Expand Up @@ -557,6 +560,7 @@ where
events: Vec::new(),
changes: Default::default(),
skipped_transactions: Vec::new(),
event_inbox_root: Default::default(),
};
let execution_data = &mut data;

Expand Down Expand Up @@ -724,13 +728,16 @@ where
return Err(ExecutorError::DaHeightExceededItsLimit)
};

let mut root_calculator = MerkleRootCalculator::new();

for da_height in next_unprocessed_da_height..=header.da_height.0 {
let da_height = da_height.into();
let events = self
.relayer
.get_events(&da_height)
.map_err(|err| ExecutorError::RelayerError(err.into()))?;
for event in events {
root_calculator.push(event.hash().as_ref());
match event {
Event::Message(message) => {
if message.da_height() != da_height {
Expand All @@ -747,6 +754,8 @@ where
}
}

execution_data.event_inbox_root = root_calculator.root().into();

Ok(())
}

Expand Down
8 changes: 4 additions & 4 deletions crates/services/producer/src/block_producer/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ mod produce_and_execute_block_txpool {
},
transactions: vec![],
}
.generate(&[])
.generate(&[], Default::default())
.compress(&Default::default());

let db = MockDb {
Expand Down Expand Up @@ -162,7 +162,7 @@ mod produce_and_execute_block_txpool {
},
transactions: vec![],
}
.generate(&[])
.generate(&[], Default::default())
.compress(&Default::default());

// Given
Expand Down Expand Up @@ -215,7 +215,7 @@ mod produce_and_execute_block_txpool {
},
transactions: vec![],
}
.generate(&[])
.generate(&[], Default::default())
.compress(&Default::default());

// Given
Expand Down Expand Up @@ -284,7 +284,7 @@ mod produce_and_execute_block_txpool {
},
transactions: vec![],
}
.generate(&[])
.generate(&[], Default::default())
.compress(&Default::default());

let db = MockDb {
Expand Down
7 changes: 6 additions & 1 deletion crates/services/producer/src/mocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,12 @@ fn to_block(component: &Components<Vec<ArcPoolTx>>) -> Block {
.into_iter()
.map(|tx| tx.as_ref().into())
.collect();
Block::new(component.header_to_produce.clone(), transactions, &[])
Block::new(
component.header_to_produce.clone(),
transactions,
&[],
Default::default(),
)
}

impl Executor<Vec<ArcPoolTx>> for MockExecutor {
Expand Down
2 changes: 1 addition & 1 deletion crates/storage/src/structured_storage/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ mod tests {
},
};
let block = PartialFuelBlock::new(header, vec![]);
block.generate(&[])
block.generate(&[], Default::default())
})
.collect::<Vec<_>>();

Expand Down
Loading

0 comments on commit 380dd0d

Please sign in to comment.