Make use of serde-with for monero-rpc

This commit is contained in:
Thomas Eizinger 2021-05-19 14:14:41 +10:00
parent ec1916161e
commit 1447242fa6
No known key found for this signature in database
GPG Key ID: 651AC83A6C6C8B96
4 changed files with 107 additions and 61 deletions

73
Cargo.lock generated
View File

@ -654,7 +654,7 @@ dependencies = [
"ansi_term 0.11.0",
"atty",
"bitflags",
"strsim",
"strsim 0.8.0",
"textwrap",
"unicode-width",
"vec_map",
@ -858,6 +858,41 @@ dependencies = [
"zeroize",
]
[[package]]
name = "darling"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36"
dependencies = [
"fnv",
"ident_case",
"proc-macro2 1.0.24",
"quote 1.0.9",
"strsim 0.10.0",
"syn 1.0.64",
]
[[package]]
name = "darling_macro"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a"
dependencies = [
"darling_core",
"quote 1.0.9",
"syn 1.0.64",
]
[[package]]
name = "data-encoding"
version = "2.3.2"
@ -1578,6 +1613,12 @@ dependencies = [
"webpki",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.1.5"
@ -2345,6 +2386,7 @@ dependencies = [
"reqwest",
"serde",
"serde_json",
"serde_with",
"tokio",
"tracing",
]
@ -3513,6 +3555,29 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_with"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edeeaecd5445109b937a3a335dc52780ca7779c4b4b7374cc6340dedfe44cfca"
dependencies = [
"rustversion",
"serde",
"serde_with_macros",
]
[[package]]
name = "serde_with_macros"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e48b35457e9d855d3dc05ef32a73e0df1e2c0fd72c38796a4ee909160c8eeec2"
dependencies = [
"darling",
"proc-macro2 1.0.24",
"quote 1.0.9",
"syn 1.0.64",
]
[[package]]
name = "serial_test"
version = "0.4.0"
@ -3825,6 +3890,12 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "structopt"
version = "0.3.21"

View File

@ -16,6 +16,7 @@ reqwest = { version = "0.11", default-features = false, features = [ "json" ] }
serde = { version = "1.0", features = [ "derive" ] }
serde_json = "1.0"
tracing = "0.1"
serde_with = "1"
[dev-dependencies]
hex-literal = "0.3"

View File

@ -1,6 +1,8 @@
use anyhow::{Context, Result};
use monero::{cryptonote::hash::Hash, util::ringct, PublicKey, Transaction};
use serde::{de::DeserializeOwned, Deserialize, Serialize, Serializer};
use curve25519_dalek::edwards::EdwardsPoint;
use monero::{cryptonote::hash::Hash, Transaction};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_with::{serde_as, TryFromInto};
#[jsonrpc_client::api(version = "2.0")]
pub trait MonerodRpc {
@ -184,9 +186,10 @@ struct GetTransactionsResponseEntry {
as_hex: Transaction,
}
#[serde_as]
#[derive(Clone, Debug, Serialize)]
struct GetOIndexesPayload {
#[serde(with = "byte_array")]
#[serde_as(as = "TryFromInto<[u8; 32]>")]
txid: Hash,
}
@ -227,14 +230,15 @@ pub struct SendRawTransactionResponse {
pub too_big: bool,
}
#[serde_as]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
pub struct OutKey {
pub height: u64,
#[serde(with = "byte_array")]
pub key: PublicKey,
#[serde(with = "byte_array")]
pub mask: PublicKey,
#[serde(with = "byte_array")]
#[serde_as(as = "TryFromInto<[u8; 32]>")]
pub key: EdwardsPoint,
#[serde_as(as = "TryFromInto<[u8; 32]>")]
pub mask: EdwardsPoint,
#[serde_as(as = "TryFromInto<[u8; 32]>")]
pub txid: Hash,
pub unlocked: bool,
}
@ -304,55 +308,3 @@ mod monero_serde_hex_transaction {
Ok(block)
}
}
mod byte_array {
use super::*;
use serde::{de::Error, Deserializer};
use std::{convert::TryFrom, fmt, marker::PhantomData};
pub fn serialize<S, B>(bytes: B, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
B: AsRef<[u8]>,
{
serializer.serialize_bytes(bytes.as_ref())
}
pub fn deserialize<'de, D, B, const N: usize>(deserializer: D) -> Result<B, D::Error>
where
D: Deserializer<'de>,
B: TryFrom<[u8; N]>,
{
struct Visitor<T, const N: usize> {
phantom: PhantomData<(T, [u8; N])>,
}
impl<'de, T, const N: usize> serde::de::Visitor<'de> for Visitor<T, N>
where
T: TryFrom<[u8; N]>,
{
type Value = T;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "a byte buffer")
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: Error,
{
let bytes = <[u8; N]>::try_from(v).map_err(|_| {
E::custom(format!("Failed to construct [u8; {}] from buffer", N))
})?;
let result = T::try_from(bytes)
.map_err(|_| E::custom(format!("Failed to construct T from [u8; {}]", N)))?;
Ok(result)
}
}
deserializer.deserialize_byte_buf(Visitor {
phantom: PhantomData,
})
}
}

View File

@ -17,6 +17,7 @@ impl EmptyTransaction {
}
}
#[derive(Debug)]
pub struct MissingOpening; // The opening was missing from the TX
pub struct InputAdded {}
@ -46,6 +47,7 @@ impl InputAdded {
}
}
#[derive(Debug)]
pub struct DuplicateIndex; // One of the indices was an evil twin
pub struct DecoyOffsetsAdded {}
@ -61,6 +63,7 @@ impl DecoyOffsetsAdded {
}
}
#[derive(Debug)]
pub struct InsufficientFunds;
pub struct OutputsAdded {}
@ -108,6 +111,7 @@ impl OutputsBlinded {
}
}
#[derive(Debug)]
pub struct InvalidSignature;
// TODO: We can break the CLSAG fn signature down into two parts:
@ -124,3 +128,21 @@ pub struct SignatureParameters {
// signing_key_index: usize,
pseudo_output_commitment: EdwardsPoint,
}
#[cfg(test)]
mod tests {
use super::*;
use rand::thread_rng;
// #[test]
// fn api_test() {
// let tx = EmptyTransaction::spend_from(todo!(), todo!())
// .unwrap()
// .with_random_decoys(&mut thread_rng(), todo!())
// .add_output(todo!(), todo!(), &mut thread_rng())
// .unwrap()
// .blind_outputs(todo!());
//
// tx.with_signature(todo!());
// }
}