Skip to content

Commit

Permalink
refac: sequencer and lc error handling, refactored sync loop
Browse files Browse the repository at this point in the history
  • Loading branch information
sebasti810 committed Jul 29, 2024
1 parent 4b73fbb commit 26d4c7e
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 150 deletions.
146 changes: 78 additions & 68 deletions src/node_types/lightclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use crate::{
cfg::CelestiaConfig,
error::{DataAvailabilityError, GeneralError, PrismResult},
};
use anyhow::Context;
use async_trait::async_trait;
use celestia_types::Height;
use std::{self, sync::Arc, time::Duration};
use tokio::{task::spawn, time::interval};

Expand All @@ -23,13 +25,15 @@ pub struct LightClient {
impl NodeType for LightClient {
async fn start(self: Arc<Self>) -> PrismResult<()> {
// start listening for new headers to update sync target
match self.da.start().await {
Ok(_) => (),
Err(e) => return Err(DataAvailabilityError::InitializationError(e.to_string()).into()),
};
self.da
.start()
.await
.context("Failed to start DataAvailabilityLayer")
.map_err(|e| DataAvailabilityError::InitializationError(e.to_string()))?;

self.sync_loop()
.await
.context("Sync loop failed")
.map_err(|e| GeneralError::InitializationError(e.to_string()).into())
}
}
Expand Down Expand Up @@ -64,75 +68,81 @@ impl LightClient {
};

debug!("updated sync target to height {}", target);
for i in current_position..target {
trace!("processing height: {}", i);
match self.da.get(i + 1).await {
Ok(epoch_json_vec) => {
if !epoch_json_vec.is_empty() {
debug!("light client: got epochs at height {}", i + 1);
}

// todo: verify adjacency to last heights, <- for this we need some sort of storage of epochs
for epoch_json in epoch_json_vec {
let prev_commitment = &epoch_json.prev_commitment;
let current_commitment = &epoch_json.current_commitment;

let proof = match epoch_json.proof.clone().try_into() {
Ok(proof) => proof,
Err(e) => {
error!("failed to deserialize proof, skipping a blob at height {}: {:?}", i, e);
continue;
}
};

// TODO(@distractedm1nd): i don't know rust yet but this seems like non-idiomatic rust -
// is there not a Trait that can satisfy these properties for us?
let verifying_key = match epoch_json.verifying_key.clone().try_into() {
Ok(vk) => vk,
Err(e) => {
error!("failed to deserialize verifying key, skipping a blob at height {}: {:?}", i, e);
continue;
}
};

// if the user does not add a verifying key, we will not verify the signature,
// but only log a warning on startup
if self.verifying_key.is_some() {
match verify_signature(
&epoch_json.clone(),
self.verifying_key.clone(),
) {
Ok(_) => trace!("valid signature for epoch {}", epoch_json.height),
Err(e) => {
panic!("invalid signature in epoch {}: {:?}", i, e)
}
}
}

match validate_epoch(
prev_commitment,
current_commitment,
proof,
verifying_key,
) {
Ok(_) => {
info!(
"zkSNARK for epoch {} was validated successfully",
epoch_json.height
)
}
Err(err) => panic!("failed to validate epoch: {:?}", err),
}
}
}

for height in current_position..target {
match self.process_height(height + 1).await {
Ok(_) => {}
Err(e) => {
debug!("light client: getting epoch: {}", e)
error!("Error processing height {}: {:?}", height + 1, e);
// @distractedm1nd: should we break the loop here? or continue? retry?
continue;
}
};
}
}

ticker.tick().await; // only for testing purposes
current_position = target; // Update the current position to the latest target
}
}).await
})
.await
}

async fn process_height(&self, height: u64) -> PrismResult<()> {
let epoch_json_vec = self
.da
.get(height)
.await
.context(format!("Failed to get epoch at height {}", height))?;

if !epoch_json_vec.is_empty() {
debug!("Light client: got epochs at height {}", height);
}

for epoch_json in epoch_json_vec {
self.process_epoch(epoch_json, height).await?;
}

Ok(())
}

async fn process_epoch(
&self,
epoch_json: crate::da::FinalizedEpoch,
height: u64,
) -> PrismResult<()> {
let proof = epoch_json
.proof
.clone()
.try_into()
.context(format!("Failed to deserialize proof at height {}", height))?;

let verifying_key = epoch_json
.verifying_key
.clone()
.try_into()
.context(format!(
"Failed to deserialize verifying key at height {}",
height
))?;

if let Some(ref vk) = self.verifying_key {
verify_signature(&epoch_json, Some(vk.clone()))
.context(format!("Invalid signature in epoch at height {}", height))?;
trace!("Valid signature for epoch {}", epoch_json.height);
}

validate_epoch(
&epoch_json.prev_commitment,
&epoch_json.current_commitment,
proof,
verifying_key,
)
.context(format!("Failed to validate epoch at height {}", height))?;

info!(
"zkSNARK for epoch {} was validated successfully",
epoch_json.height
);
Ok(())
}
}
Loading

0 comments on commit 26d4c7e

Please sign in to comment.