Skip to content

Commit b1e2dc0

Browse files
authored
apollo_committer: revret block flow (#11342)
* apollo_committer: test load offset * apollo_committer: commit state diff util * apollo_committer: height hole errors * apollo_committer: revert block flow
1 parent f998b51 commit b1e2dc0

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

crates/apollo_committer/src/committer.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ use std::error::Error;
33
use std::marker::PhantomData;
44

55
use apollo_committer_config::config::CommitterConfig;
6-
use apollo_committer_types::committer_types::{CommitBlockRequest, CommitBlockResponse};
6+
use apollo_committer_types::committer_types::{
7+
CommitBlockRequest,
8+
CommitBlockResponse,
9+
RevertBlockRequest,
10+
RevertBlockResponse,
11+
};
712
use apollo_committer_types::errors::{CommitterError, CommitterResult};
813
use starknet_api::block::BlockNumber;
914
use starknet_api::block_hash::state_diff_hash::calculate_state_diff_hash;
@@ -123,6 +128,55 @@ impl<S: StorageConstructor, CB: CommitBlockTrait> Committer<S, CB> {
123128
Ok(CommitBlockResponse { state_root: global_root })
124129
}
125130

131+
/// Applies the given state diff to revert the changes of the given height.
132+
pub async fn revert_block(
133+
&mut self,
134+
RevertBlockRequest { reversed_state_diff, height }: RevertBlockRequest,
135+
) -> CommitterResult<RevertBlockResponse> {
136+
let Some(last_committed_block) = self.offset.prev() else {
137+
// No committed blocks. Nothing to revert.
138+
return Ok(RevertBlockResponse::Uncommitted);
139+
};
140+
141+
if height > self.offset {
142+
// Request to revert a future height. Nothing to revert.
143+
return Ok(RevertBlockResponse::Uncommitted);
144+
}
145+
146+
if height == self.offset {
147+
// Request to revert the next future height.
148+
// Nothing to revert, but we have the resulted state root.
149+
let db_state_root = self.load_global_root(last_committed_block).await?;
150+
return Ok(RevertBlockResponse::AlreadyReverted(db_state_root));
151+
}
152+
153+
if height < last_committed_block {
154+
// Request to revert an old height. Nothing to revert.
155+
// Returns an error, indicating the committer has a hole in the revert series.
156+
return Err(CommitterError::RevertHeightHole {
157+
input_height: height,
158+
last_committed_block,
159+
});
160+
}
161+
// Sanity.
162+
assert_eq!(height, last_committed_block);
163+
// Happy flow. Reverts the state diff and returns the computed global root.
164+
let (filled_forest, revert_global_root) =
165+
self.commit_state_diff(reversed_state_diff).await?;
166+
167+
// Ignore entries with block number key equals to or higher than the offset.
168+
let metadata = HashMap::from([(
169+
ForestMetadataType::CommitmentOffset,
170+
DbValue(DbBlockNumber(last_committed_block).serialize().to_vec()),
171+
)]);
172+
self.forest_storage
173+
.write_with_metadata(&filled_forest, metadata)
174+
.await
175+
.map_err(|err| self.map_internal_error(err))?;
176+
self.offset = last_committed_block;
177+
Ok(RevertBlockResponse::RevertedTo(revert_global_root))
178+
}
179+
126180
async fn load_state_diff_commitment(
127181
&mut self,
128182
block_number: BlockNumber,

crates/apollo_committer/src/communication.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ impl<S: StorageConstructor, CB: CommitBlockTrait>
1919
CommitterRequest::CommitBlock(commit_block_request) => {
2020
CommitterResponse::CommitBlock(self.commit_block(commit_block_request).await)
2121
}
22-
CommitterRequest::RevertBlock(_) => {
23-
// TODO(Yoav): Call the committer.
24-
unimplemented!()
22+
CommitterRequest::RevertBlock(revert_block_request) => {
23+
CommitterResponse::RevertBlock(self.revert_block(revert_block_request).await)
2524
}
2625
}
2726
}

crates/apollo_committer_types/src/committer_types.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ pub struct CommitBlockResponse {
1919
#[derive(Clone, Debug, Serialize, Deserialize)]
2020
pub struct RevertBlockRequest {
2121
// A synthetic state diff that undoes the state diff of the given height.
22-
reversed_state_diff: ThinStateDiff,
23-
height: BlockNumber,
22+
pub reversed_state_diff: ThinStateDiff,
23+
pub height: BlockNumber,
2424
}
2525

2626
#[derive(Clone, Debug, Serialize, Deserialize)]
2727
pub enum RevertBlockResponse {
28-
Uncommitted,
28+
// Nothing to revert, the committer had the resulted state root.
29+
AlreadyReverted(GlobalRoot),
30+
// The block was reverted, return the state root after reverting the state.
2931
RevertedTo(GlobalRoot),
32+
// Nothing to revert. A future block that has not been committed.
33+
Uncommitted,
3034
}

0 commit comments

Comments
 (0)