Skip to content

Commit

Permalink
fixed txid conversion, get_block_range no works
Browse files Browse the repository at this point in the history
  • Loading branch information
idky137 committed Jun 13, 2024
1 parent b72ecc6 commit f78ac42
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 95 deletions.
31 changes: 17 additions & 14 deletions zingo-rpc/src/blockcache/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::{
blockcache::{
transaction::FullTransaction,
utils::{
read_bytes, read_i32, read_u32, read_zcash_script_i64, ParseError, ParseFromSlice,
display_txids_to_server, read_bytes, read_i32, read_u32, read_zcash_script_i64,
ParseError, ParseFromSlice,
},
},
jsonrpc::{connector::JsonRpcConnector, primitives::GetBlockResponse},
Expand Down Expand Up @@ -227,9 +228,6 @@ impl ParseFromSlice for FullBlock {
let (remaining_data, block_header_data) =
BlockHeaderData::parse_from_slice(&data[cursor.position() as usize..], None)?;
cursor.set_position(data.len() as u64 - remaining_data.len() as u64);

println!("\nBlockHeaderData: {:?}\n", block_header_data);

let tx_count = CompactSize::read(&mut cursor)?;
if txid.len() != tx_count as usize {
return Err(ParseError::InvalidData(format!(
Expand All @@ -253,8 +251,6 @@ impl ParseFromSlice for FullBlock {
transactions.push(tx);
remaining_data = new_remaining_data;
}
println!("\nTransactions: {:?}\n", transactions);

let block_height = Self::get_block_height(&transactions)?;
let block_hash = block_header_data.get_hash()?;

Expand Down Expand Up @@ -330,6 +326,7 @@ impl FullBlock {
})
.collect::<Result<Vec<_>, _>>()?;

// NOTE: LightWalletD doesnt return a compact block header, however this could be used to return data if required.
// let header = self.hdr.raw_block_header.to_binary()?;
let header = Vec::new();

Expand Down Expand Up @@ -378,6 +375,14 @@ pub async fn get_block_from_node(
Some("xxxxxx".to_string()),
)
.await;
println!(
"\ntest get_block_response: {:?}\n",
zebrad_client
.get_block(height.to_string(), Some(1))
.await
.unwrap()
);

let block_1 = zebrad_client.get_block(height.to_string(), Some(1)).await;
match block_1 {
Ok(GetBlockResponse::Object {
Expand All @@ -402,14 +407,12 @@ pub async fn get_block_from_node(
"Received object block type, this should not be possible here.".to_string(),
));
}
Ok(GetBlockResponse::Raw(block_hex)) => {
Ok(FullBlock::parse_to_compact(
block_hex.as_ref(),
Some(tx.into_iter().map(|s| s.into_bytes()).collect()),
0, //trees.sapling as u32,
2, //trees.orchard as u32,
)?)
}
Ok(GetBlockResponse::Raw(block_hex)) => Ok(FullBlock::parse_to_compact(
block_hex.as_ref(),
Some(display_txids_to_server(tx)),
trees.sapling.size as u32,
trees.orchard.size as u32,
)?),
Err(e) => {
return Err(e.into());
}
Expand Down
17 changes: 17 additions & 0 deletions zingo-rpc/src/blockcache/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,20 @@ pub fn read_zcash_script_i64(cursor: &mut Cursor<&[u8]>) -> Result<i64, ParseErr
}
}
}

/// Takes a vec of big endian hex encoded txids and returns them as a vec of little endian raw bytes.
pub fn display_txids_to_server(txids: Vec<String>) -> Vec<Vec<u8>> {
txids
.iter()
.map(|txid| {
txid.as_bytes()
.chunks(2)
.map(|chunk| {
let hex_pair = std::str::from_utf8(chunk).unwrap();
u8::from_str_radix(hex_pair, 16).unwrap()
})
.rev()
.collect()
})
.collect()
}
2 changes: 0 additions & 2 deletions zingo-rpc/src/jsonrpc/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,6 @@ impl JsonRpcConnector {
///
/// - `hash_or_height`: (string, required, example="1") The hash or height for the block to be returned.
/// - `verbosity`: (number, optional, default=1, example=1) 0 for hex encoded data, 1 for a json object, and 2 for json object with transaction data.
///
/// NOTE: Currently unused by Zingo-Proxy and untested!
pub async fn get_block(
&self,
hash_or_height: String,
Expand Down
19 changes: 16 additions & 3 deletions zingo-rpc/src/jsonrpc/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,26 @@ impl AsRef<[u8]> for ProxySerializedBlock {
}
}

/// Sapling note commitment tree information.
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct ProxyTrees {
/// Commitment tree size.
pub size: u64,
}

// /// Orchard note commitment tree information.
// #[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
// pub struct ProxyOrchardTrees {
// pub size: u64,
// }

/// Information about the note commitment trees.
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct ProxyBlockTrees {
/// Sapling commitment tree size.
pub sapling: u64,
pub sapling: ProxyTrees,
/// Orchard commitment tree size.
pub orchard: u64,
pub orchard: ProxyTrees,
}

/// Contains the hex-encoded hash of the sent transaction.
Expand Down Expand Up @@ -215,7 +228,7 @@ pub enum GetBlockResponse {
tx: Vec<String>,

/// Information about the note commitment trees.
trees: zebra_rpc::methods::GetBlockTrees,
trees: ProxyBlockTrees, //zebra_rpc::methods::GetBlockTrees,
},
}

Expand Down
152 changes: 76 additions & 76 deletions zingo-rpc/src/rpc/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,82 +203,82 @@ impl CompactTxStreamer for ProxyClient {

/// Server streaming response type for the GetBlockRange method.
#[doc = "Server streaming response type for the GetBlockRange method."]
type GetBlockRangeStream = tonic::Streaming<CompactBlock>;
// type GetBlockRangeStream = std::pin::Pin<Box<CompactBlockStream>>;

// /// Return a list of consecutive compact blocks.
// ///
// /// TODO: This implementation is slow. An internal block cache should be implemented that this rpc, along with the get_block rpc, can rely on.
// /// - add get_block function that queries the block cache for block and calls get_block_from_node to fetch block if not present.
// fn get_block_range<'life0, 'async_trait>(
// &'life0 self,
// request: tonic::Request<zcash_client_backend::proto::service::BlockRange>,
// ) -> core::pin::Pin<
// Box<
// dyn core::future::Future<
// Output = std::result::Result<
// tonic::Response<Self::GetBlockRangeStream>,
// tonic::Status,
// >,
// > + core::marker::Send
// + 'async_trait,
// >,
// >
// where
// 'life0: 'async_trait,
// Self: 'async_trait,
// {
// println!("@zingoproxyd: Received call of get_block_range.");
// let zebrad_uri = self.zebrad_uri.clone();
// Box::pin(async move {
// let blockrange = request.into_inner();
// let mut start = blockrange
// .start
// .map(|s| s.height as u32)
// .ok_or(tonic::Status::invalid_argument("Start block not specified"))?;
// let mut end = blockrange
// .end
// .map(|e| e.height as u32)
// .ok_or(tonic::Status::invalid_argument("End block not specified"))?;
// if start > end {
// (start, end) = (end, start);
// }

// let (channel_tx, channel_rx) = tokio::sync::mpsc::channel(32);
// tokio::spawn(async move {
// for height in start..end {
// let compact_block = get_block_from_node(&zebrad_uri, &height).await;
// match compact_block {
// Ok(block) => {
// println!("\nCompact Block:\n{:?}\n", block);

// if channel_tx.send(Ok(block)).await.is_err() {
// break;
// }
// }
// Err(e) => {
// if channel_tx
// .send(Err(tonic::Status::internal(e.to_string())))
// .await
// .is_err()
// {
// break;
// }
// }
// }
// }
// });
// let output_stream = CompactBlockStream::new(channel_rx);
// let stream_boxed = Box::pin(output_stream);
// Ok(tonic::Response::new(stream_boxed))
// })
// }
define_grpc_passthrough!(
fn get_block_range(
&self,
request: tonic::Request<BlockRange>,
) -> Self::GetBlockRangeStream
);
// type GetBlockRangeStream = tonic::Streaming<CompactBlock>;
type GetBlockRangeStream = std::pin::Pin<Box<CompactBlockStream>>;

/// Return a list of consecutive compact blocks.
///
/// TODO: This implementation is slow. An internal block cache should be implemented that this rpc, along with the get_block rpc, can rely on.
/// - add get_block function that queries the block cache for block and calls get_block_from_node to fetch block if not present.
fn get_block_range<'life0, 'async_trait>(
&'life0 self,
request: tonic::Request<zcash_client_backend::proto::service::BlockRange>,
) -> core::pin::Pin<
Box<
dyn core::future::Future<
Output = std::result::Result<
tonic::Response<Self::GetBlockRangeStream>,
tonic::Status,
>,
> + core::marker::Send
+ 'async_trait,
>,
>
where
'life0: 'async_trait,
Self: 'async_trait,
{
println!("@zingoproxyd: Received call of get_block_range.");
let zebrad_uri = self.zebrad_uri.clone();
Box::pin(async move {
let blockrange = request.into_inner();
let mut start = blockrange
.start
.map(|s| s.height as u32)
.ok_or(tonic::Status::invalid_argument("Start block not specified"))?;
let mut end = blockrange
.end
.map(|e| e.height as u32)
.ok_or(tonic::Status::invalid_argument("End block not specified"))?;
if start > end {
(start, end) = (end, start);
}

let (channel_tx, channel_rx) = tokio::sync::mpsc::channel(32);
tokio::spawn(async move {
for height in start..end {
let compact_block = get_block_from_node(&zebrad_uri, &height).await;
match compact_block {
Ok(block) => {
println!("\nCompact Block:\n{:?}\n", block);

if channel_tx.send(Ok(block)).await.is_err() {
break;
}
}
Err(e) => {
if channel_tx
.send(Err(tonic::Status::internal(e.to_string())))
.await
.is_err()
{
break;
}
}
}
}
});
let output_stream = CompactBlockStream::new(channel_rx);
let stream_boxed = Box::pin(output_stream);
Ok(tonic::Response::new(stream_boxed))
})
}
// define_grpc_passthrough!(
// fn get_block_range(
// &self,
// request: tonic::Request<BlockRange>,
// ) -> Self::GetBlockRangeStream
// );

/// Server streaming response type for the GetBlockRangeNullifiers method.
#[doc = " Server streaming response type for the GetBlockRangeNullifiers method."]
Expand Down

0 comments on commit f78ac42

Please sign in to comment.