rpc/types 32 bit support

This commit is contained in:
Boog900 2024-11-01 20:41:31 +00:00
parent 44981f2b24
commit 789cd4d9c3
No known key found for this signature in database
GPG key ID: 42AB1287CB0041C2
6 changed files with 23 additions and 30 deletions

1
Cargo.lock generated
View file

@ -740,7 +740,6 @@ version = "0.5.0"
dependencies = [ dependencies = [
"bytes", "bytes",
"cuprate-fixed-bytes", "cuprate-fixed-bytes",
"cuprate-helper",
"hex", "hex",
"paste", "paste",
"ref-cast", "ref-cast",

View file

@ -15,7 +15,6 @@ default = ["std"]
std = ["dep:thiserror", "bytes/std", "cuprate-fixed-bytes/std"] std = ["dep:thiserror", "bytes/std", "cuprate-fixed-bytes/std"]
[dependencies] [dependencies]
cuprate-helper = { workspace = true, default-features = false, features = ["cast"] }
cuprate-fixed-bytes = { workspace = true, default-features = false } cuprate-fixed-bytes = { workspace = true, default-features = false }
paste = "1.0.15" paste = "1.0.15"

View file

@ -69,8 +69,6 @@ use core::str::from_utf8 as str_from_utf8;
use bytes::{Buf, BufMut, Bytes, BytesMut}; use bytes::{Buf, BufMut, Bytes, BytesMut};
use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
pub mod container_as_blob; pub mod container_as_blob;
pub mod error; pub mod error;
mod io; mod io;
@ -89,7 +87,7 @@ pub use varint::{read_varint, write_varint};
/// this binary serialization format. /// this binary serialization format.
const HEADER: &[u8] = b"\x01\x11\x01\x01\x01\x01\x02\x01\x01"; const HEADER: &[u8] = b"\x01\x11\x01\x01\x01\x01\x02\x01\x01";
/// The maximum length a byte array (marked as a string) can be. /// The maximum length a byte array (marked as a string) can be.
const MAX_STRING_LEN_POSSIBLE: u64 = 2000000000; const MAX_STRING_LEN_POSSIBLE: usize = 2000000000;
/// The maximum depth of skipped objects. /// The maximum depth of skipped objects.
const MAX_DEPTH_OF_SKIPPED_OBJECTS: u8 = 20; const MAX_DEPTH_OF_SKIPPED_OBJECTS: u8 = 20;
/// The maximum number of fields in an object. /// The maximum number of fields in an object.
@ -248,7 +246,7 @@ pub fn write_bytes<T: AsRef<[u8]>, B: BufMut>(t: T, w: &mut B) -> Result<()> {
let bytes = t.as_ref(); let bytes = t.as_ref();
let len = bytes.len(); let len = bytes.len();
write_varint(usize_to_u64(len), w)?; write_varint(len, w)?;
if w.remaining_mut() < len { if w.remaining_mut() < len {
return Err(Error::IO("Not enough capacity to write bytes")); return Err(Error::IO("Not enough capacity to write bytes"));
@ -292,7 +290,7 @@ where
I: Iterator<Item = T> + ExactSizeIterator, I: Iterator<Item = T> + ExactSizeIterator,
B: BufMut, B: BufMut,
{ {
write_varint(usize_to_u64(iterator.len()), w)?; write_varint(iterator.len(), w)?;
for item in iterator { for item in iterator {
item.write(w)?; item.write(w)?;
} }
@ -337,7 +335,7 @@ fn skip_epee_value<B: Buf>(r: &mut B, skipped_objects: &mut u8) -> Result<()> {
if let Some(size) = marker.inner_marker.size() { if let Some(size) = marker.inner_marker.size() {
let bytes_to_skip = size let bytes_to_skip = size
.checked_mul(u64_to_usize(len)) .checked_mul(len.try_into()?)
.ok_or(Error::Value("List is too big".to_string()))?; .ok_or(Error::Value("List is too big".to_string()))?;
return advance(bytes_to_skip, r); return advance(bytes_to_skip, r);
}; };
@ -355,7 +353,7 @@ fn skip_epee_value<B: Buf>(r: &mut B, skipped_objects: &mut u8) -> Result<()> {
| InnerMarker::U8 | InnerMarker::U8
| InnerMarker::Bool => unreachable!("These types are constant size."), | InnerMarker::Bool => unreachable!("These types are constant size."),
InnerMarker::String => { InnerMarker::String => {
let len = u64_to_usize(read_varint(r)?); let len = read_varint(r)?;
advance(len, r)?; advance(len, r)?;
} }
InnerMarker::Object => { InnerMarker::Object => {

View file

@ -7,7 +7,6 @@ use core::fmt::Debug;
use bytes::{Buf, BufMut, Bytes, BytesMut}; use bytes::{Buf, BufMut, Bytes, BytesMut};
use cuprate_fixed_bytes::{ByteArray, ByteArrayVec}; use cuprate_fixed_bytes::{ByteArray, ByteArrayVec};
use cuprate_helper::cast::u64_to_usize;
use crate::{ use crate::{
io::{checked_read_primitive, checked_write_primitive}, io::{checked_read_primitive, checked_write_primitive},
@ -67,7 +66,7 @@ impl<T: EpeeObject> EpeeValue for Vec<T> {
"Marker is not sequence when a sequence was expected", "Marker is not sequence when a sequence was expected",
)); ));
} }
let len = u64_to_usize(read_varint(r)?); let len = read_varint(r)?;
let individual_marker = Marker::new(marker.inner_marker); let individual_marker = Marker::new(marker.inner_marker);
@ -168,8 +167,6 @@ impl EpeeValue for Vec<u8> {
return Err(Error::Format("Byte array exceeded max length")); return Err(Error::Format("Byte array exceeded max length"));
} }
let len = u64_to_usize(len);
if r.remaining() < len { if r.remaining() < len {
return Err(Error::IO("Not enough bytes to fill object")); return Err(Error::IO("Not enough bytes to fill object"));
} }
@ -206,8 +203,6 @@ impl EpeeValue for Bytes {
return Err(Error::Format("Byte array exceeded max length")); return Err(Error::Format("Byte array exceeded max length"));
} }
let len = u64_to_usize(len);
if r.remaining() < len { if r.remaining() < len {
return Err(Error::IO("Not enough bytes to fill object")); return Err(Error::IO("Not enough bytes to fill object"));
} }
@ -241,8 +236,6 @@ impl EpeeValue for BytesMut {
return Err(Error::Format("Byte array exceeded max length")); return Err(Error::Format("Byte array exceeded max length"));
} }
let len = u64_to_usize(len);
if r.remaining() < len { if r.remaining() < len {
return Err(Error::IO("Not enough bytes to fill object")); return Err(Error::IO("Not enough bytes to fill object"));
} }
@ -274,13 +267,11 @@ impl<const N: usize> EpeeValue for ByteArrayVec<N> {
return Err(Error::Format("Marker does not match expected Marker")); return Err(Error::Format("Marker does not match expected Marker"));
} }
let len = read_varint(r)?; let len = read_varint::<_, usize>(r)?;
if len > MAX_STRING_LEN_POSSIBLE { if len > MAX_STRING_LEN_POSSIBLE {
return Err(Error::Format("Byte array exceeded max length")); return Err(Error::Format("Byte array exceeded max length"));
} }
let len = u64_to_usize(len);
if r.remaining() < len { if r.remaining() < len {
return Err(Error::IO("Not enough bytes to fill object")); return Err(Error::IO("Not enough bytes to fill object"));
} }
@ -310,7 +301,7 @@ impl<const N: usize> EpeeValue for ByteArray<N> {
return Err(Error::Format("Marker does not match expected Marker")); return Err(Error::Format("Marker does not match expected Marker"));
} }
let len = u64_to_usize(read_varint(r)?); let len = read_varint::<_, usize>(r)?;
if len != N { if len != N {
return Err(Error::Format("Byte array has incorrect length")); return Err(Error::Format("Byte array has incorrect length"));
} }
@ -377,7 +368,7 @@ impl<const N: usize> EpeeValue for Vec<[u8; N]> {
)); ));
} }
let len = u64_to_usize(read_varint(r)?); let len = read_varint(r)?;
let individual_marker = Marker::new(marker.inner_marker); let individual_marker = Marker::new(marker.inner_marker);
@ -413,7 +404,7 @@ macro_rules! epee_seq {
)); ));
} }
let len = u64_to_usize(read_varint(r)?); let len = read_varint(r)?;
let individual_marker = Marker::new(marker.inner_marker.clone()); let individual_marker = Marker::new(marker.inner_marker.clone());

