Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test z_getsubtreesbyindex using a lightwalletd gRPC request #7521

Merged
merged 6 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1795,6 +1795,12 @@ dependencies = [
"serde",
]

[[package]]
name = "hex-literal"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46"

[[package]]
name = "hmac"
version = "0.12.1"
Expand Down Expand Up @@ -5814,6 +5820,7 @@ dependencies = [
"dirs",
"futures",
"hex",
"hex-literal",
"howudoin",
"humantime-serde",
"hyper",
Expand Down
1 change: 1 addition & 0 deletions zebrad/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ tonic-build = { version = "0.10.0", optional = true }
[dev-dependencies]
abscissa_core = { version = "0.7.0", features = ["testing"] }
hex = "0.4.3"
hex-literal = "0.4.1"
jsonrpc-core = "18.0.0"
once_cell = "1.18.0"
regex = "1.9.5"
Expand Down
2 changes: 1 addition & 1 deletion zebrad/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn main() {
// The lightwalletd gRPC types don't use floats or complex collections,
// so we can derive `Eq` as well as the default generated `PartialEq` derive.
// This fixes `clippy::derive_partial_eq_without_eq` warnings.
.type_attribute(".", "#[derive(Eq)]")
.message_attribute(".", "#[derive(Eq)]")
.compile(
&["tests/common/lightwalletd/proto/service.proto"],
&["tests/common/lightwalletd/proto"],
Expand Down
25 changes: 25 additions & 0 deletions zebrad/tests/common/lightwalletd/proto/service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,27 @@ message TreeState {
string tree = 5; // sapling commitment tree state
}

enum ShieldedProtocol {
sapling = 0;
orchard = 1;
}

// Request type for `GetSubtreeRoots`
message GetSubtreeRootsArg {
uint32 startIndex = 1; // Index identifying where to start returning subtree roots.
ShieldedProtocol shieldedProtocol = 2; // Shielded protocol to return subtree roots for.
uint32 maxEntries = 3; // Maximum number of entries to return, or 0 for all entries.
}


// Response type for `GetSubtreeRoots`.
// The actual response contains a stream of `SubtreeRoot`s.
message SubtreeRoot {
bytes rootHash = 2; // The 32-byte Merkle root of the subtree.
bytes completingBlockHash = 3; // The hash of the block that completed this subtree.
uint64 completingBlockHeight = 4; // The height of the block that completed this subtree in the main chain.
}

// Results are sorted by height, which makes it easy to issue another
// request that picks up from where the previous left off.
message GetAddressUtxosArg {
Expand Down Expand Up @@ -175,6 +196,10 @@ service CompactTxStreamer {
// The block can be specified by either height or hash.
rpc GetTreeState(BlockID) returns (TreeState) {}

// Returns a stream of information about roots of subtrees of the Sapling
// and Orchard note commitment trees.
rpc GetSubtreeRoots(GetSubtreeRootsArg) returns (stream SubtreeRoot) {}

rpc GetAddressUtxos(GetAddressUtxosArg) returns (GetAddressUtxosReplyList) {}
rpc GetAddressUtxosStream(GetAddressUtxosArg) returns (stream GetAddressUtxosReply) {}

Expand Down
76 changes: 75 additions & 1 deletion zebrad/tests/common/lightwalletd/wallet_grpc_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
//! purposes.

use color_eyre::eyre::Result;
use hex_literal::hex;

use zebra_chain::{
block::Block,
Expand All @@ -50,7 +51,8 @@ use crate::common::{
sync::wait_for_zebrad_and_lightwalletd_sync,
wallet_grpc::{
connect_to_lightwalletd, Address, AddressList, BlockId, BlockRange, ChainSpec, Empty,
GetAddressUtxosArg, TransparentAddressBlockFilter, TxFilter,
GetAddressUtxosArg, GetSubtreeRootsArg, ShieldedProtocol,
TransparentAddressBlockFilter, TxFilter,
},
},
test_type::TestType::UpdateCachedState,
Expand Down Expand Up @@ -337,6 +339,78 @@ pub async fn run() -> Result<()> {
*zebra_test::vectors::SAPLING_TREESTATE_MAINNET_419201_STRING
);

// Call `z_getsubtreesbyindex` separately for

// ... Sapling.
let mut subtrees = rpc_client
.get_subtree_roots(GetSubtreeRootsArg {
start_index: 0u32,
shielded_protocol: ShieldedProtocol::Sapling.into(),
max_entries: 2u32,
})
.await?
.into_inner();

let mut counter = 0;
while let Some(subtree) = subtrees.message().await? {
match counter {
0 => {
assert_eq!(
subtree.root_hash,
hex!("754bb593ea42d231a7ddf367640f09bbf59dc00f2c1d2003cc340e0c016b5b13")
);
assert_eq!(subtree.completing_block_height, 558822u64);
}
1 => {
assert_eq!(
subtree.root_hash,
hex!("03654c3eacbb9b93e122cf6d77b606eae29610f4f38a477985368197fd68e02d")
);
assert_eq!(subtree.completing_block_height, 670209u64);
}
_ => {
panic!("The response from the `z_getsubtreesbyindex` RPC contains a wrong number of Sapling subtrees.")
}
}
counter += 1;
}
assert_eq!(counter, 2);

// ... Orchard.
let mut subtrees = rpc_client
.get_subtree_roots(GetSubtreeRootsArg {
start_index: 0u32,
shielded_protocol: ShieldedProtocol::Orchard.into(),
max_entries: 2u32,
})
.await?
.into_inner();

let mut counter = 0;
while let Some(subtree) = subtrees.message().await? {
match counter {
0 => {
assert_eq!(
subtree.root_hash,
hex!("d4e323b3ae0cabfb6be4087fec8c66d9a9bbfc354bf1d9588b6620448182063b")
);
assert_eq!(subtree.completing_block_height, 1707429u64);
}
1 => {
assert_eq!(
subtree.root_hash,
hex!("8c47d0ca43f323ac573ee57c90af4ced484682827248ca5f3eead95eb6415a14")
);
assert_eq!(subtree.completing_block_height, 1708132u64);
}
_ => {
panic!("The response from the `z_getsubtreesbyindex` RPC contains a wrong number of Orchard subtrees.")
}
}
counter += 1;
}
assert_eq!(counter, 2);

// Call `GetAddressUtxos` with the ZF funding stream address that will always have utxos
let utxos = rpc_client
.get_address_utxos(GetAddressUtxosArg {
Expand Down