From f8cca0a33114f0f010a551fc11ed5c347578615a Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Thu, 26 Oct 2023 13:44:36 +0200 Subject: [PATCH] gdk_rust: switch back to serde_cbor we switched to ciborium because serde_cbor it's unmantained. However, serde_cbor never gave us trouble, while ciborium had the "invalid type: bytes, expected bytes" bug, which has been attempted to be solved upstream in https://github.com/enarx/ciborium/pull/97 Apart that we have no input on the MR yet, in trying to use the patched version we encountered the error: "invalid type: string, expected map" which is probably due to the fact the patched version is on master and not just the bug fix from the tagged version we use. While this later approach could work, ciborium doesn't look that reliable so we decided to switch back to serde_cbor for the time being. --- subprojects/gdk_rust/Cargo.lock | 39 ++++++------------- subprojects/gdk_rust/Cargo.toml | 1 + subprojects/gdk_rust/gdk_common/Cargo.toml | 2 +- .../gdk_rust/gdk_common/src/be/blockheader.rs | 4 +- subprojects/gdk_rust/gdk_common/src/lib.rs | 2 +- .../gdk_rust/gdk_common/src/util/mod.rs | 9 ----- .../gdk_rust/gdk_electrum/src/error.rs | 11 ++---- .../gdk_rust/gdk_electrum/src/headers/mod.rs | 7 ++-- .../gdk_rust/gdk_electrum/src/store.rs | 23 ++++++----- .../gdk_rust/gdk_registry/src/cache.rs | 6 +-- .../gdk_rust/gdk_registry/src/error.rs | 14 +++---- subprojects/gdk_rust/gdk_registry/src/file.rs | 4 +- 12 files changed, 44 insertions(+), 78 deletions(-) diff --git a/subprojects/gdk_rust/Cargo.lock b/subprojects/gdk_rust/Cargo.lock index 792b436c5..ccdd75fa9 100644 --- a/subprojects/gdk_rust/Cargo.lock +++ b/subprojects/gdk_rust/Cargo.lock @@ -274,33 +274,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "ciborium" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" - -[[package]] -name = "ciborium-ll" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" -dependencies = [ - "ciborium-io", - "half", -] - [[package]] name = "cipher" version = "0.3.0" @@ -612,7 +585,6 @@ dependencies = [ "aes", "aes-gcm-siv", "bitcoin 0.30.0", - "ciborium", "electrum-client", "elements", "libc", @@ -621,6 +593,7 @@ dependencies = [ "once_cell", "rand", "serde", + "serde_cbor", "serde_json", "strum", "strum_macros", @@ -1424,6 +1397,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.186" diff --git a/subprojects/gdk_rust/Cargo.toml b/subprojects/gdk_rust/Cargo.toml index c563254d0..bea4ede0c 100644 --- a/subprojects/gdk_rust/Cargo.toml +++ b/subprojects/gdk_rust/Cargo.toml @@ -9,6 +9,7 @@ members = [ ] exclude = [ "gdk_test" ] +resolver = "2" [profile.release] lto = true diff --git a/subprojects/gdk_rust/gdk_common/Cargo.toml b/subprojects/gdk_rust/gdk_common/Cargo.toml index d5d61e67e..8c0cab966 100644 --- a/subprojects/gdk_rust/gdk_common/Cargo.toml +++ b/subprojects/gdk_rust/gdk_common/Cargo.toml @@ -11,7 +11,7 @@ testing = [] aes = "0.7.0" aes-gcm-siv = "0.10" bitcoin = { version = "0.30", features = ["serde"] } -ciborium = "0.2.1" +serde_cbor = "0.11.1" elements = { version = "0.22", features = ["serde"] } libc = "0.2" log = "0.4.8" diff --git a/subprojects/gdk_rust/gdk_common/src/be/blockheader.rs b/subprojects/gdk_rust/gdk_common/src/be/blockheader.rs index 21c11d640..add35a78e 100644 --- a/subprojects/gdk_rust/gdk_common/src/be/blockheader.rs +++ b/subprojects/gdk_rust/gdk_common/src/be/blockheader.rs @@ -57,8 +57,8 @@ mod test { #[test] fn test_cbor_header() { let header = block_header_dynafed(); - let vec = crate::util::ciborium_to_vec(&header).unwrap(); - let back: BlockHeader = ciborium::from_reader(&vec[..]).unwrap(); + let vec = serde_cbor::to_vec(&header).unwrap(); + let back: BlockHeader = serde_cbor::from_slice(&vec).unwrap(); assert_eq!(header, back); } diff --git a/subprojects/gdk_rust/gdk_common/src/lib.rs b/subprojects/gdk_rust/gdk_common/src/lib.rs index b197763a6..e802c9476 100644 --- a/subprojects/gdk_rust/gdk_common/src/lib.rs +++ b/subprojects/gdk_rust/gdk_common/src/lib.rs @@ -20,7 +20,6 @@ pub mod aes { } pub use bitcoin; -pub use ciborium; pub use electrum_client; pub use elements; pub use error::*; @@ -29,6 +28,7 @@ pub use miniscript; pub use network::*; pub use once_cell; pub use rand; +pub use serde_cbor; pub use state::State; pub use ureq; diff --git a/subprojects/gdk_rust/gdk_common/src/util/mod.rs b/subprojects/gdk_rust/gdk_common/src/util/mod.rs index 14c88560e..7818f3f51 100644 --- a/subprojects/gdk_rust/gdk_common/src/util/mod.rs +++ b/subprojects/gdk_rust/gdk_common/src/util/mod.rs @@ -20,12 +20,3 @@ pub fn now() -> u64 { // Realistic timestamps can be converted to u64 u64::try_from(since_the_epoch.as_micros()).unwrap_or(u64::MAX) } - -pub fn ciborium_to_vec(value: &T) -> Result, ciborium::ser::Error> -where - T: serde::ser::Serialize, -{ - let mut v = Vec::new(); - ciborium::ser::into_writer(value, &mut v)?; - Ok(v) -} diff --git a/subprojects/gdk_rust/gdk_electrum/src/error.rs b/subprojects/gdk_rust/gdk_electrum/src/error.rs index dc4af414c..c2a22b14d 100644 --- a/subprojects/gdk_rust/gdk_electrum/src/error.rs +++ b/subprojects/gdk_rust/gdk_electrum/src/error.rs @@ -2,7 +2,7 @@ use crate::BETxid; use gdk_common::bitcoin::bip32::ExtendedPubKey; use gdk_common::bitcoin::sighash; use gdk_common::error::Error as CommonError; -use gdk_common::{bitcoin, ciborium, electrum_client, elements, ureq}; +use gdk_common::{bitcoin, electrum_client, elements, serde_cbor, ureq}; use serde::ser::Serialize; use std::convert::From; use std::path::PathBuf; @@ -75,6 +75,9 @@ pub enum Error { #[error(transparent)] JSON(#[from] serde_json::error::Error), + #[error(transparent)] + SerdeCbor(#[from] serde_cbor::Error), + #[error("insufficient funds")] InsufficientFunds, @@ -163,12 +166,6 @@ pub enum Error { #[error("sendall error")] SendAll, - #[error(transparent)] - DeserializeCBORError(#[from] ciborium::de::Error), - - #[error(transparent)] - SerializeCBORError(#[from] ciborium::ser::Error), - #[error(transparent)] SliceConversionError(#[from] std::array::TryFromSliceError), diff --git a/subprojects/gdk_rust/gdk_electrum/src/headers/mod.rs b/subprojects/gdk_rust/gdk_electrum/src/headers/mod.rs index 0c8b4534a..8e8ed7ba8 100644 --- a/subprojects/gdk_rust/gdk_electrum/src/headers/mod.rs +++ b/subprojects/gdk_rust/gdk_electrum/src/headers/mod.rs @@ -7,7 +7,6 @@ use gdk_common::aes::aead::NewAead; use gdk_common::aes::{Aes256GcmSiv, Key}; use gdk_common::be::{BETxid, BETxidConvert}; use gdk_common::bitcoin::hashes::{sha256, sha256d, Hash}; -use gdk_common::electrum_client; use gdk_common::elements; use gdk_common::log::{debug, info, warn}; use gdk_common::model::{ @@ -15,8 +14,8 @@ use gdk_common::model::{ SPVVerifyTxResult, }; use gdk_common::store::{Decryptable, Encryptable}; -use gdk_common::util::ciborium_to_vec; use gdk_common::NetworkId; +use gdk_common::{electrum_client, serde_cbor}; use std::collections::HashSet; use std::fs::File; use std::io::Write; @@ -243,7 +242,7 @@ impl VerifiedCache { ) -> Result, Error> { let mut file = File::open(&filepath)?; let plaintext = file.decrypt(cipher)?; - Ok(gdk_common::ciborium::from_reader(&plaintext[..])?) + Ok(gdk_common::serde_cbor::from_reader(&plaintext[..])?) } fn contains(&self, txid: &BETxid, height: u32) -> Result { @@ -263,7 +262,7 @@ impl VerifiedCache { fn flush(&mut self) -> Result<(), Error> { if let Some(store) = &self.store { - let plaintext = ciborium_to_vec(&self.set)?; + let plaintext = serde_cbor::to_vec(&self.set)?; let (nonce_bytes, ciphertext) = plaintext.encrypt(&store.cipher)?; let mut file = File::create(&store.filepath)?; file.write_all(&nonce_bytes)?; diff --git a/subprojects/gdk_rust/gdk_electrum/src/store.rs b/subprojects/gdk_rust/gdk_electrum/src/store.rs index 2f087802d..d711dfe7d 100644 --- a/subprojects/gdk_rust/gdk_electrum/src/store.rs +++ b/subprojects/gdk_rust/gdk_electrum/src/store.rs @@ -9,13 +9,12 @@ use gdk_common::be::{ use gdk_common::bitcoin::bip32::{DerivationPath, ExtendedPubKey}; use gdk_common::bitcoin::hashes::{sha256, Hash}; use gdk_common::bitcoin::Txid; -use gdk_common::ciborium; use gdk_common::elements; use gdk_common::elements::TxOutSecrets; use gdk_common::log::{info, log, Level}; use gdk_common::model::{AccountSettings, FeeEstimate, SPVVerifyTxResult, Settings}; +use gdk_common::serde_cbor; use gdk_common::store::{Decryptable, Encryptable, ToCipher}; -use gdk_common::util::ciborium_to_vec; use gdk_common::wally::MasterBlindingKey; use gdk_common::NetworkId; use serde::{Deserialize, Serialize}; @@ -211,7 +210,7 @@ impl RawCache { fn try_new>(path: P, cipher: &Aes256GcmSiv) -> Result { let decrypted = load_decrypt(Kind::Cache, path, cipher)?; - let store = ciborium::from_reader(&decrypted[..])?; + let store = serde_cbor::from_reader(&decrypted[..])?; Ok(store) } @@ -253,7 +252,7 @@ impl RawStore { fn try_new>(path: P, cipher: &Aes256GcmSiv) -> Result { let decrypted = load_decrypt(Kind::Store, path, cipher)?; - let store = ciborium::from_reader(&decrypted[..])?; + let store = serde_cbor::from_reader(&decrypted[..])?; Ok(store) } } @@ -334,8 +333,8 @@ impl StoreMeta { let now = Instant::now(); let plaintext = match kind { - Kind::Store => ciborium_to_vec(&self.store), - Kind::Cache => ciborium_to_vec(&self.cache), + Kind::Store => serde_cbor::to_vec(&self.store), + Kind::Cache => serde_cbor::to_vec(&self.cache), }?; let hash = sha256::Hash::hash(&plaintext); @@ -698,14 +697,14 @@ mod tests { }, }; - let blob = ciborium_to_vec(&store_v0).unwrap(); - let store_v1: RawStoreV1 = ciborium::from_reader(&blob[..]).unwrap(); + let blob = serde_cbor::to_vec(&store_v0).unwrap(); + let store_v1: RawStoreV1 = serde_cbor::from_reader(&blob[..]).unwrap(); assert_eq!(store_v0.settings, store_v1.settings); assert_eq!(store_v0.memos, store_v1.memos); - let blob = ciborium_to_vec(&store_v1).unwrap(); - let store_v0: RawStoreV0 = ciborium::from_reader(&blob[..]).unwrap(); + let blob = serde_cbor::to_vec(&store_v1).unwrap(); + let store_v0: RawStoreV0 = serde_cbor::from_reader(&blob[..]).unwrap(); assert_eq!(store_v0.settings, store_v1.settings); assert_eq!(store_v0.memos, store_v1.memos); } @@ -736,8 +735,8 @@ mod tests { bip44_discovered: Default::default(), }; - let blob = ciborium_to_vec(&cache_v0).unwrap(); - let cache_v1: RawAccountCacheV1 = ciborium::from_reader(&blob[..]) + let blob = serde_cbor::to_vec(&cache_v0).unwrap(); + let cache_v1: RawAccountCacheV1 = serde_cbor::from_reader(&blob[..]) .expect("cache compatibility broke, not critical but think twice"); assert_eq!(cache_v0.xpub, cache_v1.xpub); diff --git a/subprojects/gdk_rust/gdk_registry/src/cache.rs b/subprojects/gdk_rust/gdk_registry/src/cache.rs index e56437ae5..c91efd6fa 100644 --- a/subprojects/gdk_rust/gdk_registry/src/cache.rs +++ b/subprojects/gdk_rust/gdk_registry/src/cache.rs @@ -11,8 +11,8 @@ use gdk_common::bitcoin::hashes::{sha256, Hash}; use gdk_common::elements::AssetId; use gdk_common::log::{debug, warn}; use gdk_common::once_cell::sync::{Lazy, OnceCell}; +use gdk_common::serde_cbor; use gdk_common::store::{Decryptable, Encryptable, ToCipher}; -use gdk_common::util::ciborium_to_vec; use serde::{Deserialize, Serialize}; use crate::registry_infos::{RegistryAssets, RegistryIcons}; @@ -128,7 +128,7 @@ impl Cache { let get_cache = |file: &mut File| -> Result { let cipher = xpub.to_cipher()?; let decrypted = file.decrypt(&cipher)?; - gdk_common::ciborium::from_reader(&decrypted[..]).map_err(Into::into) + gdk_common::serde_cbor::from_reader(&decrypted[..]).map_err(Into::into) }; let mut cache = match cache_files.get_mut(&hash_xpub(xpub)) { @@ -178,7 +178,7 @@ impl Cache { pub(crate) fn update(&self, cache_files: &mut CacheFiles) -> Result<()> { let xpub = self.xpub.unwrap(); - let plain_text = ciborium_to_vec(self)?; + let plain_text = serde_cbor::to_vec(self)?; let cipher = xpub.to_cipher()?; let (nonce, rest) = plain_text.encrypt(&cipher)?; diff --git a/subprojects/gdk_rust/gdk_registry/src/error.rs b/subprojects/gdk_rust/gdk_registry/src/error.rs index 08117913d..913981a22 100644 --- a/subprojects/gdk_rust/gdk_registry/src/error.rs +++ b/subprojects/gdk_rust/gdk_registry/src/error.rs @@ -1,4 +1,4 @@ -use gdk_common::{bitcoin, ciborium, elements, ureq}; +use gdk_common::{bitcoin, elements, serde_cbor, ureq}; use std::sync::{MutexGuard, PoisonError, TryLockError}; /// Result type alias of the `gdk_registry` crate. @@ -69,18 +69,14 @@ pub enum Error { #[error(transparent)] SerdeJson(#[from] serde_json::Error), - /// Wraps errors happened when serializing CBORs. - #[error(transparent)] - SerializeCbor(#[from] ciborium::ser::Error), - - /// Wraps errors happened when deserializing CBORs. - #[error(transparent)] - DeserializeCbor(#[from] ciborium::de::Error), - /// Wraps http errors. #[error(transparent)] Ureq(#[from] ureq::Error), + /// Wraps serde error. + #[error(transparent)] + SerdeCbor(#[from] serde_cbor::Error), + /// A generic error. #[error("{0}")] Generic(String), diff --git a/subprojects/gdk_rust/gdk_registry/src/file.rs b/subprojects/gdk_rust/gdk_registry/src/file.rs index f50d3c950..86a2852ad 100644 --- a/subprojects/gdk_rust/gdk_registry/src/file.rs +++ b/subprojects/gdk_rust/gdk_registry/src/file.rs @@ -12,7 +12,7 @@ pub(crate) fn read(file: &mut File) -> Result { info!("file {:?} size {}", &file, file.metadata()?.len()); } let buffered = BufReader::new(file); - Ok(gdk_common::ciborium::from_reader(buffered)?) + Ok(gdk_common::serde_cbor::from_reader(buffered)?) } pub(crate) fn write(value: &V, file: &mut File) -> Result<()> { @@ -24,7 +24,7 @@ pub(crate) fn write(value: &V, file: &mut File) -> Result<()> { file.seek(std::io::SeekFrom::Start(0))?; let buffered = BufWriter::new(file); - Ok(gdk_common::ciborium::ser::into_writer(value, buffered)?) + Ok(gdk_common::serde_cbor::to_writer(buffered, value)?) } #[cfg(test)]