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",
"hex",
"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-wire",
"multiexp",
@ -1163,6 +1163,16 @@ dependencies = [
"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]]
name = "monero-epee-bin-serde"
version = "1.0.1"
@ -1245,7 +1255,7 @@ version = "0.1.0"
dependencies = [
"hex",
"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_bytes",
"thiserror",

View file

@ -9,7 +9,7 @@ repository = "https://github.com/SyntheticBird45/cuprate/tree/main/net/monero-wi
[dependencies]
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_bytes = "0.11"
thiserror = "1"

View file

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

View file

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