View file

@ -19,7 +19,7 @@ const FITS_IN_FOUR_BYTES: u64 = 2_u64.pow(32 - SIZE_OF_SIZE_MARKER) - 1;
/// assert_eq!(read_varint(&mut [254, 255, 255, 255].as_slice()).unwrap(), 1_073_741_823); /// assert_eq!(read_varint(&mut [254, 255, 255, 255].as_slice()).unwrap(), 1_073_741_823);
/// assert_eq!(read_varint(&mut [3, 0, 0, 0, 1, 0, 0, 0].as_slice()).unwrap(), 1_073_741_824); /// assert_eq!(read_varint(&mut [3, 0, 0, 0, 1, 0, 0, 0].as_slice()).unwrap(), 1_073_741_824);
/// ``` /// ```
pub fn read_varint<B: Buf>(r: &mut B) -> Result<u64> { pub fn read_varint<B: Buf, T: TryFrom<u64>>(r: &mut B) -> Result<T> {
if !r.has_remaining() { if !r.has_remaining() {
return Err(Error::IO("Not enough bytes to build VarInt")); return Err(Error::IO("Not enough bytes to build VarInt"));
} }
@ -35,7 +35,8 @@ pub fn read_varint<B: Buf>(r: &mut B) -> Result<u64> {
for i in 1..len { for i in 1..len {
vi |= u64::from(r.get_u8()) << (((i - 1) * 8) + 6); vi |= u64::from(r.get_u8()) << (((i - 1) * 8) + 6);
} }
Ok(vi)
vi.try_into().map_err(|_| Error::IO("VarInt is too big"))
} }
/// Write an epee variable sized number into `w`. /// Write an epee variable sized number into `w`.
@ -58,7 +59,12 @@ pub fn read_varint<B: Buf>(r: &mut B) -> Result<u64> {
/// assert_eq!(buf.as_slice(), expected_bytes); /// assert_eq!(buf.as_slice(), expected_bytes);
/// } /// }
/// ``` /// ```
pub fn write_varint<B: BufMut>(number: u64, w: &mut B) -> Result<()> { pub fn write_varint<B: BufMut, T: TryInto<u64>>(number: T, w: &mut B) -> Result<()> {
let number = number
.try_into()
.map_err(|_| "Tried to write a varint bigger than 64-bits")
.unwrap();
let size_marker = match number { let size_marker = match number {
0..=FITS_IN_ONE_BYTE => 0, 0..=FITS_IN_ONE_BYTE => 0,
64..=FITS_IN_TWO_BYTES => 1, 64..=FITS_IN_TWO_BYTES => 1,
@ -101,7 +107,7 @@ mod tests {
} }
fn assert_varint_val(mut varint: &[u8], val: u64) { fn assert_varint_val(mut varint: &[u8], val: u64) {
assert_eq!(read_varint(&mut varint).unwrap(), val); assert_eq!(read_varint::<_, u64>(&mut varint).unwrap(), val);
} }
#[test] #[test]

View file

@ -10,13 +10,13 @@ keywords = ["cuprate", "rpc", "types", "monero"]
[features] [features]
default = ["serde", "epee"] default = ["serde", "epee"]
serde = ["dep:serde", "cuprate-fixed-bytes/serde"] serde = ["dep:serde", "cuprate-fixed-bytes/serde", "cuprate-types/serde"]
epee = ["dep:cuprate-epee-encoding"] epee = ["dep:cuprate-epee-encoding", "cuprate-types/epee"]
[dependencies] [dependencies]
cuprate-epee-encoding = { workspace = true, optional = true } cuprate-epee-encoding = { workspace = true, optional = true }
cuprate-fixed-bytes = { workspace = true } cuprate-fixed-bytes = { workspace = true }
cuprate-types = { workspace = true, default-features = false, features = ["epee", "serde"] } cuprate-types = { workspace = true, default-features = false }
paste = { workspace = true } paste = { workspace = true }
serde = { workspace = true, optional = true } serde = { workspace = true, optional = true }