From a6e91477c0807c552e4137a16f1801c2ae0c636f Mon Sep 17 00:00:00 2001 From: NanezX Date: Tue, 17 Oct 2023 04:45:10 -0400 Subject: [PATCH] wip: missing encode rain docs. added queries --- subgraph/tests/entities.rs | 19 ++-- subgraph/tests/utils/cbor.rs | 182 +++++++++++++++++++++++++++++++---- 2 files changed, 170 insertions(+), 31 deletions(-) diff --git a/subgraph/tests/entities.rs b/subgraph/tests/entities.rs index 5d866b6da..a240ea310 100644 --- a/subgraph/tests/entities.rs +++ b/subgraph/tests/entities.rs @@ -6,12 +6,12 @@ use anyhow::Result; use ethers::{signers::Signer, types::Bytes, utils::keccak256}; use subgraph::{wait, Query}; use utils::{ - cbor::{decode_rain_meta, RainMapDoc}, + cbor::{_encode_rain_meta, decode_rain_meta, RainMapDoc}, deploy::{get_orderbook, read_orderbook_meta}, }; #[tokio::main] -// #[test] +#[test] async fn orderbook_entity_test() -> Result<()> { let orderbook = get_orderbook().await.expect("cannot get OB"); @@ -117,7 +117,7 @@ async fn orderbook_entity_test() -> Result<()> { } #[tokio::main] -// #[test] +#[test] async fn rain_meta_v1_entity_test() -> Result<()> { // Always checking if OB is deployed, so we attemp to obtaing it let _ = get_orderbook().await.expect("cannot get OB"); @@ -145,17 +145,14 @@ async fn rain_meta_v1_entity_test() -> Result<()> { } #[test] -fn aver_test() -> Result<()> { +fn cbor_test() -> Result<()> { // Read meta from root repository (output from nix command) and convert to Bytes - // let ob_meta = read_orderbook_meta(); - - // let ob_meta = ::from_hex("0xff0a89c674ee7874A3011BFFE5FFB4A3FF2CDE0052946869735F69735F616E5F6578616D706C8502706170706C69636174696F6E2F6A736F6EA4011BFFE5FFB4A3FF2CDF0052746869735F69735F616E5F6578616D706C6502706170706C69636174696F6E2F63626F720362656E").expect("bad hex"); - - let ob_meta = ::from_hex("0xff0a89c674ee7874A2011BFFE5FFB4A3FF2CDE0052946869735F69735F616E5F6578616D706C8502706170706C69636174696F6E2F6A736F6EA4011BFFE5FFB4A3FF2CDF0052746869735F69735F616E5F6578616D706C6502706170706C69636174696F6E2F63626F720362656E").expect("bad hex"); + let ob_meta = read_orderbook_meta(); + // println!("ob_meta: {}", Bytes::from(ob_meta.clone())); - let output: Vec = decode_rain_meta(ob_meta)?; + let output: Vec = decode_rain_meta(ob_meta.into())?; - println!("output.len: {}", output.len()); + println!("output.len: {}\n", output.len()); Ok(()) } diff --git a/subgraph/tests/utils/cbor.rs b/subgraph/tests/utils/cbor.rs index 853eecbb6..efaf1c3d0 100644 --- a/subgraph/tests/utils/cbor.rs +++ b/subgraph/tests/utils/cbor.rs @@ -1,9 +1,9 @@ use super::MagicNumber; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Error, Result}; use ethers::types::{Bytes, U256}; use minicbor::data::Type; use minicbor::decode::{Decode, Decoder, Error as DecodeError}; -use minicbor::encode::{Encode, Encoder, Error as EncodeError}; +use minicbor::encode::{Encode, Encoder, Error as EncodeError, Write}; use serde::Deserialize; #[derive(Debug, Deserialize)] @@ -16,11 +16,28 @@ pub struct RainMapDoc { } impl RainMapDoc { + fn len(&self) -> usize { + // Starting on two (2) since payload and magic_number are not optional. + let mut count = 2; + + if self.content_type.is_some() { + count += 1; + } + if self.content_encoding.is_some() { + count += 1; + } + if self.content_language.is_some() { + count += 1; + } + + count + } + fn bad_meta_map() -> Result { - return Err(DecodeError::message("bad rain meta map")); + Err(DecodeError::message("bad rain meta map")) } fn no_meta_map() -> Result { - return Err(DecodeError::message("not rain meta map")); + Err(DecodeError::message("not rain meta map")) } } @@ -77,12 +94,38 @@ impl<'b> Decode<'b, ()> for RainMapDoc { content_language, }) } else { - // Since it's starting to decode and it's not a map, error. - return Self::no_meta_map(); + // Since it's starting to decode and it's not a map, return an error. + Self::no_meta_map() } } } +// impl Encode for RainMapDoc { +// fn encode( +// &self, +// enc: &mut Encoder, +// ctx: &mut C, +// ) -> Result<(), EncodeError> { +// println!("&self: {:?}\n", &self); + +// let doc_len = &self.len(); +// println!("doc_len: {:?}\n", doc_len); + +// enc.u8(20)?.end(); +// // enc.map(1) + +// // println!("xdd: {:?}", pave); +// // let averr = pave.ok(); +// // if pave.is_err() { +// // println!("pave failed"); +// // } else { +// // println!("pave is ok"); +// // } + +// Ok(()) +// } +// } + /// Receive a Rain Meta document with his prefix bytes and try to decode it usin cbor. pub fn decode_rain_meta(meta_data: Bytes) -> Result> { let (doc_magic_number, cbor_data) = meta_data.split_at(8); @@ -105,26 +148,125 @@ pub fn decode_rain_meta(meta_data: Bytes) -> Result> { return Ok(all_docs); } - return Err(anyhow!("Unable to decode - missing rain doc prefix")); + + Err(anyhow!("Unable to decode - missing rain doc prefix")) } -// pub fn decode_cbor(cbor_data: Vec) -> Result> { -// let mut decoder = Decoder::new(&cbor_data); +/// Receive a vec of RainMapDoc and try to encode it. +/// +/// **NOTE:** If the length of the Vec is greater than one (1), then the output will be +/// an cbor sequence. +pub fn _encode_rain_meta(docs: Vec) -> Result> { + let cbor_items: usize = docs.len(); + println!("cbor_items: {}", cbor_items); -// let mut all_docs: Vec = vec![]; + let mut main_buffer: Vec = Vec::new(); + let mut buffer = [0u8; 4]; + // let mut buffer = [0u8; 128]; -// while decoder.position() < decoder.input().len() { -// // TODO: Create error response -// let doc: RainMapDoc = decoder.decode().unwrap(); + let mut encoder = Encoder::new(&mut buffer[..]); -// all_docs.push(doc); -// } + let aver = encoder.map(1).unwrap().u8(0).unwrap().u8(200).unwrap(); -// return Ok(all_docs); -// } + println!("xd_0: {}", aver.writer().len()); + aver.writer_mut().fill(99u8); + + println!("xd_1: {}", aver.writer().len()); + + println!("buffer: {}", Bytes::from(buffer)); + + // let mut main_buffer: Vec = Vec::new(); + // // let mut encoder: Encoder<&mut [u8]> = Encoder::new(&mut main_buffer); + + // for doc_index in 0..cbor_items { + // let mut buffer = [0u8; 128]; + + // let mut encoder = Encoder::new(&mut buffer[..]); + + // let doc = docs.get(doc_index).unwrap(); + // let doc_len = doc.len() as u8; + + // // Creating the map based on the rain document length + // encoder.map(doc_len.into()).unwrap(); + + // for key in 0..doc_len { + // match key { + // 0 => { + // // + // encoder.u8(key); + // } + + // // 1 => magic_number = Some(d.u64()?.into()), + + // // 2 => content_type = Some(d.str()?.to_string()), + + // // 3 => content_encoding = Some(d.str()?.to_string()), + + // // 4 => content_language = Some(d.str()?.to_string()), + + // // Does not allow other keys than the defnied by the metadata spec. + // // See: https://github.com/rainprotocol/specs/blob/main/metadata-v1.md#header-name-aliases-cbor-map-keys + // _ => { + // // + // } + // } + // } + + // // + // } + + // let mut buffer = Vec::new(); + // let mut encoder: Encoder<&mut [u8]> = Encoder::new(&mut buffer); + + // // Iterate over your data chunks and encode them + // for chunk in data_chunks { + // encoder.encode(chunk)?; + // } + + // let response = encoder.encode(single_doc); + + // println!("buffer_end: {}", Bytes::from(buffer)); + + // encoder. + + // Encoder::encode(&mut self, single_doc); + + // let single_doc_0 = docs.get(0).unwrap(); + // let size_0: usize = single_doc_0.len(); + // println!("size_0: {}", size_0); + + // let single_doc_1 = docs.get(1).unwrap(); + // let size_1: usize = single_doc_1.len(); + // println!("size_1: {}", size_1); + // Encoder::map(&mut self, len) + + // for _ in 0..cbor_items { + // // + // } -/// Receive a vec of RainMapDoc and try to encode it. -pub fn _encode_rain_meta(_docs: Vec) -> Result> { - // Ok([0].to_vec()) } + +// TODO: Use this for recursive encode the RainDocs +// +// let mut data: [u8; 1024] = [1; 1024]; // Example filled array +// +// data[data.len() - 1] = 0; +// data[data.len() - 2] = 0; +// println!("1: {:?}", data.len()); +// +// let resp = remove_trailing_zeros(&data); +// println!("2: {:?}", resp.unwrap().len()); +fn _remove_trailing_zeros(arr: &[u8]) -> Option> { + // Find the position of the last non-zero element + let length = arr.iter().rposition(|&x| x != 0).map(|pos| pos + 1); + + match length { + Some(len) => { + // Create a new Vec with the non-zero data + let new_vec: Vec = arr[0..len].to_vec(); + Some(new_vec) + } + None => None, // All elements are zeros + } +}