From cdfc8419ad11b66efd458d3a92ce259559c37039 Mon Sep 17 00:00:00 2001 From: rishflab Date: Wed, 6 Oct 2021 18:58:13 +1100 Subject: [PATCH] Implement human-readable serialization for monero private key Some of the swap states were unable to be serialized using serde_json because this was not implemented. --- Cargo.lock | 1 + swap/Cargo.toml | 1 + swap/src/monero.rs | 35 ++++++++++++++++++++++++++++++++--- swap/tests/harness/mod.rs | 18 +++++++++++------- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b16c5021..8a03cf46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4128,6 +4128,7 @@ dependencies = [ "ed25519-dalek", "futures", "get-port", + "hex 0.4.3", "hyper 0.14.12", "itertools 0.10.1", "libp2p", diff --git a/swap/Cargo.toml b/swap/Cargo.toml index 0ff8e094..6a066938 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -29,6 +29,7 @@ directories-next = "2" ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", default-features = false, features = [ "libsecp_compat", "serde" ] } ed25519-dalek = "1" futures = { version = "0.3", default-features = false } +hex = "0.4" itertools = "0.10" libp2p = { git = "https://github.com/comit-network/rust-libp2p", branch = "rendezvous", default-features = false, features = [ "tcp-tokio", "yamux", "mplex", "dns-tokio", "noise", "request-response", "websocket", "ping", "rendezvous" ] } miniscript = { version = "5", features = [ "serde" ] } diff --git a/swap/src/monero.rs b/swap/src/monero.rs index bcfd3a3d..86c97eba 100644 --- a/swap/src/monero.rs +++ b/swap/src/monero.rs @@ -234,6 +234,15 @@ pub mod monero_private_key { let mut s = s; PrivateKey::consensus_decode(&mut s).map_err(|err| E::custom(format!("{:?}", err))) } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error, + { + let bytes = hex::decode(s).map_err(|err| E::custom(format!("{:?}", err)))?; + PrivateKey::consensus_decode(&mut bytes.as_slice()) + .map_err(|err| E::custom(format!("{:?}", err))) + } } pub fn serialize(x: &PrivateKey, s: S) -> Result @@ -243,7 +252,11 @@ pub mod monero_private_key { let mut bytes = Cursor::new(vec![]); x.consensus_encode(&mut bytes) .map_err(|err| S::Error::custom(format!("{:?}", err)))?; - s.serialize_bytes(bytes.into_inner().as_ref()) + if s.is_human_readable() { + s.serialize_str(&hex::encode(bytes.into_inner())) + } else { + s.serialize_bytes(bytes.into_inner().as_ref()) + } } pub fn deserialize<'de, D>( @@ -252,7 +265,13 @@ pub mod monero_private_key { where D: Deserializer<'de>, { - let key = deserializer.deserialize_bytes(BytesVisitor)?; + let key = { + if deserializer.is_human_readable() { + deserializer.deserialize_string(BytesVisitor)? + } else { + deserializer.deserialize_bytes(BytesVisitor)? + } + }; Ok(key) } } @@ -351,7 +370,17 @@ mod tests { pub struct MoneroAmount(#[serde(with = "monero_amount")] crate::monero::Amount); #[test] - fn serde_monero_private_key() { + fn serde_monero_private_key_json() { + let key = MoneroPrivateKey(monero::PrivateKey::from_scalar( + crate::monero::Scalar::random(&mut OsRng), + )); + let encoded = serde_json::to_vec(&key).unwrap(); + let decoded: MoneroPrivateKey = serde_json::from_slice(&encoded).unwrap(); + assert_eq!(key, decoded); + } + + #[test] + fn serde_monero_private_key_cbor() { let key = MoneroPrivateKey(monero::PrivateKey::from_scalar( crate::monero::Scalar::random(&mut OsRng), )); diff --git a/swap/tests/harness/mod.rs b/swap/tests/harness/mod.rs index fbf1115a..1c04f86f 100644 --- a/swap/tests/harness/mod.rs +++ b/swap/tests/harness/mod.rs @@ -18,6 +18,7 @@ use swap::asb::FixedRate; use swap::bitcoin::{CancelTimelock, PunishTimelock, TxCancel, TxPunish, TxRedeem, TxRefund}; use swap::database::SledDatabase; use swap::env::{Config, GetConfig}; +use swap::fs::ensure_directory_exists; use swap::network::swarm; use swap::protocol::alice::{AliceState, Swap}; use swap::protocol::bob::BobState; @@ -156,13 +157,16 @@ async fn init_containers(cli: &Cli) -> (Monero, Containers<'_>) { .await .unwrap(); - (monero, Containers { - bitcoind_url, - bitcoind, - monerod_container, - monero_wallet_rpc_containers, - electrs, - }) + ( + monero, + Containers { + bitcoind_url, + bitcoind, + monerod_container, + monero_wallet_rpc_containers, + electrs, + }, + ) } async fn init_bitcoind_container(