monero-wire: fix some message decoding

This commit is contained in:
Boog900 2024-01-17 16:31:57 +00:00
parent 0cc2acc816
commit b14e740d2d
No known key found for this signature in database
GPG key ID: 5401367FB7302004
5 changed files with 84 additions and 48 deletions

14
Cargo.lock generated
View file

@ -463,7 +463,7 @@ dependencies = [
"futures", "futures",
"hex", "hex",
"monero-consensus", "monero-consensus",
"monero-epee-bin-serde", "monero-epee-bin-serde 1.0.1 (git+https://github.com/monero-rs/monero-epee-bin-serde.git?rev=e4a585a)",
"monero-serai", "monero-serai",
"monero-wire", "monero-wire",
"multiexp", "multiexp",
@ -1163,6 +1163,16 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "monero-epee-bin-serde"
version = "1.0.1"
source = "git+https://github.com/monero-rs/monero-epee-bin-serde.git?rev=aafe4ba#aafe4ba1b9912b03cf616db7403628fc2bd82eb1"
dependencies = [
"byteorder",
"serde",
"serde_bytes",
]
[[package]] [[package]]
name = "monero-epee-bin-serde" name = "monero-epee-bin-serde"
version = "1.0.1" version = "1.0.1"
@ -1245,7 +1255,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"hex", "hex",
"levin-cuprate", "levin-cuprate",
"monero-epee-bin-serde", "monero-epee-bin-serde 1.0.1 (git+https://github.com/monero-rs/monero-epee-bin-serde.git?rev=aafe4ba)",
"serde", "serde",
"serde_bytes", "serde_bytes",
"thiserror", "thiserror",

View file

@ -9,7 +9,7 @@ repository = "https://github.com/SyntheticBird45/cuprate/tree/main/net/monero-wi
[dependencies] [dependencies]
levin-cuprate = {path="../levin"} levin-cuprate = {path="../levin"}
monero-epee-bin-serde = {git = "https://github.com/monero-rs/monero-epee-bin-serde.git", rev="e4a585a"} monero-epee-bin-serde = {git = "https://github.com/monero-rs/monero-epee-bin-serde.git", rev="aafe4ba"}
serde = {version = "1", features = ["derive"]} serde = {version = "1", features = ["derive"]}
serde_bytes = "0.11" serde_bytes = "0.11"
thiserror = "1" thiserror = "1"

View file

@ -16,10 +16,9 @@
//! Common types that are used across multiple messages. //! Common types that are used across multiple messages.
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;
use crate::{ use crate::{
serde_helpers::{default_false, default_zero}, serde_helpers::{default_false, default_zero, serde_vec_bytes},
NetworkAddress, NetworkAddress,
}; };
@ -159,7 +158,8 @@ impl std::hash::Hash for PeerListEntryBase {
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct PrunedTxBlobEntry { pub struct PrunedTxBlobEntry {
/// The Tx /// The Tx
pub tx: ByteBuf, #[serde(with = "serde_bytes")]
pub tx: Vec<u8>,
/// The Prunable Tx Hash /// The Prunable Tx Hash
pub prunable_hash: [u8; 32], pub prunable_hash: [u8; 32],
} }
@ -168,12 +168,29 @@ pub struct PrunedTxBlobEntry {
#[serde(untagged)] #[serde(untagged)]
pub enum TransactionBlobs { pub enum TransactionBlobs {
Pruned(Vec<PrunedTxBlobEntry>), Pruned(Vec<PrunedTxBlobEntry>),
Normal(Vec<ByteBuf>), #[serde(with = "serde_vec_bytes")]
Normal(Vec<Vec<u8>>),
#[serde(skip_serializing)] #[serde(skip_serializing)]
None, None,
} }
impl TransactionBlobs { impl TransactionBlobs {
pub fn take_pruned(self) -> Option<Vec<PrunedTxBlobEntry>> {
match self {
TransactionBlobs::Normal(_) => None,
TransactionBlobs::Pruned(txs) => Some(txs),
TransactionBlobs::None => Some(vec![]),
}
}
pub fn take_normal(self) -> Option<Vec<Vec<u8>>> {
match self {
TransactionBlobs::Normal(txs) => Some(txs),
TransactionBlobs::Pruned(_) => None,
TransactionBlobs::None => Some(vec![]),
}
}
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
match self { match self {
TransactionBlobs::Normal(txs) => txs.len(), TransactionBlobs::Normal(txs) => txs.len(),
@ -198,7 +215,6 @@ pub struct BlockCompleteEntry {
#[serde(default = "default_false")] #[serde(default = "default_false")]
pub pruned: bool, pub pruned: bool,
/// The Block /// The Block
//#[serde_as(as = "Bytes")]
#[serde(with = "serde_bytes")] #[serde(with = "serde_bytes")]
pub block: Vec<u8>, pub block: Vec<u8>,
/// The Block Weight/Size /// The Block Weight/Size

View file

@ -21,6 +21,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf; use serde_bytes::ByteBuf;
use monero_epee_bin_serde::container_as_blob;
use super::common::BlockCompleteEntry; use super::common::BlockCompleteEntry;
use crate::serde_helpers::*; use crate::serde_helpers::*;
@ -43,13 +45,17 @@ pub struct NewTransactions {
pub dandelionpp_fluff: bool, pub dandelionpp_fluff: bool,
/// Padding /// Padding
#[serde(rename = "_")] #[serde(rename = "_")]
pub padding: ByteBuf, #[serde(with = "serde_bytes")]
pub padding: Vec<u8>,
} }
/// A Request For Blocks /// A Request For Blocks
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GetObjectsRequest { pub struct GetObjectsRequest {
/// Block hashes we want /// Block hashes we want
#[serde(default = "Vec::new")]
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(with = "container_as_blob")]
pub blocks: Vec<[u8; 32]>, pub blocks: Vec<[u8; 32]>,
/// Pruned /// Pruned
#[serde(default = "default_false")] #[serde(default = "default_false")]
@ -64,6 +70,8 @@ pub struct GetObjectsResponse {
pub blocks: Vec<BlockCompleteEntry>, pub blocks: Vec<BlockCompleteEntry>,
/// Missed IDs /// Missed IDs
#[serde(default = "Vec::new")] #[serde(default = "Vec::new")]
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(with = "container_as_blob")]
pub missed_ids: Vec<[u8; 32]>, pub missed_ids: Vec<[u8; 32]>,
/// The height of the peers blockchain /// The height of the peers blockchain
pub current_blockchain_height: u64, pub current_blockchain_height: u64,
@ -73,6 +81,9 @@ pub struct GetObjectsResponse {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ChainRequest { pub struct ChainRequest {
/// Block IDs /// Block IDs
#[serde(default = "Vec::new")]
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(with = "container_as_blob")]
pub block_ids: Vec<[u8; 32]>, pub block_ids: Vec<[u8; 32]>,
/// Prune /// Prune
#[serde(default = "default_false")] #[serde(default = "default_false")]
@ -80,7 +91,6 @@ pub struct ChainRequest {
} }
/// A Chain Response /// A Chain Response
// TODO: Fix the fields on this: m_block_ids, m_block_weights
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ChainResponse { pub struct ChainResponse {
/// Start Height /// Start Height
@ -93,46 +103,19 @@ pub struct ChainResponse {
#[serde(default = "default_zero")] #[serde(default = "default_zero")]
pub cumulative_difficulty_top64: u64, pub cumulative_difficulty_top64: u64,
/// Block IDs /// Block IDs
#[serde(default = "ByteBuf::new")] #[serde(default = "Vec::new")]
pub m_block_ids: ByteBuf, #[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(with = "container_as_blob")]
pub m_block_ids: Vec<[u8; 32]>,
/// Block Weights /// Block Weights
#[serde(default = "ByteBuf::new")] #[serde(default = "Vec::new")]
pub m_block_weights: ByteBuf, #[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(with = "container_as_blob")]
pub m_block_weights: Vec<u64>,
/// The first Block in the response /// The first Block in the response
#[serde(default = "ByteBuf::new")] #[serde(default = "Vec::new")]
pub first_block: ByteBuf, #[serde(with = "serde_bytes")]
} pub first_block: Vec<u8>,
impl ChainResponse {
/*
pub fn new(
start_height: u64,
total_height: u64,
cumulative_difficulty_128: u128,
m_block_ids: ByteBuf,
m_block_weights: Vec<u64>,
first_block: ByteBuf,
) -> Self {
let cumulative_difficulty_low = cumulative_difficulty_128 as u64;
let cumulative_difficulty_high = (cumulative_difficulty_128 >> 64) as u64;
Self {
// start_height,
// total_height,
// cumulative_difficulty_low,
// cumulative_difficulty_high,
m_block_ids,
// m_block_weights,
// first_block,
}
}
pub fn cumulative_difficulty(&self) -> u128 {
let mut ret: u128 = self.cumulative_difficulty_high as u128;
ret <<= 64;
ret | self.cumulative_difficulty_low as u128
}
*/
} }
/// A Block that doesn't have transactions unless requested /// A Block that doesn't have transactions unless requested
@ -152,6 +135,9 @@ pub struct FluffyMissingTransactionsRequest {
/// The current blockchain height /// The current blockchain height
pub current_blockchain_height: u64, pub current_blockchain_height: u64,
/// The Tx Indices /// The Tx Indices
#[serde(default = "Vec::new")]
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(with = "container_as_blob")]
pub missing_tx_indices: Vec<u64>, pub missing_tx_indices: Vec<u64>,
} }
@ -160,6 +146,8 @@ pub struct FluffyMissingTransactionsRequest {
pub struct GetTxPoolCompliment { pub struct GetTxPoolCompliment {
/// Tx Hashes /// Tx Hashes
#[serde(default = "Vec::new")] #[serde(default = "Vec::new")]
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(with = "container_as_blob")]
pub hashes: Vec<[u8; 32]>, pub hashes: Vec<[u8; 32]>,
} }

View file

@ -11,3 +11,25 @@ pub(crate) fn default_zero<T: TryFrom<u8>>() -> T {
.map_err(|_| "Couldn't fit 0 into integer type!") .map_err(|_| "Couldn't fit 0 into integer type!")
.unwrap() .unwrap()
} }
pub(crate) mod serde_vec_bytes {
use serde::{Deserialize, Deserializer, Serializer};
use serde_bytes::ByteBuf;
pub fn deserialize<'de, D>(d: D) -> Result<Vec<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
Ok(Vec::<ByteBuf>::deserialize(d)?
.into_iter()
.map(ByteBuf::into_vec)
.collect())
}
pub fn serialize<S>(t: &[Vec<u8>], s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
s.collect_seq(t.iter())
}
}