Skip to content

Commit 22d4173

Browse files
authored
fault_proving(global_roots): service definition and initial tests (#2722)
1 parent b65f7b6 commit 22d4173

File tree

22 files changed

+651
-81
lines changed

22 files changed

+651
-81
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1414
- [2150](https://github.com/FuelLabs/fuel-core/pull/2150): Upgraded `libp2p` to `0.54.1` and introduced `ConnectionLimiter` to limit pending incoming/outgoing connections.
1515
- [2491](https://github.com/FuelLabs/fuel-core/pull/2491): Storage read replays of historical blocks for execution tracing. Only available behind `--historical-execution` flag.
1616
- [2666](https://github.com/FuelLabs/fuel-core/pull/2666): Added two new CLI arguments to control the GraphQL queries consistency: `--graphql-block-height-tolerance` (default: `10`) and `--graphql-block-height-min-timeout` (default: `30s`). If a request requires a specific block height and the node is slightly behind, it will wait instead of failing.
17+
- [2722](https://github.com/FuelLabs/fuel-core/pull/2722): Service definition for state root service.
1718

1819
### Fixed
1920
- [2646](https://github.com/FuelLabs/fuel-core/pull/2646): Improved performance of fetching block height by caching it when the view is created.

Cargo.lock

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ members = [
1010
"crates/client",
1111
"crates/compression",
1212
"crates/database",
13-
"crates/fraud_proofs/global_merkle_root/storage",
1413
"crates/fuel-core",
1514
"crates/fuel-gas-price-algorithm",
1615
"crates/keygen",
1716
"crates/metrics",
17+
"crates/proof_system/global_merkle_root/service",
18+
"crates/proof_system/global_merkle_root/storage",
1819
"crates/services",
1920
"crates/services/consensus_module",
2021
"crates/services/consensus_module/bft",
@@ -96,6 +97,10 @@ fuel-core-wasm-executor = { version = "0.41.7", path = "./crates/services/upgrad
9697
fuel-core-xtask = { version = "0.0.0", path = "./xtask" }
9798
fuel-gas-price-algorithm = { version = "0.41.7", path = "crates/fuel-gas-price-algorithm" }
9899

100+
# Proof system
101+
fuel-core-global-merkle-root-storage = { version = "0.41.7", path = "./crates/proof_system/global_merkle_root/storage" }
102+
fuel-core-global-merkle-root-service = { version = "0.41.7", path = "./crates/proof_system/global_merkle_root/service" }
103+
99104
# Fuel dependencies
100105
fuel-vm-private = { version = "0.59.2", package = "fuel-vm", default-features = false }
101106

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[package]
2+
authors = { workspace = true }
3+
categories = ["cryptography::cryptocurrencies"]
4+
description = "Service definition for the global merkle root service."
5+
edition = { workspace = true }
6+
homepage = { workspace = true }
7+
keywords = ["blockchain", "cryptocurrencies", "fuel-client", "fuel-core"]
8+
license = { workspace = true }
9+
name = "fuel-core-global-merkle-root-service"
10+
repository = { workspace = true }
11+
version = { workspace = true }
12+
13+
[dependencies]
14+
anyhow = { workspace = true }
15+
async-trait = { workspace = true }
16+
fuel-core-global-merkle-root-storage = { workspace = true }
17+
fuel-core-services = { workspace = true }
18+
fuel-core-storage = { workspace = true, features = ["alloc"] }
19+
fuel-core-types = { workspace = true, default-features = false, features = [
20+
"serde",
21+
"alloc",
22+
] }
23+
tokio = { workspace = true }
24+
tracing = { workspace = true }
25+
26+
[dev-dependencies]
27+
derive_more = { workspace = true }
28+
fuel-core-global-merkle-root-storage = { workspace = true, features = [
29+
"test-helpers",
30+
] }
31+
fuel-core-storage = { workspace = true, features = ["alloc", "test-helpers"] }
32+
fuel-core-types = { workspace = true, default-features = false, features = [
33+
"serde",
34+
"random",
35+
"test-helpers",
36+
] }
37+
rand = { workspace = true }
38+
39+
[features]
40+
fault-proving = [
41+
"fuel-core-types/fault-proving",
42+
"fuel-core-storage/fault-proving",
43+
"fuel-core-global-merkle-root-storage/fault-proving",
44+
]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//! The state root service
2+
3+
#![deny(clippy::arithmetic_side_effects)]
4+
#![deny(clippy::cast_possible_truncation)]
5+
#![deny(unused_crate_dependencies)]
6+
#![deny(missing_docs)]
7+
#![deny(warnings)]
8+
9+
/// Port definitions
10+
pub mod ports;
11+
12+
/// Service definition
13+
pub mod service;
14+
15+
#[cfg(test)]
16+
mod tests;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::future::Future;
2+
3+
use fuel_core_global_merkle_root_storage::column::Column;
4+
use fuel_core_storage::{
5+
kv_store::KeyValueInspect,
6+
transactional::Modifiable,
7+
};
8+
use fuel_core_types::blockchain::block::Block;
9+
10+
/// A stream of blocks
11+
pub trait BlockStream {
12+
/// Error type
13+
type Error;
14+
15+
/// Get the next block
16+
fn next(&mut self) -> impl Future<Output = Result<Block, Self::Error>> + Send;
17+
}
18+
19+
/// The storage requirements for the merkle root service
20+
pub trait ServiceStorage: KeyValueInspect<Column = Column> + Modifiable {}
21+
22+
impl<T> ServiceStorage for T where T: KeyValueInspect<Column = Column> + Modifiable {}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
use fuel_core_global_merkle_root_storage::update::UpdateMerkleizedTables;
2+
use fuel_core_services::{
3+
RunnableService,
4+
RunnableTask,
5+
ServiceRunner,
6+
StateWatcher,
7+
TaskNextAction,
8+
};
9+
use fuel_core_storage::transactional::WriteTransaction;
10+
use fuel_core_types::fuel_types::ChainId;
11+
12+
use crate::ports::{
13+
BlockStream,
14+
ServiceStorage,
15+
};
16+
17+
/// Instantiate a new service runner.
18+
pub fn new_service<B, S>(
19+
chain_id: ChainId,
20+
storage: S,
21+
blocks: B,
22+
) -> ServiceRunner<UpdateMerkleRootTask<B, S>>
23+
where
24+
B: BlockStream + Send + 'static,
25+
B::Error: std::error::Error + Send + Sync + 'static,
26+
S: ServiceStorage + Send + 'static,
27+
{
28+
ServiceRunner::new(UpdateMerkleRootTask::new(chain_id, storage, blocks))
29+
}
30+
31+
/// The inner task definition. Holds the state of the service.
32+
pub struct UpdateMerkleRootTask<BlockStream, Storage> {
33+
chain_id: ChainId,
34+
storage: Storage,
35+
blocks: BlockStream,
36+
}
37+
38+
impl<B, S> UpdateMerkleRootTask<B, S> {
39+
/// Create a new task
40+
pub fn new(chain_id: ChainId, storage: S, blocks: B) -> Self {
41+
Self {
42+
chain_id,
43+
storage,
44+
blocks,
45+
}
46+
}
47+
}
48+
49+
#[async_trait::async_trait]
50+
impl<B, S> RunnableService for UpdateMerkleRootTask<B, S>
51+
where
52+
B: BlockStream + Send,
53+
B::Error: std::error::Error + Send + Sync + 'static,
54+
S: ServiceStorage + Send,
55+
{
56+
const NAME: &'static str = "MerkleRootService";
57+
58+
type SharedData = ();
59+
60+
type Task = Self;
61+
62+
type TaskParams = ();
63+
64+
fn shared_data(&self) -> Self::SharedData {}
65+
66+
async fn into_task(
67+
self,
68+
_state_watcher: &StateWatcher,
69+
_params: Self::TaskParams,
70+
) -> anyhow::Result<Self::Task> {
71+
Ok(self)
72+
}
73+
}
74+
75+
impl<B, S> RunnableTask for UpdateMerkleRootTask<B, S>
76+
where
77+
B: BlockStream + Send,
78+
B::Error: std::error::Error + Send + Sync + 'static,
79+
S: ServiceStorage + Send,
80+
{
81+
#[tracing::instrument(skip(self, watcher))]
82+
async fn run(&mut self, watcher: &mut StateWatcher) -> TaskNextAction {
83+
tokio::select! {
84+
biased;
85+
_ = watcher.while_started() => {
86+
TaskNextAction::Stop
87+
}
88+
_ = self.process_next_block() => {
89+
TaskNextAction::Continue
90+
}
91+
}
92+
}
93+
94+
async fn shutdown(self) -> anyhow::Result<()> {
95+
Ok(())
96+
}
97+
}
98+
99+
impl<B, S> UpdateMerkleRootTask<B, S>
100+
where
101+
B: BlockStream,
102+
B::Error: std::error::Error + Send + Sync + 'static,
103+
S: ServiceStorage,
104+
{
105+
#[tracing::instrument(skip(self))]
106+
async fn process_next_block(&mut self) -> anyhow::Result<()> {
107+
let block = self.blocks.next().await?;
108+
let mut tx = self.storage.write_transaction();
109+
110+
tx.update_merkleized_tables(self.chain_id, &block)?;
111+
112+
tx.commit()?;
113+
114+
Ok(())
115+
}
116+
}

0 commit comments

Comments
 (0)