embedded.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //! Run a Signatory in a embedded environment, inside a CDK instance, but this wrapper makes sure to
  2. //! run the Signatory in another thread, isolated form the main CDK, communicating through messages
  3. use std::sync::Arc;
  4. use cashu::{BlindSignature, BlindedMessage, Proof};
  5. use cdk_common::Error;
  6. use tokio::sync::{mpsc, oneshot};
  7. use tokio::task::JoinHandle;
  8. use crate::signatory::{RotateKeyArguments, Signatory, SignatoryKeySet, SignatoryKeysets};
  9. enum Request {
  10. BlindSign(
  11. (
  12. Vec<BlindedMessage>,
  13. oneshot::Sender<Result<Vec<BlindSignature>, Error>>,
  14. ),
  15. ),
  16. VerifyProof((Vec<Proof>, oneshot::Sender<Result<(), Error>>)),
  17. Keysets(oneshot::Sender<Result<SignatoryKeysets, Error>>),
  18. RotateKeyset(
  19. (
  20. RotateKeyArguments,
  21. oneshot::Sender<Result<SignatoryKeySet, Error>>,
  22. ),
  23. ),
  24. }
  25. /// Creates a service-like to wrap an implementation of the Signatory
  26. ///
  27. /// This implements the actor model, ensuring the Signatory and their private key is moved from the
  28. /// main thread to their own tokio task, and communicates with the main program by passing messages,
  29. /// an extra layer of security to move the keys to another layer.
  30. pub struct Service {
  31. pipeline: mpsc::Sender<Request>,
  32. runner: Option<JoinHandle<()>>,
  33. }
  34. impl Drop for Service {
  35. fn drop(&mut self) {
  36. if let Some(runner) = self.runner.take() {
  37. runner.abort();
  38. }
  39. }
  40. }
  41. impl Service {
  42. pub fn new(handler: Arc<dyn Signatory + Send + Sync>) -> Self {
  43. let (tx, rx) = mpsc::channel(10_000);
  44. let runner = Some(tokio::spawn(Self::runner(rx, handler)));
  45. Self {
  46. pipeline: tx,
  47. runner,
  48. }
  49. }
  50. async fn runner(
  51. mut receiver: mpsc::Receiver<Request>,
  52. handler: Arc<dyn Signatory + Send + Sync>,
  53. ) {
  54. while let Some(request) = receiver.recv().await {
  55. match request {
  56. Request::BlindSign((blinded_message, response)) => {
  57. let output = handler.blind_sign(blinded_message).await;
  58. if let Err(err) = response.send(output) {
  59. tracing::error!("Error sending response: {:?}", err);
  60. }
  61. }
  62. Request::VerifyProof((proof, response)) => {
  63. let output = handler.verify_proofs(proof).await;
  64. if let Err(err) = response.send(output) {
  65. tracing::error!("Error sending response: {:?}", err);
  66. }
  67. }
  68. Request::Keysets(response) => {
  69. let output = handler.keysets().await;
  70. if let Err(err) = response.send(output) {
  71. tracing::error!("Error sending response: {:?}", err);
  72. }
  73. }
  74. Request::RotateKeyset((args, response)) => {
  75. let output = handler.rotate_keyset(args).await;
  76. if let Err(err) = response.send(output) {
  77. tracing::error!("Error sending response: {:?}", err);
  78. }
  79. }
  80. }
  81. }
  82. }
  83. }
  84. #[async_trait::async_trait]
  85. impl Signatory for Service {
  86. async fn blind_sign(
  87. &self,
  88. blinded_messages: Vec<BlindedMessage>,
  89. ) -> Result<Vec<BlindSignature>, Error> {
  90. let (tx, rx) = oneshot::channel();
  91. self.pipeline
  92. .send(Request::BlindSign((blinded_messages, tx)))
  93. .await
  94. .map_err(|e| Error::SendError(e.to_string()))?;
  95. rx.await.map_err(|e| Error::RecvError(e.to_string()))?
  96. }
  97. async fn verify_proofs(&self, proofs: Vec<Proof>) -> Result<(), Error> {
  98. let (tx, rx) = oneshot::channel();
  99. self.pipeline
  100. .send(Request::VerifyProof((proofs, tx)))
  101. .await
  102. .map_err(|e| Error::SendError(e.to_string()))?;
  103. rx.await.map_err(|e| Error::RecvError(e.to_string()))?
  104. }
  105. async fn keysets(&self) -> Result<SignatoryKeysets, Error> {
  106. let (tx, rx) = oneshot::channel();
  107. self.pipeline
  108. .send(Request::Keysets(tx))
  109. .await
  110. .map_err(|e| Error::SendError(e.to_string()))?;
  111. rx.await.map_err(|e| Error::RecvError(e.to_string()))?
  112. }
  113. async fn rotate_keyset(&self, args: RotateKeyArguments) -> Result<SignatoryKeySet, Error> {
  114. let (tx, rx) = oneshot::channel();
  115. self.pipeline
  116. .send(Request::RotateKeyset((args, tx)))
  117. .await
  118. .map_err(|e| Error::SendError(e.to_string()))?;
  119. rx.await.map_err(|e| Error::RecvError(e.to_string()))?
  120. }
  121. }