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

Centralized Signed Blobs #604

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
14 changes: 7 additions & 7 deletions protocol-units/da/m1/light-node-verifier/src/celestia/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{Error, Verified, VerifierOperations};
use celestia_rpc::Client;
use celestia_types::{nmt::Namespace, Blob};
use m1_da_light_node_util::inner_blob::InnerBlob;
use m1_da_light_node_util::ir_blob::IntermediateBlobRepresentation;
use std::sync::Arc;

#[derive(Clone)]
Expand All @@ -19,13 +19,13 @@ impl Verifier {
}

#[tonic::async_trait]
impl VerifierOperations<Blob, InnerBlob> for Verifier {
/// Verifies a Celestia Blob as a Valid InnerBlob
async fn verify(&self, blob: Blob, _height: u64) -> Result<Verified<InnerBlob>, Error> {
// Only assert that we can indeed get an InnerBlob from the Blob
let inner_blob = InnerBlob::try_from(blob).map_err(|e| Error::Internal(e.to_string()))?;
impl VerifierOperations<Blob, IntermediateBlobRepresentation> for Verifier {
/// Verifies a Celestia Blob as a Valid IntermediateBlobRepresentation
async fn verify(&self, blob: Blob, _height: u64) -> Result<Verified<IntermediateBlobRepresentation>, Error> {
// Only assert that we can indeed get an IntermediateBlobRepresentation from the Blob
let ir_blob = IntermediateBlobRepresentation::try_from(blob).map_err(|e| Error::Internal(e.to_string()))?;

Ok(Verified::new(inner_blob))
Ok(Verified::new(ir_blob))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{Error, Verified, VerifierOperations};
use celestia_rpc::Client;
use celestia_rpc::{BlobClient, HeaderClient};
use celestia_types::{nmt::Namespace, Blob};
use m1_da_light_node_util::inner_blob::InnerBlob;
use m1_da_light_node_util::ir_blob::IntermediateBlobRepresentation;
use std::sync::Arc;

#[derive(Clone)]
Expand All @@ -20,9 +20,9 @@ impl Verifier {
}

#[tonic::async_trait]
impl VerifierOperations<Blob, InnerBlob> for Verifier {
/// Verifies a Celestia Blob as a Valid InnerBlob
async fn verify(&self, blob: Blob, height: u64) -> Result<Verified<InnerBlob>, Error> {
impl VerifierOperations<Blob, IntermediateBlobRepresentation> for Verifier {
/// Verifies a Celestia Blob as a Valid IntermediateBlobRepresentation
async fn verify(&self, blob: Blob, height: u64) -> Result<Verified<IntermediateBlobRepresentation>, Error> {
//@l-monninger: the light node itself does most of the work of verify blobs. The verification under the feature flag below is useful in zero-trust environments.

blob.validate().map_err(|e| Error::Validation(e.to_string()))?;
Expand Down Expand Up @@ -61,8 +61,8 @@ impl VerifierOperations<Blob, InnerBlob> for Verifier {
})?;
}

let inner_blob = InnerBlob::try_from(blob).map_err(|e| Error::Internal(e.to_string()))?;
let ir_blob = IntermediateBlobRepresentation::try_from(blob).map_err(|e| Error::Internal(e.to_string()))?;

Ok(Verified::new(inner_blob))
Ok(Verified::new(ir_blob))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use ecdsa::{
hazmat::{DigestPrimitive, SignPrimitive, VerifyPrimitive},
SignatureSize,
};
use m1_da_light_node_util::inner_blob::InnerBlob;
use m1_da_light_node_util::ir_blob::IntermediateBlobRepresentation;
use std::sync::Arc;

/// A verifier of Celestia blobs for permissioned signers
Expand Down Expand Up @@ -61,15 +61,15 @@ where
}

#[tonic::async_trait]
impl<C> VerifierOperations<CelestiaBlob, InnerBlob> for Verifier<C>
impl<C> VerifierOperations<CelestiaBlob, IntermediateBlobRepresentation> for Verifier<C>
where
C: PrimeCurve + CurveArithmetic + DigestPrimitive + PointCompression,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
SignatureSize<C>: ArrayLength<u8>,
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C> + VerifyPrimitive<C>,
FieldBytesSize<C>: ModulusSize,
{
async fn verify(&self, blob: CelestiaBlob, height: u64) -> Result<Verified<InnerBlob>, Error> {
async fn verify(&self, blob: CelestiaBlob, height: u64) -> Result<Verified<IntermediateBlobRepresentation>, Error> {
let verified_blob = self.celestia.verify(blob, height).await?;
self.known_signers.verify(verified_blob.into_inner(), height).await
}
Expand Down
28 changes: 14 additions & 14 deletions protocol-units/da/m1/light-node-verifier/src/signed/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use ecdsa::{
hazmat::{DigestPrimitive, SignPrimitive, VerifyPrimitive},
SignatureSize,
};
use m1_da_light_node_util::inner_blob::InnerBlob;
use m1_da_light_node_util::ir_blob::IntermediateBlobRepresentation;
use std::collections::HashSet;
use tracing::info;

Expand Down Expand Up @@ -42,15 +42,15 @@ where
}

#[tonic::async_trait]
impl<C> VerifierOperations<InnerBlob, InnerBlob> for Verifier<C>
impl<C> VerifierOperations<IntermediateBlobRepresentation, IntermediateBlobRepresentation> for Verifier<C>
where
C: PrimeCurve + CurveArithmetic + DigestPrimitive + PointCompression,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
SignatureSize<C>: ArrayLength<u8>,
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C> + VerifyPrimitive<C>,
FieldBytesSize<C>: ModulusSize,
{
async fn verify(&self, blob: InnerBlob, _height: u64) -> Result<Verified<InnerBlob>, Error> {
async fn verify(&self, blob: IntermediateBlobRepresentation, _height: u64) -> Result<Verified<IntermediateBlobRepresentation>, Error> {
blob.verify_signature::<C>().map_err(|e| Error::Validation(e.to_string()))?;

Ok(Verified::new(blob))
Expand Down Expand Up @@ -97,31 +97,31 @@ where
}

#[tonic::async_trait]
impl<C> VerifierOperations<InnerBlob, InnerBlob> for InKnownSignersVerifier<C>
impl<C> VerifierOperations<IntermediateBlobRepresentation, IntermediateBlobRepresentation> for InKnownSignersVerifier<C>
where
C: PrimeCurve + CurveArithmetic + DigestPrimitive + PointCompression,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
SignatureSize<C>: ArrayLength<u8>,
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C> + VerifyPrimitive<C>,
FieldBytesSize<C>: ModulusSize,
{
async fn verify(&self, blob: InnerBlob, height: u64) -> Result<Verified<InnerBlob>, Error> {
let inner_blob = self.inner_verifier.verify(blob, height).await?;
async fn verify(&self, blob: IntermediateBlobRepresentation, height: u64) -> Result<Verified<IntermediateBlobRepresentation>, Error> {
let ir_blob = self.inner_verifier.verify(blob, height).await?;
info!("Verified inner blob");
let signer = inner_blob.inner().signer_hex();
let signer = ir_blob.inner().signer_hex();
if !self.known_signers_sec1_bytes_hex.contains(&signer) {
return Err(Error::Validation("signer not in known signers".to_string()));
}

Ok(inner_blob)
Ok(ir_blob)
}
}

#[cfg(test)]
pub mod tests {
/*use ecdsa::SigningKey;
use k256::Secp256k1;
use m1_da_light_node_util::inner_blob::{InnerSignedBlobV1, InnerSignedBlobV1Data, InnerBlob};
use m1_da_light_node_util::ir_blob::{InnerSignedBlobV1, InnerSignedBlobV1Data, IntermediateBlobRepresentation};
use std::iter::FromIterator;

#[tokio::test]
Expand All @@ -130,14 +130,14 @@ pub mod tests {
// rand_core
&mut rand::rngs::OsRng,
);
let blob : InnerBlob = InnerSignedBlobV1::tr
let blob : IntermediateBlobRepresentation = InnerSignedBlobV1::tr

let inner_blob = create_inner_blob("known_signer");
let verified = verifier.verify(inner_blob, 0).await.unwrap();
let ir_blob = create_ir_blob("known_signer");
let verified = verifier.verify(ir_blob, 0).await.unwrap();
assert_eq!(verified.inner().signer_hex(), "known_signer");

let inner_blob = create_inner_blob("unknown_signer");
let verified = verifier.verify(inner_blob, 0).await;
let ir_blob = create_ir_blob("unknown_signer");
let verified = verifier.verify(ir_blob, 0).await;
assert!(verified.is_err());
}*/
}
48 changes: 27 additions & 21 deletions protocol-units/da/m1/light-node/src/v1/passthrough.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use m1_da_light_node_util::inner_blob::InnerBlob;
use m1_da_light_node_util::ir_blob::IntermediateBlobRepresentation;
use std::fmt::{self, Debug, Formatter};
use std::sync::Arc;
use tokio_stream::{Stream, StreamExt};
Expand All @@ -12,7 +12,7 @@ use m1_da_light_node_grpc::light_node_service_server::LightNodeService;
use m1_da_light_node_grpc::*;
use m1_da_light_node_util::{
config::Config,
inner_blob::{celestia::CelestiaInnerBlob, InnerSignedBlobV1Data},
ir_blob::{celestia::CelestiaIntermediateBlobRepresentation, InnerSignedBlobV1Data},
};
use m1_da_light_node_verifier::{permissioned_signers::Verifier, VerifierOperations};

Expand Down Expand Up @@ -42,7 +42,9 @@ where
pub config: Config,
pub celestia_namespace: Namespace,
pub default_client: Arc<Client>,
pub verifier: Arc<Box<dyn VerifierOperations<CelestiaBlob, InnerBlob> + Send + Sync>>,
pub verifier: Arc<
Box<dyn VerifierOperations<CelestiaBlob, IntermediateBlobRepresentation> + Send + Sync>,
>,
pub signing_key: SigningKey<C>,
}

Expand Down Expand Up @@ -119,7 +121,8 @@ where
let data = InnerSignedBlobV1Data::new(data, timestamp).try_to_sign(&self.signing_key)?;

// create the celestia blob
CelestiaInnerBlob(data.into(), self.celestia_namespace.clone()).try_into()
CelestiaIntermediateBlobRepresentation(data.into(), self.celestia_namespace.clone())
.try_into()
}

/// Submits a CelestiaBlob to the Celestia node.
Expand Down Expand Up @@ -155,10 +158,10 @@ where
}

/// Gets the blobs at a given height.
pub async fn get_inner_blobs_at_height(
pub async fn get_ir_blobs_at_height(
&self,
height: u64,
) -> Result<Vec<InnerBlob>, anyhow::Error> {
) -> Result<Vec<IntermediateBlobRepresentation>, anyhow::Error> {
let blobs = self.default_client.blob_get_all(height, &[self.celestia_namespace]).await;

if let Err(e) = &blobs {
Expand Down Expand Up @@ -186,10 +189,10 @@ where

#[tracing::instrument(target = "movement_timing", level = "debug")]
async fn get_blobs_at_height(&self, height: u64) -> Result<Vec<Blob>, anyhow::Error> {
let inner_blobs = self.get_inner_blobs_at_height(height).await?;
let ir_blobs = self.get_ir_blobs_at_height(height).await?;
let mut blobs = Vec::new();
for inner_blob in inner_blobs {
let blob = Self::inner_blob_to_blob(inner_blob, height)?;
for ir_blob in ir_blobs {
let blob = Self::ir_blob_to_blob(ir_blob, height)?;
// todo: update logging here
blobs.push(blob);
}
Expand Down Expand Up @@ -277,26 +280,29 @@ where
as std::pin::Pin<Box<dyn Stream<Item = Result<Blob, anyhow::Error>> + Send>>)
}

pub fn inner_blob_to_blob(inner_blob: InnerBlob, height: u64) -> Result<Blob, anyhow::Error> {
pub fn ir_blob_to_blob(
ir_blob: IntermediateBlobRepresentation,
height: u64,
) -> Result<Blob, anyhow::Error> {
Ok(Blob {
data: inner_blob.blob().to_vec(),
signature: inner_blob.signature().to_vec(),
timestamp: inner_blob.timestamp(),
signer: inner_blob.signer().to_vec(),
blob_id: inner_blob.id().to_vec(),
data: ir_blob.blob().to_vec(),
signature: ir_blob.signature().to_vec(),
timestamp: ir_blob.timestamp(),
signer: ir_blob.signer().to_vec(),
blob_id: ir_blob.id().to_vec(),
height,
})
}

pub fn celestia_blob_to_blob(blob: CelestiaBlob, height: u64) -> Result<Blob, anyhow::Error> {
let inner_blob: InnerBlob = blob.try_into()?;
let ir_blob: IntermediateBlobRepresentation = blob.try_into()?;

Ok(Blob {
data: inner_blob.blob().to_vec(),
signature: inner_blob.signature().to_vec(),
timestamp: inner_blob.timestamp(),
signer: inner_blob.signer().to_vec(),
blob_id: inner_blob.id().to_vec(),
data: ir_blob.blob().to_vec(),
signature: ir_blob.signature().to_vec(),
timestamp: ir_blob.timestamp(),
signer: ir_blob.signer().to_vec(),
blob_id: ir_blob.id().to_vec(),
height,
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,38 +95,38 @@ impl InnerSignedBlobV1 {
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum InnerBlob {
pub enum IntermediateBlobRepresentation {
SignedV1(InnerSignedBlobV1),
}

impl From<InnerSignedBlobV1> for InnerBlob {
impl From<InnerSignedBlobV1> for IntermediateBlobRepresentation {
fn from(inner: InnerSignedBlobV1) -> Self {
InnerBlob::SignedV1(inner)
IntermediateBlobRepresentation::SignedV1(inner)
}
}

impl InnerBlob {
impl IntermediateBlobRepresentation {
pub fn blob(&self) -> &[u8] {
match self {
InnerBlob::SignedV1(inner) => inner.data.blob.as_slice(),
IntermediateBlobRepresentation::SignedV1(inner) => inner.data.blob.as_slice(),
}
}

pub fn signature(&self) -> &[u8] {
match self {
InnerBlob::SignedV1(inner) => inner.signature.as_slice(),
IntermediateBlobRepresentation::SignedV1(inner) => inner.signature.as_slice(),
}
}

pub fn timestamp(&self) -> u64 {
match self {
InnerBlob::SignedV1(inner) => inner.data.timestamp,
IntermediateBlobRepresentation::SignedV1(inner) => inner.data.timestamp,
}
}

pub fn signer(&self) -> &[u8] {
match self {
InnerBlob::SignedV1(inner) => inner.signer.as_slice(),
IntermediateBlobRepresentation::SignedV1(inner) => inner.signer.as_slice(),
}
}

Expand All @@ -136,7 +136,7 @@ impl InnerBlob {

pub fn id(&self) -> &[u8] {
match self {
InnerBlob::SignedV1(inner) => inner.id.as_slice(),
IntermediateBlobRepresentation::SignedV1(inner) => inner.id.as_slice(),
}
}

Expand All @@ -149,19 +149,19 @@ impl InnerBlob {
FieldBytesSize<C>: ModulusSize,
{
match self {
InnerBlob::SignedV1(inner) => inner.try_verify::<C>(),
IntermediateBlobRepresentation::SignedV1(inner) => inner.try_verify::<C>(),
}
}
}

pub mod celestia {

use super::InnerBlob;
use super::IntermediateBlobRepresentation;
use anyhow::Context;
use celestia_types::{nmt::Namespace, Blob as CelestiaBlob};
use tracing::info;

impl TryFrom<CelestiaBlob> for InnerBlob {
impl TryFrom<CelestiaBlob> for IntermediateBlobRepresentation {
type Error = anyhow::Error;

// todo: it would be nice to have this be self describing over the compression and serialization format
Expand All @@ -178,20 +178,23 @@ pub mod celestia {
}
}

pub struct CelestiaInnerBlob(pub InnerBlob, pub Namespace);
pub struct CelestiaIntermediateBlobRepresentation(
pub IntermediateBlobRepresentation,
pub Namespace,
);

/// Tries to form a CelestiaBlob from a CelestiaInnerBlob
impl TryFrom<CelestiaInnerBlob> for CelestiaBlob {
/// Tries to form a CelestiaBlob from a CelestiaIntermediateBlobRepresentation
impl TryFrom<CelestiaIntermediateBlobRepresentation> for CelestiaBlob {
type Error = anyhow::Error;

fn try_from(inner_blob: CelestiaInnerBlob) -> Result<Self, Self::Error> {
info!("converting CelestiaInnerBlob to CelestiaBlob");
fn try_from(ir_blob: CelestiaIntermediateBlobRepresentation) -> Result<Self, Self::Error> {
info!("converting CelestiaIntermediateBlobRepresentation to CelestiaBlob");

// Extract the inner blob and namespace
let CelestiaInnerBlob(inner_blob, namespace) = inner_blob;
let CelestiaIntermediateBlobRepresentation(ir_blob, namespace) = ir_blob;

// Serialize the inner blob with bcs
let serialized_blob = bcs::to_bytes(&inner_blob).context("failed to serialize blob")?;
let serialized_blob = bcs::to_bytes(&ir_blob).context("failed to serialize blob")?;

// Compress the serialized data with zstd
let compressed_blob = zstd::encode_all(serialized_blob.as_slice(), 0)
Expand Down
2 changes: 1 addition & 1 deletion protocol-units/da/m1/util/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod config;
pub use config::*;
pub mod inner_blob;
pub mod ir_blob;
Loading