浏览代码

WIP: Working on a simpler Proto

Cesar Rodas 1 周之前
父节点
当前提交
45e33578ec

+ 2 - 2
crates/cdk-integration-tests/tests/mint.rs

@@ -58,8 +58,8 @@ async fn test_correct_keyset() -> Result<()> {
     let quote_ttl = QuoteTTL::new(10000, 10000);
     localstore.set_quote_ttl(quote_ttl).await?;
 
-    mint.rotate_next_keyset(CurrencyUnit::Sat, 32, 0).await?;
-    mint.rotate_next_keyset(CurrencyUnit::Sat, 32, 0).await?;
+    mint.rotate_keyset(CurrencyUnit::Sat, 32, 0).await?;
+    mint.rotate_keyset(CurrencyUnit::Sat, 32, 0).await?;
 
     let active = mint.get_active_keysets().await?;
 

+ 1 - 1
crates/cdk-mint-rpc/src/proto/server.rs

@@ -669,7 +669,7 @@ impl CdkMint for MintRPCServer {
 
         let keyset_info = self
             .mint
-            .rotate_next_keyset(
+            .rotate_keyset(
                 unit,
                 request.max_order.map(|a| a as u8).unwrap_or(32),
                 request.input_fee_ppk.unwrap_or(0),

+ 88 - 69
crates/cdk-signatory/proto/signatory.proto

@@ -3,58 +3,85 @@ syntax = "proto3";
 package signatory;
 
 service Signatory {
-    rpc BlindSign(BlindedMessage) returns (BlindSignature);
-
-    rpc VerifyProof(Proof) returns (Empty);
-
-    rpc AuthKeysets(Empty) returns (VecSignatoryKeySet);
+    /// Sign messages
+    rpc BlindSign (BlindedMessages) returns (BlindSignResponse);
+    /// VerifyProofs
+    rpc VerifyProofs (Proofs) returns (BooleanResponse);
+    /// Returns all the keysets for the mint, active and non actives.
+    /// This requests will include keysets for all CurrencyUnit, Auth.
+    rpc Keysets (EmptyRequest) returns (KeysResponse);
+    /// Rotates the keyset for the mint
+    rpc RotateKeyset (RotationRequest) returns (KeyRotationResponse);
+}
+
+message BlindSignResponse {
+    oneof result {
+        BlindSignatures sigs  = 1;
+        Error error = 2;
+    }
+}
 
-    rpc Keysets(Empty) returns (VecSignatoryKeySet);
+message BlindedMessages {
+    repeated BlindedMessage blinded_messages = 1;
+}
 
-    rpc RotateKeyset(RotateKeyArguments) returns (MintKeySetInfo);
+// Represents a blinded message
+message BlindedMessage {
+    uint64 amount = 1;
+    string keyset_id = 2;
+    bytes blinded_secret = 3;
 }
 
-message Empty {}
+message BooleanResponse {
+    oneof result {
+        bool success  = 1;
+        Error error = 2;
+    }
+}
 
-message VecSignatoryKeySet {
-    repeated SignatoryKeySet keysets = 1;
+message KeyRotationResponse {
+    oneof result {
+        KeySet keyset  = 1;
+        Error error = 2;
+    }
+}
 
-    optional bool is_none = 2;
+message KeysResponse {
+    oneof result {
+        SignatoryKeysets keysets = 1;
+        Error error = 2;
+    }
 }
 
-message SignatoryKeySet {
-    KeySet key = 1;
-    MintKeySetInfo info = 2;
+message SignatoryKeysets {
+    bytes pubkey = 1;
+    repeated KeySet keysets = 2;
 }
 
 message KeySet {
-    Id id = 1;
+    string id = 1;
     CurrencyUnit unit = 2;
-    Keys keys = 3;
+    bool active = 3;
+    uint64 input_fee_ppk = 4;
+    Keys keys = 5;
 }
 
 message Keys {
     map<uint64, bytes> keys = 1;
 }
 
-
-message RotateKeyArguments {
-    CurrencyUnit unit = 1;
-    optional uint32 derivation_path_index = 2;
+message RotationRequest {
+    CurrencyUnit unit  = 1;
+    uint32 input_fee_ppk  = 2;
     uint32 max_order = 3;
-    uint64 input_fee_ppk = 4;
-}
-
-message CustomDerivationPath {
-    CurrencyUnit unit = 1;
-    repeated DerivationPath derivation_path = 2;
 }
 
 enum CurrencyUnitType {
-  SAT = 0;
-  MSAT = 1;
-  USD = 2;
-  EUR = 3;
+    SAT = 0;
+    MSAT = 1;
+    USD = 2;
+    EUR = 3;
+    AUTH = 4;
 }
 
 message CurrencyUnit {
@@ -64,13 +91,16 @@ message CurrencyUnit {
     }
 }
 
+message Proofs {
+    repeated Proof proof = 1;
+}
+
 message Proof {
     uint64 amount = 1;
     string keyset_id = 2;
-    string secret = 3;
+    bytes secret = 3;
     bytes C = 4;
     optional Witness witness = 5;
-    optional ProofDLEQ dleq = 6;
 }
 
 message ProofDLEQ {
@@ -79,6 +109,16 @@ message ProofDLEQ {
     bytes r = 3;
 }
 
+message SigningResponse {
+    oneof result {
+        BlindSignatures blind_signatures = 1;
+        Error error = 2;
+    }
+}
+message BlindSignatures {
+    repeated BlindSignature blind_signatures = 1;
+}
+
 message BlindSignature {
     uint64 amount = 1;
     string keyset_id = 2;
@@ -91,13 +131,6 @@ message BlindSignatureDLEQ {
     bytes s = 2;
 }
 
-message KeySetInfo {
-    Id id = 1;
-    CurrencyUnit unit = 2;
-    bool active = 3;
-    uint64 input_fee_ppk = 4;
-}
-
 // Witness type
 message Witness {
     oneof witness_type {
@@ -116,42 +149,28 @@ message P2PKWitness {
 message HTLCWitness {
     // Preimage
     string preimage = 1;
-
     // List of signatures
     repeated string signatures = 2;
 }
 
-message BlindedMessage {
-    uint64 amount = 1;
-    string keyset_id = 2;
-    bytes blinded_secret = 3;
-    optional Witness witness = 4; // This field is optional by default in proto3
-}
 
-message KeysResponse {
-    repeated KeySet keysets = 1;
+enum ErrorCode {
+    UNKNOWN = 0;
+    AMOUNT_OUTSIDE_LIMIT = 1;
+    DUPLICATE_INPUTS_PROVIDED = 2;
+    DUPLICATE_OUTPUTS_PROVIDED = 3;
+    KEYSET_NOT_KNOWN = 4;
+    KEYSET_INACTIVE = 5;
+    MINTING_DISABLED = 6;
+    COULD_NOT_ROTATE_KEYSET = 7;
+    INVALID_PROOF = 8;
+    INVALID_BLIND_MESSAGE = 9;
+    UNIT_NOT_SUPPORTED = 10;
 }
 
-
-message Id {
-    bytes inner = 1;
+message Error {
+  ErrorCode code = 1;
+  string detail = 2;
 }
 
-message DerivationPath {
-    oneof child_number {
-        uint32 normal = 1;
-        uint32 hardened = 2;
-    }
-}
-
-message MintKeySetInfo {
-    Id id = 1;
-    CurrencyUnit unit = 2;
-    bool active = 3;
-    uint64 valid_from = 4;
-    optional uint64 valid_to = 5;
-    repeated DerivationPath derivation_path = 6;
-    optional uint32 derivation_path_index = 7;
-    uint32 max_order = 8;
-    uint64 input_fee_ppk = 9;
-}
+message EmptyRequest {}

+ 53 - 64
crates/cdk-signatory/src/db_signatory.rs

@@ -169,61 +169,54 @@ impl DbSignatory {
 
 #[async_trait::async_trait]
 impl Signatory for DbSignatory {
-    async fn blind_sign(&self, blinded_message: BlindedMessage) -> Result<BlindSignature, Error> {
-        let BlindedMessage {
-            amount,
-            blinded_secret,
-            keyset_id,
-            ..
-        } = blinded_message;
-
+    async fn blind_sign(
+        &self,
+        blinded_messages: Vec<BlindedMessage>,
+    ) -> Result<Vec<BlindSignature>, Error> {
         let keysets = self.keysets.read().await;
-        let (info, key) = keysets.get(&keyset_id).ok_or(Error::UnknownKeySet)?;
-        if !info.active {
-            return Err(Error::InactiveKeyset);
-        }
+        blinded_messages
+            .into_iter()
+            .map(|blinded_message| {
+                let BlindedMessage {
+                    amount,
+                    blinded_secret,
+                    keyset_id,
+                    ..
+                } = blinded_message;
+
+                let (info, key) = keysets.get(&keyset_id).ok_or(Error::UnknownKeySet)?;
+                if !info.active {
+                    return Err(Error::InactiveKeyset);
+                }
 
-        let key_pair = key.keys.get(&amount).ok_or(Error::UnknownKeySet)?;
-        let c = sign_message(&key_pair.secret_key, &blinded_secret)?;
+                let key_pair = key.keys.get(&amount).ok_or(Error::UnknownKeySet)?;
+                let c = sign_message(&key_pair.secret_key, &blinded_secret)?;
 
-        let blinded_signature = BlindSignature::new(
-            amount,
-            c,
-            keyset_id,
-            &blinded_message.blinded_secret,
-            key_pair.secret_key.clone(),
-        )?;
+                let blinded_signature = BlindSignature::new(
+                    amount,
+                    c,
+                    keyset_id,
+                    &blinded_message.blinded_secret,
+                    key_pair.secret_key.clone(),
+                )?;
 
-        Ok(blinded_signature)
+                Ok(blinded_signature)
+            })
+            .collect()
     }
 
-    async fn verify_proof(&self, proof: Proof) -> Result<(), Error> {
+    async fn verify_proofs(&self, proofs: Vec<Proof>) -> Result<(), Error> {
         let keysets = self.keysets.read().await;
-        let (_, key) = keysets.get(&proof.keyset_id).ok_or(Error::UnknownKeySet)?;
-        let key_pair = key.keys.get(&proof.amount).ok_or(Error::UnknownKeySet)?;
-        verify_message(&key_pair.secret_key, proof.c, proof.secret.as_bytes())?;
-
-        Ok(())
-    }
-
-    async fn auth_keysets(&self) -> Result<Option<Vec<SignatoryKeySet>>, Error> {
-        let keyset_id = self
-            .active_keysets
-            .read()
-            .await
-            .get(&CurrencyUnit::Auth)
-            .cloned()
-            .ok_or(Error::NoActiveKeyset)?;
 
-        let active_keyset = self
-            .keysets
-            .read()
-            .await
-            .get(&keyset_id)
-            .ok_or(Error::UnknownKeySet)?
-            .into();
-
-        Ok(Some(vec![active_keyset]))
+        proofs
+            .into_iter()
+            .map(|proof| {
+                let (_, key) = keysets.get(&proof.keyset_id).ok_or(Error::UnknownKeySet)?;
+                let key_pair = key.keys.get(&proof.amount).ok_or(Error::UnknownKeySet)?;
+                verify_message(&key_pair.secret_key, proof.c, proof.secret.as_bytes())?;
+                Ok(())
+            })
+            .collect()
     }
 
     async fn keysets(&self) -> Result<Vec<SignatoryKeySet>, Error> {
@@ -240,23 +233,19 @@ impl Signatory for DbSignatory {
     /// Generate new keyset
     #[tracing::instrument(skip(self))]
     async fn rotate_keyset(&self, args: RotateKeyArguments) -> Result<MintKeySetInfo, Error> {
-        let path_index = if let Some(path_index) = args.derivation_path_index {
-            path_index
-        } else {
-            let current_keyset_id = self
-                .localstore
-                .get_active_keyset_id(&args.unit)
-                .await?
-                .ok_or(Error::UnsupportedUnit)?;
-
-            let keyset_info = self
-                .localstore
-                .get_keyset_info(&current_keyset_id)
-                .await?
-                .ok_or(Error::UnknownKeySet)?;
-
-            keyset_info.derivation_path_index.unwrap_or(1) + 1
-        };
+        let current_keyset_id = self
+            .localstore
+            .get_active_keyset_id(&args.unit)
+            .await?
+            .ok_or(Error::UnsupportedUnit)?;
+
+        let keyset_info = self
+            .localstore
+            .get_keyset_info(&current_keyset_id)
+            .await?
+            .ok_or(Error::UnknownKeySet)?;
+
+        let path_index = keyset_info.derivation_path_index.unwrap_or(1) + 1;
 
         let derivation_path = match self.custom_paths.get(&args.unit) {
             Some(path) => path.clone(),

+ 4 - 26
crates/cdk-signatory/src/proto/client.rs

@@ -21,7 +21,7 @@ impl SignatoryRpcClient {
 
 #[async_trait::async_trait]
 impl Signatory for SignatoryRpcClient {
-    async fn blind_sign(&self, request: BlindedMessage) -> Result<BlindSignature, Error> {
+    async fn blind_sign(&self, request: Vec<BlindedMessage>) -> Result<Vec<BlindSignature>, Error> {
         let req: super::BlindedMessage = request.into();
         self.client
             .clone()
@@ -31,42 +31,20 @@ impl Signatory for SignatoryRpcClient {
             .map_err(|e| Error::Custom(e.to_string()))?
     }
 
-    async fn verify_proof(&self, proof: Proof) -> Result<(), Error> {
+    async fn verify_proofs(&self, proof: Vec<Proof>) -> Result<(), Error> {
         let req: super::Proof = proof.into();
         self.client
             .clone()
-            .verify_proof(req)
+            .verify_proofs(req)
             .await
             .map(|response| response.into_inner().try_into())
             .map_err(|e| Error::Custom(e.to_string()))?
     }
 
-    async fn auth_keysets(&self) -> Result<Option<Vec<SignatoryKeySet>>, Error> {
-        self.client
-            .clone()
-            .auth_keysets(super::Empty {})
-            .await
-            .map(|response| {
-                let response = response.into_inner();
-
-                if response.is_none == Some(true) {
-                    Ok(None)
-                } else {
-                    response
-                        .keysets
-                        .into_iter()
-                        .map(|x| x.try_into())
-                        .collect::<Result<Vec<SignatoryKeySet>, _>>()
-                        .map(Some)
-                }
-            })
-            .map_err(|e| Error::Custom(e.to_string()))?
-    }
-
     async fn keysets(&self) -> Result<Vec<SignatoryKeySet>, Error> {
         self.client
             .clone()
-            .keysets(super::Empty {})
+            .keysets(super::EmptyRequest {})
             .await
             .map(|response| {
                 response

+ 8 - 30
crates/cdk-signatory/src/proto/server.rs

@@ -20,8 +20,8 @@ where
 {
     async fn blind_sign(
         &self,
-        request: Request<proto::BlindedMessage>,
-    ) -> Result<Response<proto::BlindSignature>, Status> {
+        request: Request<proto::BlindedMessages>,
+    ) -> Result<Response<proto::BlindSignatures>, Status> {
         let blind_signature = self
             .inner
             .blind_sign(request.into_inner().try_into()?)
@@ -30,42 +30,20 @@ where
         Ok(Response::new(blind_signature.into()))
     }
 
-    async fn verify_proof(
+    async fn verify_proofs(
         &self,
-        request: Request<proto::Proof>,
-    ) -> Result<Response<proto::Empty>, Status> {
+        request: Request<proto::Proofs>,
+    ) -> Result<Response<proto::BooleanResponse>, Status> {
         self.inner
-            .verify_proof(request.into_inner().try_into()?)
+            .verify_proofs(request.into_inner().try_into()?)
             .await
             .map_err(|e| Status::from_error(Box::new(e)))?;
-        Ok(Response::new(proto::Empty {}))
-    }
-
-    async fn auth_keysets(
-        &self,
-        _request: Request<proto::Empty>,
-    ) -> Result<Response<proto::VecSignatoryKeySet>, Status> {
-        let keys_response = self
-            .inner
-            .auth_keysets()
-            .await
-            .map_err(|e| Status::from_error(Box::new(e)))?;
-        Ok(Response::new(if let Some(keys_response) = keys_response {
-            proto::VecSignatoryKeySet {
-                keysets: keys_response.into_iter().map(|k| k.into()).collect(),
-                is_none: Some(false),
-            }
-        } else {
-            proto::VecSignatoryKeySet {
-                keysets: vec![],
-                is_none: Some(true),
-            }
-        }))
+        Ok(Response::new(proto::BooleanResponse {}))
     }
 
     async fn keysets(
         &self,
-        _request: Request<proto::Empty>,
+        _request: Request<proto::EmptyRequest>,
     ) -> Result<Response<proto::VecSignatoryKeySet>, Status> {
         let keys_response = self
             .inner

+ 11 - 25
crates/cdk-signatory/src/service.rs

@@ -11,12 +11,11 @@ use crate::signatory::{RotateKeyArguments, Signatory, SignatoryKeySet};
 enum Request {
     BlindSign(
         (
-            BlindedMessage,
-            oneshot::Sender<Result<BlindSignature, Error>>,
+            Vec<BlindedMessage>,
+            oneshot::Sender<Result<Vec<BlindSignature>, Error>>,
         ),
     ),
-    VerifyProof((Proof, oneshot::Sender<Result<(), Error>>)),
-    AuthKeysets(oneshot::Sender<Result<Option<Vec<SignatoryKeySet>>, Error>>),
+    VerifyProofs((Vec<Proof>, oneshot::Sender<Result<(), Error>>)),
     Keysets(oneshot::Sender<Result<Vec<SignatoryKeySet>, Error>>),
     RotateKeyset(
         (
@@ -67,14 +66,8 @@ impl Service {
                         tracing::error!("Error sending response: {:?}", err);
                     }
                 }
-                Request::VerifyProof((proof, response)) => {
-                    let output = handler.verify_proof(proof).await;
-                    if let Err(err) = response.send(output) {
-                        tracing::error!("Error sending response: {:?}", err);
-                    }
-                }
-                Request::AuthKeysets(response) => {
-                    let output = handler.auth_keysets().await;
+                Request::VerifyProofs((proof, response)) => {
+                    let output = handler.verify_proofs(proof).await;
                     if let Err(err) = response.send(output) {
                         tracing::error!("Error sending response: {:?}", err);
                     }
@@ -98,7 +91,10 @@ impl Service {
 
 #[async_trait::async_trait]
 impl Signatory for Service {
-    async fn blind_sign(&self, blinded_message: BlindedMessage) -> Result<BlindSignature, Error> {
+    async fn blind_sign(
+        &self,
+        blinded_message: Vec<BlindedMessage>,
+    ) -> Result<Vec<BlindSignature>, Error> {
         let (tx, rx) = oneshot::channel();
         self.pipeline
             .send(Request::BlindSign((blinded_message, tx)))
@@ -108,20 +104,10 @@ impl Signatory for Service {
         rx.await.map_err(|e| Error::RecvError(e.to_string()))?
     }
 
-    async fn verify_proof(&self, proof: Proof) -> Result<(), Error> {
-        let (tx, rx) = oneshot::channel();
-        self.pipeline
-            .send(Request::VerifyProof((proof, tx)))
-            .await
-            .map_err(|e| Error::SendError(e.to_string()))?;
-
-        rx.await.map_err(|e| Error::RecvError(e.to_string()))?
-    }
-
-    async fn auth_keysets(&self) -> Result<Option<Vec<SignatoryKeySet>>, Error> {
+    async fn verify_proofs(&self, proof: Vec<Proof>) -> Result<(), Error> {
         let (tx, rx) = oneshot::channel();
         self.pipeline
-            .send(Request::AuthKeysets(tx))
+            .send(Request::VerifyProofs((proof, tx)))
             .await
             .map_err(|e| Error::SendError(e.to_string()))?;
 

+ 5 - 6
crates/cdk-signatory/src/signatory.rs

@@ -37,7 +37,6 @@ impl From<CurrencyUnit> for KeysetIdentifier {
 #[derive(Debug, Clone)]
 pub struct RotateKeyArguments {
     pub unit: CurrencyUnit,
-    pub derivation_path_index: Option<u32>,
     pub max_order: u8,
     pub input_fee_ppk: u64,
 }
@@ -66,16 +65,16 @@ impl From<&(MintKeySetInfo, MintKeySet)> for SignatoryKeySet {
 #[async_trait::async_trait]
 /// Signatory trait
 pub trait Signatory {
-    /// Get all the mint keysets for authentication
-    async fn auth_keysets(&self) -> Result<Option<Vec<SignatoryKeySet>>, Error>;
-
     /// Blind sign a message.
     ///
     /// The message can be for a coin or an auth token.
-    async fn blind_sign(&self, blinded_message: BlindedMessage) -> Result<BlindSignature, Error>;
+    async fn blind_sign(
+        &self,
+        blinded_messages: Vec<BlindedMessage>,
+    ) -> Result<Vec<BlindSignature>, Error>;
 
     /// Verify [`Proof`] meets conditions and is signed
-    async fn verify_proof(&self, proofs: Proof) -> Result<(), Error>;
+    async fn verify_proofs(&self, proofs: Vec<Proof>) -> Result<(), Error>;
 
     /// Retrieve the list of all mint keysets
     async fn keysets(&self) -> Result<Vec<SignatoryKeySet>, Error>;

+ 5 - 1
crates/cdk/src/mint/auth/mod.rs

@@ -214,6 +214,10 @@ impl Mint {
         &self,
         blinded_message: &BlindedMessage,
     ) -> Result<BlindSignature, Error> {
-        self.signatory.blind_sign(blinded_message.to_owned()).await
+        self.signatory
+            .blind_sign(vec![blinded_message.to_owned()])
+            .await?
+            .pop()
+            .ok_or(Error::Internal)
     }
 }

+ 1 - 22
crates/cdk/src/mint/keysets/mod.rs

@@ -73,29 +73,9 @@ impl Mint {
             .map(|x| x.key))
     }
 
-    /// Add current keyset to inactive keysets
-    /// Generate new keyset
-    #[instrument(skip(self))]
-    pub async fn rotate_keyset(
-        &self,
-        unit: CurrencyUnit,
-        derivation_path_index: u32,
-        max_order: u8,
-        input_fee_ppk: u64,
-    ) -> Result<MintKeySetInfo, Error> {
-        self.signatory
-            .rotate_keyset(RotateKeyArguments {
-                unit,
-                derivation_path_index: Some(derivation_path_index),
-                max_order,
-                input_fee_ppk,
-            })
-            .await
-    }
-
     /// Rotate to next keyset for unit
     #[instrument(skip(self))]
-    pub async fn rotate_next_keyset(
+    pub async fn rotate_keyset(
         &self,
         unit: CurrencyUnit,
         max_order: u8,
@@ -105,7 +85,6 @@ impl Mint {
             .rotate_keyset(RotateKeyArguments {
                 unit,
                 max_order,
-                derivation_path_index: None,
                 input_fee_ppk,
             })
             .await

+ 6 - 2
crates/cdk/src/mint/mod.rs

@@ -348,7 +348,11 @@ impl Mint {
         &self,
         blinded_message: &BlindedMessage,
     ) -> Result<BlindSignature, Error> {
-        self.signatory.blind_sign(blinded_message.to_owned()).await
+        self.signatory
+            .blind_sign(vec![blinded_message.to_owned()])
+            .await?
+            .pop()
+            .ok_or(Error::Internal)
     }
 
     /// Verify [`Proof`] meets conditions and is signed
@@ -373,7 +377,7 @@ impl Mint {
                 }
             }
         }
-        self.signatory.verify_proof(proof.to_owned()).await
+        self.signatory.verify_proofs(vec![proof.to_owned()]).await
     }
 
     /// Verify melt request is valid