Skip to content

Commit

Permalink
fixed block range inversion bug, possible bug with sapling spend / ou…
Browse files Browse the repository at this point in the history
…tput return in parse_from_slice, error in parse_full_block
  • Loading branch information
idky137 committed Jun 13, 2024
1 parent f78ac42 commit 0e612aa
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 103 deletions.
11 changes: 6 additions & 5 deletions integration-tests/tests/integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,8 @@ mod wallet {
TestManager::launch(online.clone()).await;
let zingo_client = test_manager.build_lightclient().await;

test_manager.regtest_manager.generate_n_blocks(1).unwrap();
test_manager.regtest_manager.generate_n_blocks(2).unwrap();
zingo_client.do_sync(false).await.unwrap();

// std::thread::sleep(std::time::Duration::from_secs(10));

zingo_client
.do_send(vec![(
&zingolib::get_base_address!(zingo_client, "sapling"),
Expand All @@ -62,12 +59,16 @@ mod wallet {
)])
.await
.unwrap();
test_manager.regtest_manager.generate_n_blocks(1).unwrap();
test_manager.regtest_manager.generate_n_blocks(2).unwrap();
zingo_client.do_sync(false).await.unwrap();
// test_manager.regtest_manager.generate_n_blocks(1).unwrap();
// zingo_client.do_sync(false).await.unwrap();

let balance = zingo_client.do_balance().await;
println!("@zingoproxytest: zingo_client balance: \n{:#?}.", balance);

assert_eq!(balance.sapling_balance.unwrap(), 250_000);

drop_test_manager(
Some(test_manager.temp_conf_dir.path().to_path_buf()),
regtest_handler,
Expand Down
22 changes: 10 additions & 12 deletions zingo-rpc/src/blockcache/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,17 @@ impl FullBlock {

/// Decodes a hex encoded zcash full block into a FullBlock struct.
pub fn parse_full_block(data: &[u8], txid: Option<Vec<Vec<u8>>>) -> Result<Self, ParseError> {
println!(
"\nIn parse_full_block with inputs:\ndata: {:?}\n\ntxid: {:?}\n",
data, txid
);
let (remaining_data, full_block) = Self::parse_from_slice(data, txid)?;
if remaining_data.len() != 0 {
return Err(ParseError::InvalidData(
"Error decoding full block, data ramaining: ({remaining_data})".to_string(),
));
return Err(ParseError::InvalidData(format!(
"Error decoding full block - Data Remaining: ({:?}) - Compact Block: ({:?})",
remaining_data,
full_block.to_compact(0, 0)
)));
}
Ok(full_block)
}
Expand All @@ -326,7 +332,7 @@ impl FullBlock {
})
.collect::<Result<Vec<_>, _>>()?;

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

Expand Down Expand Up @@ -375,14 +381,6 @@ 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 Down
2 changes: 1 addition & 1 deletion zingo-rpc/src/blockcache/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const OP_1_NEGATE: u8 = 0x4f;
const OP_1: u8 = 0x51;
const OP_16: u8 = 0x60;

/// Reads and interprets a Zcash (Bitcoin)-custom compact integer encoding used for int64 numbers in scripts.
/// Reads and interprets a Zcash (Bitcoin) custom compact integer encoding used for int64 numbers in scripts.
pub fn read_zcash_script_i64(cursor: &mut Cursor<&[u8]>) -> Result<i64, ParseError> {
let first_byte = read_bytes(cursor, 1, "Error reading first byte in i64 script hash")?[0];

Expand Down
12 changes: 3 additions & 9 deletions zingo-rpc/src/jsonrpc/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,24 +179,18 @@ impl AsRef<[u8]> for ProxySerializedBlock {

/// Sapling note commitment tree information.
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct ProxyTrees {
pub struct ProxyTree {
/// 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: ProxyTrees,
pub sapling: ProxyTree,
/// Orchard commitment tree size.
pub orchard: ProxyTrees,
pub orchard: ProxyTree,
}

/// Contains the hex-encoded hash of the sent transaction.
Expand Down
155 changes: 79 additions & 76 deletions zingo-rpc/src/rpc/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,82 +203,85 @@ 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.
// /// TODO: Add 30s timeout.
// 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);
// }
// println!(
// "\n Fetching Blocks in Range - Start: {}, End: {}\n",
// start, end
// );
// let (channel_tx, channel_rx) = tokio::sync::mpsc::channel(32);
// tokio::spawn(async move {
// for height in (start..=end).rev() {
// let compact_block = get_block_from_node(&zebrad_uri, &height).await;
// match compact_block {
// Ok(block) => {
// println!("\nCompact Block at Height {}: {:?}\n", height, 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 0e612aa

Please sign in to comment.