diff --git a/Cargo.toml b/Cargo.toml index cc5aba0..034a833 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,10 @@ members = [ "crates/bs", "crates/bs-p2p", "crates/bs-traits", + "crates/comrade", + "crates/comrade-component", + "crates/comrade-reference", + "crates/bs-p2p", "crates/content-addressable", "crates/multibase", "crates/multicid", @@ -32,13 +36,15 @@ license = "FSL-1.1 OR Apache-2.0" unexpected_cfgs = { level = "warn", check-cfg = [ 'cfg(feature, values("cargo-clippy"))', 'cfg(fuzzing)', -]} +] } [workspace.dependencies] # Crate ependencies bs = { path = "crates/bs" } bs-p2p = { path = "crates/bs-p2p" } bs-traits = { path = "crates/bs-traits" } +comrade = { path = "crates/comrade" } +comrade-reference = { path = "crates/comrade-reference" } multibase = { path = "crates/multibase" } multicid = { path = "crates/multicid" } multicodec = { path = "crates/multicodec" } @@ -60,14 +66,23 @@ rand = { version = "0.9.0", features = ["os_rng"] } rand_core = "0.9.3" rand_6 = { version = "0.6.4", package = "rand" } rand_core_6 = { version = "0.6.4", package = "rand_core" } -serde = { version = "1.0.219", default-features = false, features = ["alloc", "derive"]} -serde_cbor = { version = "0.11.2", features = ["tags"]} -serde_json = { version = "1.0.104"} -serde_test = { version = "1.0.104"} +serde = { version = "1.0.219", default-features = false, features = [ + "alloc", + "derive", +] } +serde_cbor = { version = "0.11.2", features = ["tags"] } +serde_json = { version = "1.0.104" } +serde_test = { version = "1.0.104" } sha3 = "0.10.8" test-log = { version = "0.2.17", features = ["trace", "color"] } thiserror = "2.0.12" -tokio = { version = "1.44.2", features = ["fs", "io-util", "macros", "rt", "test-util"] } +tokio = { version = "1.44.2", features = [ + "fs", + "io-util", + "macros", + "rt", + "test-util", +] } tracing = "0.1.41" tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } unsigned-varint = { version = "0.8.0", features = ["std"] } diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 8db8101..07fa020 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -20,6 +20,7 @@ anyhow = "1.0" async-trait = "0.1" best-practices.workspace = true bs.workspace = true +bs-traits.workspace = true clap = { version = "4.5.36", features = ["cargo"] } colored = "3.0.0" csv = "1.3.1" @@ -42,7 +43,7 @@ rustyline = { version = "15.0.0", features = ["derive"] } serde = { workspace = true, optional = true } serde_cbor.workspace = true serde_json.workspace = true -ssh-key = { version = "0.6.2", features = ["crypto", "ed25519"]} +ssh-key = { version = "0.6.2", features = ["crypto", "ed25519"] } ssh-agent-client-rs = "1.0.0" structopt = "0.3.26" thiserror.workspace = true @@ -50,7 +51,7 @@ tokio = { version = "1.44.2", features = ["full"] } toml = "0.8.20" tracing.workspace = true tracing-subscriber.workspace = true -wacc.workspace = true +comrade.workspace = true [dev-dependencies] tokio-test = "0.4.4" diff --git a/cli/src/error.rs b/cli/src/error.rs index 18783df..e809ad4 100644 --- a/cli/src/error.rs +++ b/cli/src/error.rs @@ -29,6 +29,15 @@ pub enum Error { /// Bs errors #[error(transparent)] Bs(#[from] bs::Error), + + /// Error opening a provenance log + #[error(transparent)] + Open(#[from] bs::error::OpenError), + + /// Error updating a provenance log + #[error(transparent)] + Update(#[from] bs::error::UpdateError), + /// Multicid error #[error(transparent)] Multicid(#[from] multicid::Error), diff --git a/cli/src/subcmds/plog.rs b/cli/src/subcmds/plog.rs index 486618a..fe167e3 100644 --- a/cli/src/subcmds/plog.rs +++ b/cli/src/subcmds/plog.rs @@ -2,6 +2,7 @@ /// Plog command pub mod command; +use bs_traits::{GetKey, Signer, SyncGetKey, SyncSigner}; pub use command::Command; use crate::{error::PlogError, Config, Error}; @@ -11,6 +12,7 @@ use bs::{ ops::{open, update}, update::OpParams, }; +use comrade::Pairs; use multibase::Base; use multicid::{Cid, EncodedCid, EncodedVlad, Vlad}; use multicodec::Codec; @@ -22,7 +24,54 @@ use provenance_log::{Key, Log, Script}; use rng::StdRng; use std::{collections::VecDeque, convert::TryFrom, path::PathBuf}; use tracing::debug; -use wacc::Pairs; + +/// Cli KeyManager +struct KeyManager; + +impl GetKey for KeyManager { + type Key = Multikey; + + type KeyPath = Key; + + type Codec = Codec; + + type Error = Error; +} + +impl SyncGetKey for KeyManager { + fn get_key( + &self, + key_path: &Self::KeyPath, + codec: &Self::Codec, + threshold: usize, + limit: usize, + ) -> Result { + debug!("Generating {} key ({} of {})...", codec, threshold, limit); + let mut rng = StdRng::from_os_rng(); + let mk = mk::Builder::new_from_random_bytes(*codec, &mut rng)?.try_build()?; + let fingerprint = mk.fingerprint_view()?.fingerprint(Codec::Blake3)?; + + let ef = EncodedMultihash::new(Base::Base32Z, fingerprint); + debug!("Writing {} key fingerprint: {}", key_path, ef); + let w = writer(&Some(format!("{}.multikey", ef).into()))?; + serde_cbor::to_writer(w, &mk)?; + Ok(mk) + } +} + +impl Signer for KeyManager { + type Key = Multikey; + + type Signature = Multisig; + + type Error = Error; +} + +impl SyncSigner for KeyManager { + fn try_sign(&self, key: &Self::Key, data: &[u8]) -> Result { + Ok(key.sign_view()?.sign(data, false, None)?) + } +} /// processes plog subcommands pub async fn go(cmd: Command, _config: &Config) -> Result<(), Error> { @@ -49,29 +98,10 @@ pub async fn go(cmd: Command, _config: &Config) -> Result<(), Error> { .with_entry_lock_script(&lock_script_path) .with_entry_unlock_script(&unlock_script_path); + let key_manager = KeyManager; + // open the p.log - let plog = open::open_plog( - cfg, - |key: &Key, - codec: Codec, - threshold: usize, - limit: usize| - -> Result { - debug!("Generating {} key ({} of {})...", codec, threshold, limit); - let mut rng = StdRng::from_os_rng(); - let mk = mk::Builder::new_from_random_bytes(codec, &mut rng)?.try_build()?; - let fingerprint = mk.fingerprint_view()?.fingerprint(Codec::Blake3)?; - let ef = EncodedMultihash::new(Base::Base32Z, fingerprint); - debug!("Writing {} key fingerprint: {}", key, ef); - let w = writer(&Some(format!("{}.multikey", ef).into()))?; - serde_cbor::to_writer(w, &mk)?; - Ok(mk) - }, - |mk: &Multikey, data: &[u8]| -> Result { - debug!("Signing the first entry"); - Ok(mk.sign_view()?.sign(data, false, None)?) - }, - )?; + let plog = open::open_plog(cfg, &key_manager, &key_manager)?; println!("Created p.log {}", writer_name(&output)?.to_string_lossy()); print_plog(&plog)?; @@ -122,30 +152,10 @@ pub async fn go(cmd: Command, _config: &Config) -> Result<(), Error> { .with_entry_signing_key(&entry_signing_key) .with_entry_unlock_script(&unlock_script_path); + let key_manager = KeyManager; + // update the p.log - update::update_plog( - &mut plog, - cfg, - |key: &Key, - codec: Codec, - threshold: usize, - limit: usize| - -> Result { - debug!("Generating {} key ({} of {})...", codec, threshold, limit); - let mut rng = StdRng::from_os_rng(); - let mk = mk::Builder::new_from_random_bytes(codec, &mut rng)?.try_build()?; - let fingerprint = mk.fingerprint_view()?.fingerprint(Codec::Blake3)?; - let ef = EncodedMultihash::new(Base::Base32Z, fingerprint); - debug!("Writing {} key fingerprint: {}", key, ef); - let w = writer(&Some(format!("{}.multikey", ef).into()))?; - serde_cbor::to_writer(w, &mk)?; - Ok(mk) - }, - |mk: &Multikey, data: &[u8]| -> Result { - debug!("Signing the first entry"); - Ok(mk.sign_view()?.sign(data, false, None)?) - }, - )?; + update::update_plog(&mut plog, cfg, &key_manager, &key_manager)?; println!("Writing p.log {}", writer_name(&output)?.to_string_lossy()); print_plog(&plog)?; @@ -298,17 +308,17 @@ where } */ -fn get_from_wacc_value<'a, T>(value: &'a wacc::Value) -> Option +fn get_from_wacc_value<'a, T>(value: &'a comrade::Value) -> Option where T: TryFrom<&'a [u8]> + EncodingInfo, BaseEncoded: TryFrom<&'a str>, { match value { - wacc::Value::Bin { + comrade::Value::Bin { hint: _, data: ref v, } => T::try_from(v.as_slice()).ok(), - wacc::Value::Str { + comrade::Value::Str { hint: _, data: ref s, } => match BaseEncoded::::try_from(s.as_str()) { diff --git a/crates/bs-traits/Cargo.toml b/crates/bs-traits/Cargo.toml index b13b8aa..66f51fc 100644 --- a/crates/bs-traits/Cargo.toml +++ b/crates/bs-traits/Cargo.toml @@ -8,7 +8,6 @@ readme = "README.md" license = "Functional Source License 1.1" [dependencies] -async-trait = "0.1" thiserror.workspace = true [dev-dependencies] diff --git a/crates/bs-traits/src/async.rs b/crates/bs-traits/src/async.rs index 9dc7211..0323105 100644 --- a/crates/bs-traits/src/async.rs +++ b/crates/bs-traits/src/async.rs @@ -1,107 +1,141 @@ // SPDX-License-Identifier: FSL-1.1 - +//! This module provides traits for asynchronous operations +use crate::cond_send::{CondSend, CondSync}; use crate::*; -use async_trait::*; +use std::future::Future; use std::num::NonZeroUsize; /// Trait for types that can sign data asynchronously -#[async_trait] pub trait AsyncSigner: Signer { /// Attempt to sign the data asynchronously - async fn try_sign_async(&self, key: &Self::Key, data: &[u8]) -> Result; + fn try_sign( + &self, + key: &Self::Key, + data: &[u8], + ) -> impl Future> + CondSend + '_; /// Sign the data asynchronously - async fn sign_async(&self, key: &Self::Key, data: &[u8]) -> Self::Signature { - self.try_sign_async(key, data) - .await - .expect("signing operation failed") + /// + /// # Panics + /// + /// This function will panic if the signing operation fails. + fn sign<'a>( + &'a self, + key: &'a Self::Key, + data: &'a [u8], + ) -> impl Future + CondSend + 'a + where + Self: CondSync, + Self::Key: CondSync, + { + async move { + self.try_sign(key, data) + .await + .expect("signing operation failed") + } } } /// Trait for types that can verify data asynchronously -#[async_trait] pub trait AsyncVerifier: Verifier { /// Verify the data asynchronously - async fn verify_async( + fn verify( &self, key: &Self::Key, data: &[u8], signature: &Self::Signature, - ) -> Result<(), Error>; + ) -> impl Future> + CondSend + '_; } /// Trait for types that can encrypt data asynchronously -#[async_trait] pub trait AsyncEncryptor: Encryptor { /// Attempt to encrypt the data asynchronously - async fn try_encrypt_async( + fn try_encrypt( &self, key: &Self::Key, plaintext: &Self::Plaintext, - ) -> Result; + ) -> impl Future> + CondSend + '_; /// Encrypt the data asynchronously - async fn encrypt_async( - &self, - key: &Self::Key, - plaintext: &Self::Plaintext, - ) -> Self::Ciphertext { - self.try_encrypt_async(key, plaintext) - .await - .expect("encryption operation failed") + /// + /// # Panics + /// + /// This function will panic if the encryption operation fails. + fn encrypt<'a>( + &'a self, + key: &'a Self::Key, + plaintext: &'a Self::Plaintext, + ) -> impl Future + CondSend + 'a + where + Self: CondSync, + Self::Key: CondSync, + Self::Plaintext: CondSync, + { + async move { + self.try_encrypt(key, plaintext) + .await + .expect("encryption operation failed") + } } } /// Trait for types that can decrypt data asynchronously -#[async_trait] pub trait AsyncDecryptor: Decryptor { /// Decrypt the data asynchronously - async fn decrypt_async( + fn decrypt( &self, key: &Self::Key, ciphertext: &Self::Ciphertext, - ) -> Result; + ) -> impl Future> + CondSend + '_; } /// Trait for types that can split a secret into shares asynchronously -#[async_trait] pub trait AsyncSecretSplitter: SecretSplitter { /// Split the secret into shares asynchronously - async fn split_async( + /// + /// Conditions for `split` to succeed: + /// - Threshold must be less than or equal to limit. + /// - Threshold must be greater than or equal to 2. + fn split( &self, secret: &Self::Secret, threshold: NonZeroUsize, limit: NonZeroUsize, - ) -> Result; + ) -> impl Future> + CondSend + '_; /// Split the secret into shares with the given identifiers asynchronously - async fn split_with_identifiers_async( + /// The number of shares will be equal to the number of identifiers i.e. the `limit`. + /// + /// Conditions for `split_with_identifiers` to succeed: + /// - Threshold must be less than or equal to the number of identifiers. + /// - Threshold must be greater than or equal to 2. + /// - Identifiers must be unique. + /// - Identifiers must not be empty. + fn split_with_identifiers( &self, secret: &Self::Secret, threshold: NonZeroUsize, identifiers: &[Self::Identifier], - ) -> Result; + ) -> impl Future> + CondSend + '_; } /// Trait for types that can combine shares into a secret asynchronously -#[async_trait] pub trait AsyncSecretCombiner: SecretCombiner { /// Combine the shares into a secret asynchronously - async fn combine_async( + fn combine( &self, shares: &[(Self::Identifier, Self::Shares)], - ) -> Result; + ) -> impl Future> + CondSend + '_; } /// Trait for types that can get a key asynchronously -#[async_trait] pub trait AsyncGetKey: GetKey { /// Get the key asynchronously - async fn get_key_async( + fn get_key( &self, key_path: &Self::KeyPath, codec: &Self::Codec, threshold: usize, limit: usize, - ) -> Result; + ) -> impl Future> + CondSend + '_; } diff --git a/crates/bs-traits/src/cond_send.rs b/crates/bs-traits/src/cond_send.rs new file mode 100644 index 0000000..df30005 --- /dev/null +++ b/crates/bs-traits/src/cond_send.rs @@ -0,0 +1,33 @@ +//! Utilities for conditionally adding `Send` and `Sync` constraints. + +/// A conditionally compiled trait indirection for `Send` bounds. +/// This target makes it require `Send`. +#[cfg(not(target_arch = "wasm32"))] +pub trait CondSend: Send {} + +/// A conditionally compiled trait indirection for `Send` bounds. +/// This target makes it not require any marker traits. +#[cfg(target_arch = "wasm32")] +pub trait CondSend {} + +#[cfg(not(target_arch = "wasm32"))] +impl CondSend for S where S: Send {} + +#[cfg(target_arch = "wasm32")] +impl CondSend for S {} + +/// A conditionally compiled trait indirection for `Send + Sync` bounds. +/// This target makes it require `Send + Sync`. +#[cfg(not(target_arch = "wasm32"))] +pub trait CondSync: Send + Sync {} + +/// A conditionally compiled trait indirection for `Send + Sync` bounds. +/// This target makes it not require any marker traits. +#[cfg(target_arch = "wasm32")] +pub trait CondSync {} + +#[cfg(not(target_arch = "wasm32"))] +impl CondSync for S where S: Send + Sync {} + +#[cfg(target_arch = "wasm32")] +impl CondSync for S {} diff --git a/crates/bs-traits/src/lib.rs b/crates/bs-traits/src/lib.rs index d74ab8b..c6ef5b3 100644 --- a/crates/bs-traits/src/lib.rs +++ b/crates/bs-traits/src/lib.rs @@ -5,6 +5,7 @@ /// It also provides a `WaitQueue` type that can be used to implement synchronous and asynchronous operations /// without having to use tokio::block_in_place or similar. mod r#async; +mod cond_send; mod error; mod sync; mod wait_queue; @@ -13,3 +14,89 @@ pub use error::Error; pub use r#async::*; pub use sync::*; pub use wait_queue::*; + +use std::fmt::Debug; + +/// Trait for types that can sign data using [AsyncSigner] or [SyncSigner] +pub trait Signer { + /// The type of key used to sign + type Key; + /// The type of signature + type Signature; + /// Any Signing Error + type Error: Debug; +} + +/// Trait for types that can verify signatures using [AsyncVerifier] or [SyncVerifier] +pub trait Verifier { + /// The type of key used to verify + type Key; + /// The type of signature + type Signature; + /// Error type for verification operations + type Error; +} + +/// Trait for types that can encrypt data using [AsyncEncryptor] or [SyncEncryptor] +pub trait Encryptor { + /// The type of key used to encrypt + type Key: Send + Sync; + /// The type of ciphertext + type Ciphertext: Send + Sync; + /// The type of plaintext, might include the nonce, and additional authenticated data + type Plaintext: Send + Sync; + /// Error type for encryption operations + type Error: Debug; +} + +/// Trait for types that can decrypt data using [AsyncDecryptor] or [SyncDecryptor] +pub trait Decryptor { + /// The type of key used to decrypt + type Key: Send + Sync; + /// The type of ciphertext + type Ciphertext: Send + Sync; + /// The type of plaintext + type Plaintext: Send + Sync; + /// Error type for decryption operations + type Error; +} + +/// Trait for types that can split a secret into shares, using [AsyncSecretSplitter] or [SyncSecretSplitter] +pub trait SecretSplitter { + /// The type of secret to split + type Secret: Send + Sync; + /// The type of identifier for the shares + type Identifier: Send + Sync; + /// The output from splitting the secret. + /// Might include the threshold and limit used to split the secret, + /// the shares, and the verifiers, identifiers, + /// or any other information needed to reconstruct the secret + /// and verify the shares. + type Output: Send + Sync; + /// Error type for secret splitting operations + type Error; +} + +/// Trait for types that can combine shares into a secret, using [AsyncSecretCombiner] or [SyncSecretCombiner] +pub trait SecretCombiner { + /// The type of secret to combine + type Secret: Send + Sync; + /// The type of identifier for the shares + type Identifier: Send + Sync; + /// The type of shares to combine + type Shares: Send + Sync; + /// Error type for secret combining operations + type Error; +} + +/// Trait for types that can retrieve a key, using [AsyncGetKey] or [SyncGetKey] +pub trait GetKey { + /// The type of key + type Key; + /// The type of key path + type KeyPath; + /// The type of codec + type Codec; + /// The Error returned + type Error; +} diff --git a/crates/bs-traits/src/sync.rs b/crates/bs-traits/src/sync.rs index d0916f8..ac56561 100644 --- a/crates/bs-traits/src/sync.rs +++ b/crates/bs-traits/src/sync.rs @@ -1,54 +1,42 @@ +//! This module contains traits for synchronous operations. use core::num::NonZeroUsize; -use crate::Error; +use crate::*; /// Trait for types that can sign data -pub trait Signer { - /// The type of key used to sign - type Key: Send + Sync; - /// The type of signature - type Signature: Send + Sync; - +pub trait SyncSigner: Signer { /// Attempt to sign the data - fn try_sign(&self, key: &Self::Key, data: &[u8]) -> Result; + fn try_sign(&self, key: &Self::Key, data: &[u8]) -> Result; /// Sign the data and return the signature + /// + /// # Panics + /// + /// This function will panic if the signing operation fails. fn sign(&self, key: &Self::Key, data: &[u8]) -> Self::Signature { self.try_sign(key, data).expect("signing operation failed") } } /// Trait for types that can verify signatures -pub trait Verifier { - /// The type of key used to verify - type Key: Send + Sync; - /// The type of signature - type Signature: Send + Sync; - +pub trait SyncVerifier: Verifier { /// Verify that the provided signature for the given data is authentic fn verify( &self, key: &Self::Key, data: &[u8], signature: &Self::Signature, - ) -> Result<(), Error>; + ) -> Result<(), Self::Error>; } /// Trait for types that can encrypt data -pub trait Encryptor { - /// The type of key used to encrypt - type Key: Send + Sync; - /// The type of ciphertext - type Ciphertext: Send + Sync; - /// The type of plaintext, might include the nonce, and additional authenticated data - type Plaintext: Send + Sync; - +pub trait SyncEncryptor: Encryptor { /// Attempt to encrypt the plaintext fn try_encrypt( &self, key: &Self::Key, plaintext: &Self::Plaintext, - ) -> Result; + ) -> Result; /// Encrypt the plaintext fn encrypt(&self, key: &Self::Key, plaintext: &Self::Plaintext) -> Self::Ciphertext { @@ -58,35 +46,17 @@ pub trait Encryptor { } /// Trait for types that can decrypt data -pub trait Decryptor { - /// The type of key used to decrypt - type Key: Send + Sync; - /// The type of ciphertext - type Ciphertext: Send + Sync; - /// The type of plaintext - type Plaintext: Send + Sync; - +pub trait SyncDecryptor: Decryptor { /// Attempt to decrypt the ciphertext fn decrypt( &self, key: &Self::Key, ciphertext: &Self::Ciphertext, - ) -> Result; + ) -> Result; } /// Trait for types that can split a secret into shares -pub trait SecretSplitter { - /// The type of secret to split - type Secret: Send + Sync; - /// The type of identifier for the shares - type Identifier: Send + Sync; - /// The output from splitting the secret. - /// Might include the threshold and limit used to split the secret, - /// the shares, and the verifiers, identifiers, - /// or any other information needed to reconstruct the secret - /// and verify the shares. - type Output: Send + Sync; - +pub trait SyncSecretSplitter: SecretSplitter { /// Split the secret into shares. /// /// Conditions for `split` to succeed: @@ -97,7 +67,7 @@ pub trait SecretSplitter { secret: &Self::Secret, threshold: NonZeroUsize, limit: NonZeroUsize, - ) -> Result; + ) -> Result; /// Split the secret into shares with the given identifiers. /// The number of shares will be equal to the number of identifiers i.e. the `limit`. @@ -112,31 +82,20 @@ pub trait SecretSplitter { secret: &Self::Secret, threshold: NonZeroUsize, identifiers: &[Self::Identifier], - ) -> Result; + ) -> Result; } /// Trait for types that can combine shares into a secret -pub trait SecretCombiner { - /// The type of secret to combine - type Secret: Send + Sync; - /// The type of identifier for the shares - type Identifier: Send + Sync; - /// The type of shares to combine - type Shares: Send + Sync; - +pub trait SyncSecretCombiner: SecretCombiner { /// Combine the shares into a secret - fn combine(&self, shares: &[(Self::Identifier, Self::Shares)]) -> Result; + fn combine( + &self, + shares: &[(Self::Identifier, Self::Shares)], + ) -> Result; } /// Trait for types that can retrieve a key -pub trait GetKey { - /// The type of key - type Key: Send + Sync; - /// The type of key path - type KeyPath: Send + Sync; - /// The type of codec - type Codec: Send + Sync; - +pub trait SyncGetKey: GetKey { /// Get the key fn get_key( &self, @@ -144,5 +103,5 @@ pub trait GetKey { codec: &Self::Codec, threshold: usize, limit: usize, - ) -> Result; + ) -> Result; } diff --git a/crates/bs/Cargo.toml b/crates/bs/Cargo.toml index a575852..ee01f8a 100644 --- a/crates/bs/Cargo.toml +++ b/crates/bs/Cargo.toml @@ -17,10 +17,8 @@ multikey.workspace = true multisig.workspace = true provenance-log.workspace = true rand.workspace = true -serde_cbor.workspace = true thiserror.workspace = true tracing.workspace = true -wacc.workspace = true [lints] workspace = true diff --git a/crates/bs/src/error.rs b/crates/bs/src/error.rs index fe72900..bb9a2a3 100644 --- a/crates/bs/src/error.rs +++ b/crates/bs/src/error.rs @@ -39,9 +39,6 @@ pub enum Error { /// I/O error #[error(transparent)] Io(#[from] std::io::Error), - /// Serde CBOR error - #[error(transparent)] - SerdeCbor(#[from] serde_cbor::Error), } /// Open op errors diff --git a/crates/bs/src/ops/open.rs b/crates/bs/src/ops/open.rs index 3b0bc5b..d673cf1 100644 --- a/crates/bs/src/ops/open.rs +++ b/crates/bs/src/ops/open.rs @@ -7,9 +7,8 @@ pub use config::Config; use crate::{ error::OpenError, update::{op, script, OpParams}, - Error, }; -use bs_traits::{GetKey, Signer}; +use bs_traits::{GetKey, Signer, SyncGetKey, SyncSigner}; use multicid::{cid, vlad, Cid}; use multicodec::Codec; use multihash::mh; @@ -20,10 +19,18 @@ use std::{fs::read, path::Path}; use tracing::debug; /// open a new provenance log based on the config -pub fn open_plog(config: Config, get_key: &G, sign_entry: &S) -> Result +pub fn open_plog(config: Config, key_manager: &G, signer: &S) -> Result where - G: GetKey, - S: Signer, + G: GetKey + SyncGetKey, + S: Signer + SyncSigner, + E: From + + From + + From + + From + + From + + From + + From + + ToString, { // 0. Set up the list of ops we're going to add let mut op_params = Vec::default(); @@ -33,14 +40,14 @@ where config .additional_ops .iter() - .try_for_each(|params| -> Result<(), Error> { + .try_for_each(|params| -> Result<(), E> { match params { p @ OpParams::KeyGen { .. } => { - let _ = load_key(&mut op_params, p, get_key)?; + let _ = load_key(&mut op_params, p, key_manager)?; } p @ OpParams::CidGen { .. } => { - let _ = load_cid(&mut op_params, p, |path| -> Result, Error> { - Ok(read(path)?) + let _ = load_cid(&mut op_params, p, |path| -> Result, E> { + read(path).map_err(E::from) })?; } p => op_params.push(p.clone()), @@ -53,15 +60,15 @@ where // get the codec for the vlad signing key and cid let (vlad_key_params, vlad_cid_params) = config .vlad_params - .ok_or::(OpenError::InvalidVladParams.into())?; + .ok_or::(OpenError::InvalidVladParams.into())?; // get the vlad signing key - let vlad_mk = load_key(&mut op_params, &vlad_key_params, get_key)?; + let vlad_mk = load_key(&mut op_params, &vlad_key_params, key_manager)?; // get the cid for the first lock script let mut first_lock_script: Option