Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
b715dce
Add ZValidateAddressResponse struct for RPC responses
nachog00 Jun 18, 2025
e584359
Merge branch 'dev' into implement-z_validateaddress
zancas Jun 27, 2025
ec88ac8
Merge branch 'dev' into implement-z_validateaddress
dorianvp Oct 19, 2025
80c7a84
chore(`z_validateaddress`): initial structs
dorianvp Oct 19, 2025
e122406
chore(`z_validateaddress`): initial impl
dorianvp Oct 19, 2025
0716b4d
chore(`z_validateaddress`): expose endpoint
dorianvp Oct 19, 2025
657055f
docs(`z_validateaddress`): add doc comments
dorianvp Oct 21, 2025
3a48403
chore(`z_validateaddress`): merge variants into `Known`
dorianvp Oct 21, 2025
a2a4257
chore(`z_validateaddress`): use cleaner API & some tests
dorianvp Oct 22, 2025
78e8ad0
Merge branch 'dev' into implement-z_validateaddress
dorianvp Oct 22, 2025
728a0cc
chore(`z_validateaddress`): fmt
dorianvp Oct 22, 2025
3afa4f0
fix(`z_validateaddress`): `fetch_service` test
dorianvp Oct 22, 2025
41570e9
fix(`z_validateaddress`): add remaining tests
dorianvp Oct 22, 2025
dffa47e
fix(`z_validateaddress`): comment out sprout validation
dorianvp Oct 23, 2025
a4f72c1
fix(`z_validateaddress`): `fetch_service` test
dorianvp Oct 23, 2025
73bb823
fix(`z_validateaddress`): address comments
dorianvp Oct 23, 2025
7d84149
fix(`z_validateaddress`): add error type
dorianvp Oct 23, 2025
4c6aac1
Merge branch 'dev' into implement-z_validateaddress
dorianvp Oct 24, 2025
ad09e27
Merge branch 'dev' into implement-z_validateaddress
dorianvp Oct 29, 2025
8a0a588
chore(`z_validateaddress`): remove comment
dorianvp Oct 29, 2025
2c25bfd
fix(`z_validateaddress`): address comments
dorianvp Oct 30, 2025
e23ba87
Merge branch 'dev' into implement-z_validateaddress
dorianvp Oct 30, 2025
47b6756
add testvectors
dorianvp Oct 30, 2025
bf12e1a
Merge branch 'dev' into implement-z_validateaddress
dorianvp Oct 30, 2025
4380d4f
fix: post-merge fixes
dorianvp Oct 30, 2025
f6436a0
docs(`z_validateaddress`): better doc-comments
dorianvp Oct 31, 2025
688c2e9
Merge branch 'dev' into implement-z_validateaddress
dorianvp Oct 31, 2025
1c1b653
chore(`z_validateaddress`): use testvectors
dorianvp Oct 31, 2025
f51301c
chore(`z_validateaddress`): rename `ZValidateAddress` to `ZValidateAd…
dorianvp Oct 31, 2025
bd67120
chore(`z_validateaddress`): stricter invalid deser
dorianvp Oct 31, 2025
95f6648
chore(`z_validateaddress`): fix doc comment
dorianvp Oct 31, 2025
3b4d080
chore(`z_validateaddress`): default `is_mine` to `IsMine::Unknown`
dorianvp Nov 1, 2025
6765f98
chore(`z_validateaddress`): fix tests
dorianvp Nov 1, 2025
754230f
Merge branch 'dev' into implement-z_validateaddress
zancas Nov 4, 2025
2c09e29
Merge branch 'dev' into implement-z_validateaddress
dorianvp Nov 4, 2025
d5d7202
chore(`z_validateaddress`): dry up tests
dorianvp Nov 4, 2025
c6f9319
chore(`z_validateaddress`): rename for clarity
dorianvp Nov 4, 2025
5e01626
Merge branch 'dev' into implement-z_validateaddress
dorianvp Nov 5, 2025
049b20f
Further helperized run_z_validate_suite, expposing inconsistencies.
fluidvanadium Nov 5, 2025
755f504
Dbg removed.
fluidvanadium Nov 5, 2025
68d45e1
cargo clippy --fix --tests --all-features
fluidvanadium Nov 5, 2025
075a8e3
trailing whitespace clipper
fluidvanadium Nov 5, 2025
d480b3a
cargo fmt
fluidvanadium Nov 5, 2025
ff9a4a8
add tracing to integration tests
fluidvanadium Nov 5, 2025
30ddea4
Use qualified paths instead of single-use imports.
fluidvanadium Nov 5, 2025
809674c
Added tracing debug message.
fluidvanadium Nov 5, 2025
601d437
Zebra now uses diversifier and diversified_transmission_key.
fluidvanadium Nov 5, 2025
73c76ab
Add tracing.
fluidvanadium Nov 5, 2025
ea627f0
Merge branch 'dev' into implement-z_validateaddress
dorianvp Nov 5, 2025
bcbd2c2
Merge branch 'dev' into implement-z_validateaddress
dorianvp Nov 5, 2025
547a5aa
Fixed conflicts.
fluidvanadium Nov 28, 2025
395dbfc
Fix check fail on deprecation.
fluidvanadium Nov 28, 2025
5b57d4d
Merge branch 'dev' into implement-z_validateaddress
fluidvanadium Dec 1, 2025
356d01b
Updated test to use upgraded framework.
fluidvanadium Dec 1, 2025
727a45d
Merge branch 'dev' into implement-z_validateaddress
fluidvanadium Dec 8, 2025
73f9180
Removed IsMine enum.
fluidvanadium Dec 8, 2025
78d0586
Configured tests to expect no ismine parameter.
fluidvanadium Dec 9, 2025
7be2b57
Separated validate sapling behavior under test.
fluidvanadium Dec 9, 2025
af15f87
Merged dev
fluidvanadium Jan 16, 2026
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
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ edition = { workspace = true }
license = { workspace = true }
version = { workspace = true }

[dependencies]
zaino-fetch = { workspace = true }
zaino-testutils = { workspace = true }
tracing.workspace = true

[dev-dependencies]
anyhow = { workspace = true }

Expand All @@ -23,7 +28,7 @@ zaino-state = { workspace = true, features = ["test_dependencies"] }
zebra-chain.workspace = true
zebra-state.workspace = true
zebra-rpc.workspace = true
zip32 = {workspace = true}
zip32 = { workspace = true }

core2 = { workspace = true }
prost = { workspace = true }
Expand Down
131 changes: 131 additions & 0 deletions integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,132 @@
//! Helpers for integration-tests go here.
//!
//! This crate also exposes test-vectors.

pub mod rpc {
pub mod json_rpc {
pub const VALID_P2PKH_ADDRESS: &str = "tmVqEASZxBNKFTbmASZikGa5fPLkd68iJyx";
pub const VALID_P2SH_ADDRESS: &str = "t2MjoXQ2iDrjG9QXNZNCY9io8ecN4FJYK1u";

pub const VALID_SPROUT_ADDRESS: &str = "ztfhKyLouqi8sSwjRm4YMQdWPjTmrJ4QgtziVQ1Kd1e9EsRHYKofjoJdF438FwcUQnix8yrbSrzPpJJNABewgNffs5d4YZJ";
pub const VALID_PAYING_KEY: &str =
"c8e8797f1fb5e9cf6b2d000177c5994119279a2629970a4f669aed1362a4cca5";
pub const VALID_TRANSMISSION_KEY: &str =
"480f78d61bdd7fc4b4edeef9f6305b29753057ab1008d42ded1a3364dac2d83c";

pub const VALID_SAPLING_ADDRESS: &str = "zregtestsapling1jalqhycwumq3unfxlzyzcktq3n478n82k2wacvl8gwfxk6ahshkxmtp2034qj28n7gl92ka5wca";
pub const VALID_DIVERSIFIER: &str = "977e0b930ee6c11e4d26f8";
pub const VALID_DIVERSIFIED_TRANSMISSION_KEY: &str =
"553ef2f328096a7c2aac6dec85b76b6b9243e733dc9db2eacce3eb8c60592c88";

pub const VALID_UNIFIED_ADDRESS: &str = "uregtest1njwg60x0jarhyuuxrcdvw854p68cgdfe85822lmclc7z9vy9xqr7t49n3d97k2dwlee82skwwe0ens0rc06p4vr04tvd3j9ckl3qry83ckay4l4ngdq9atg7vuj9z58tfjs0mnsgyrnprtqfv8almu564z498zy6tp2aa569tk8fyhdazyhytel2m32awe4kuy6qq996um3ljaajj36";
}

pub mod z_validate_address {
use std::future::Future;

use zaino_fetch::jsonrpsee::response::z_validate_address::{
KnownZValidateAddress, ValidZValidateAddress, ZValidateAddressResponse,
};
use zaino_testutils::ValidatorKind;

use crate::rpc::json_rpc::{
VALID_DIVERSIFIED_TRANSMISSION_KEY, VALID_DIVERSIFIER, VALID_P2PKH_ADDRESS,
VALID_P2SH_ADDRESS, VALID_SAPLING_ADDRESS, VALID_UNIFIED_ADDRESS,
};

pub fn assert_known_valid_eq(
resp: ZValidateAddressResponse,
expected: ValidZValidateAddress,
label: &str,
) {
match resp {
ZValidateAddressResponse::Known(KnownZValidateAddress::Valid(actual)) => {
assert_eq!(actual, expected, "mismatch for {label}")
}
other => panic!(
"Unexpected ZValidateAddressResponse for {label}: {:#?}",
other
),
}
}

pub async fn run_z_validate_suite<F, Fut>(rpc_call: &F)
where
// Any callable that takes an address and returns the response (you can unwrap inside)
F: Fn(String) -> Fut,
Fut: Future<Output = ZValidateAddressResponse>,
{
// P2PKH
let expected_p2pkh = ValidZValidateAddress::p2pkh(VALID_P2PKH_ADDRESS.to_string());
assert_known_valid_eq(
rpc_call(VALID_P2PKH_ADDRESS.to_string()).await,
expected_p2pkh,
"P2PKH",
);

// P2SH
let expected_p2sh = ValidZValidateAddress::p2sh(VALID_P2SH_ADDRESS.to_string());
assert_known_valid_eq(
rpc_call(VALID_P2SH_ADDRESS.to_string()).await,
expected_p2sh,
"P2SH",
);

// Note: It could be the case that Zaino needs to support Sprout. For now, it's been disabled.

// let expected_sprout = ZValidateAddress::sprout("ztfhKyLouqi8sSwjRm4YMQdWPjTmrJ4QgtziVQ1Kd1e9EsRHYKofjoJdF438FwcUQnix8yrbSrzPpJJNABewgNffs5d4YZJ".to_string(), "c8e8797f1fb5e9cf6b2d000177c5994119279a2629970a4f669aed1362a4cca5".to_string(), "480f78d61bdd7fc4b4edeef9f6305b29753057ab1008d42ded1a3364dac2d83c".to_string());

// let fs_sprout = zcashd_subscriber
// .z_validate_address("ztfhKyLouqi8sSwjRm4YMQdWPjTmrJ4QgtziVQ1Kd1e9EsRHYKofjoJdF438FwcUQnix8yrbSrzPpJJNABewgNffs5d4YZJ".to_string())
// .await
// .unwrap();

// assert_eq!(fs_sprout, expected_sprout);

// Sapling (differs by validator)

// Unified (differs by validator)
let expected_unified =
ValidZValidateAddress::unified(VALID_UNIFIED_ADDRESS.to_string());
assert_known_valid_eq(
rpc_call(VALID_UNIFIED_ADDRESS.to_string()).await,
expected_unified,
"Unified",
);

// Invalids
let by_len = rpc_call("t1123456789ABCDEFGHJKLMNPQRSTUVWXY".to_string()).await;
let all_zeroes = rpc_call("t1000000000000000000000000000000000".to_string()).await;
assert_eq!(by_len, ZValidateAddressResponse::invalid());
assert_eq!(all_zeroes, ZValidateAddressResponse::invalid());
}

pub async fn run_z_validate_sapling<F, Fut>(rpc_call: &F)
where
// Any callable that takes an address and returns the response (you can unwrap inside)
F: Fn(String) -> Fut,
Fut: Future<Output = ZValidateAddressResponse>,
{
// Sapling (differs by validator)
let expected_sapling = ValidZValidateAddress::sapling(
VALID_SAPLING_ADDRESS.to_string(),
Some(VALID_DIVERSIFIER.to_string()),
Some(VALID_DIVERSIFIED_TRANSMISSION_KEY.to_string()),
);
}

pub async fn run_z_validate_sapling_legacy<F, Fut>(rpc_call: &F)
where
// Any callable that takes an address and returns the response (you can unwrap inside)
F: Fn(String) -> Fut,
Fut: Future<Output = ZValidateAddressResponse>,
{
// Sapling (differs by validator)
let expected_sapling = ValidZValidateAddress::sapling(
VALID_SAPLING_ADDRESS.to_string(),
None::<String>,
None::<String>,
);
}
}
}
48 changes: 48 additions & 0 deletions integration-tests/tests/fetch_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,44 @@ async fn fetch_service_validate_address<V: ValidatorExt>(validator: &ValidatorKi
test_manager.close().await;
}

/// This test only runs validation for regtest addresses.
/// The following addresses were generated with `zcashd` on regtest:
///
/// - P2PKH: `tmVqEASZxBNKFTbmASZikGa5fPLkd68iJyx`
/// - P2SH: `t2MjoXQ2iDrjG9QXNZNCY9io8ecN4FJYK1u`
/// - Sprout: `ztfhKyLouqi8sSwjRm4YMQdWPjTmrJ4QgtziVQ1Kd1e9EsRHYKofjoJdF438FwcUQnix8yrbSrzPpJJNABewgNffs5d4YZJ`
/// - Sapling: `zregtestsapling1jalqhycwumq3unfxlzyzcktq3n478n82k2wacvl8gwfxk6ahshkxmtp2034qj28n7gl92ka5wca`
/// - unified: `uregtest1njwg60x0jarhyuuxrcdvw854p68cgdfe85822lmclc7z9vy9xqr7t49n3d97k2dwlee82skwwe0ens0rc06p4vr04tvd3j9ckl3qry83ckay4l4ngdq9atg7vuj9z58tfjs0mnsgyrnprtqfv8almu564z498zy6tp2aa569tk8fyhdazyhytel2m32awe4kuy6qq996um3ljaajj36`
/// - invalid (length shorter than expected by 1 char): `t1123456789ABCDEFGHJKLMNPQRSTUVWXY`
/// - invalid (all zeroes): `t1000000000000000000000000000000000`
#[allow(deprecated)]
async fn fetch_service_z_validate_address(validator: &ValidatorKind) {
let mut test_manager = TestManager::<FetchService>::launch(
validator,
&BackendType::Fetch,
None,
None,
None,
true,
false,
false,
)
.await
.unwrap();

let fetch_service_subscriber = test_manager.service_subscriber.take().unwrap();

let rpc_call = |addr: String| {
let subscriber = &fetch_service_subscriber;
async move { subscriber.z_validate_address(addr).await.unwrap() }
};

integration_tests::rpc::z_validate_address::run_z_validate_suite(&rpc_call).await;
integration_tests::rpc::z_validate_address::run_z_validate_sapling_legacy(&rpc_call).await;

test_manager.close().await;
}

#[allow(deprecated)]
async fn fetch_service_get_block_nullifiers<V: ValidatorExt>(validator: &ValidatorKind) {
let mut test_manager =
Expand Down Expand Up @@ -1795,6 +1833,11 @@ mod zcashd {
pub(crate) async fn validate_address() {
fetch_service_validate_address::<Zcashd>(&ValidatorKind::Zcashd).await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
pub(crate) async fn z_validate_address() {
fetch_service_z_validate_address(&ValidatorKind::Zcashd).await;
}
}

mod get {
Expand Down Expand Up @@ -2068,6 +2111,11 @@ mod zebrad {
pub(crate) async fn validate_address() {
fetch_service_validate_address::<Zebrad>(&ValidatorKind::Zebrad).await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
pub(crate) async fn z_validate_address() {
fetch_service_z_validate_address(&ValidatorKind::Zebrad).await;
}
}

mod get {
Expand Down
16 changes: 16 additions & 0 deletions integration-tests/tests/json_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,22 @@ mod zcashd {
validate_address_inner().await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn z_validate_address() {
let (mut test_manager, _zcashd_service, zcashd_subscriber, _zaino_service, _zaino_sub) =
create_test_manager_and_fetch_services(false).await;

let rpc_call = |addr: String| {
let subscriber = &zcashd_subscriber;
async move { subscriber.z_validate_address(addr).await.unwrap() }
};

integration_tests::rpc::z_validate_address::run_z_validate_suite(&rpc_call).await;
integration_tests::rpc::z_validate_address::run_z_validate_sapling(&rpc_call).await;

test_manager.close().await;
}

#[tokio::test(flavor = "multi_thread")]
async fn z_get_block() {
z_get_block_inner().await;
Expand Down
53 changes: 51 additions & 2 deletions integration-tests/tests/state_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1635,9 +1635,58 @@ mod zebra {
}
}

mod z {
use zcash_local_net::validator::zebrad::Zebrad;
mod validation {

use zaino_state::ZcashIndexer;
use zaino_testutils::ValidatorKind;

use crate::create_test_manager_and_services;

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
pub(crate) async fn z_validate_address() {
// const VALID_P2PKH_ADDRESS: &str = "tmVqEASZxBNKFTbmASZikGa5fPLkd68iJyx";
// const VALID_P2SH_ADDRESS: &str = "t2MjoXQ2iDrjG9QXNZNCY9io8ecN4FJYK1u";

// const VALID_SPROUT_ADDRESS: &str = "ztfhKyLouqi8sSwjRm4YMQdWPjTmrJ4QgtziVQ1Kd1e9EsRHYKofjoJdF438FwcUQnix8yrbSrzPpJJNABewgNffs5d4YZJ";
// const VALID_PAYING_KEY: &str = "VALID_SPROUT_ADDRESS";
// const VALID_TRANSMISSION_KEY: &str =
// "480f78d61bdd7fc4b4edeef9f6305b29753057ab1008d42ded1a3364dac2d83c";

// const VALID_SAPLING_ADDRESS: &str = "zregtestsapling1jalqhycwumq3unfxlzyzcktq3n478n82k2wacvl8gwfxk6ahshkxmtp2034qj28n7gl92ka5wca";
// const VALID_DIVERSIFIER: &str = "977e0b930ee6c11e4d26f8";
// const VALID_DIVERSIFIED_TRANSMISSION_KEY: &str =
// "553ef2f328096a7c2aac6dec85b76b6b9243e733dc9db2eacce3eb8c60592c88";

// const VALID_UNIFIED_ADDRESS: &str = "uregtest1njwg60x0jarhyuuxrcdvw854p68cgdfe85822lmclc7z9vy9xqr7t49n3d97k2dwlee82skwwe0ens0rc06p4vr04tvd3j9ckl3qry83ckay4l4ngdq9atg7vuj9z58tfjs0mnsgyrnprtqfv8almu564z498zy6tp2aa569tk8fyhdazyhytel2m32awe4kuy6qq996um3ljaajj36";

let (
mut test_manager,
_fetch_service,
_fetch_service_subscriber,
_state_service,
state_service_subscriber,
) = create_test_manager_and_services(
&ValidatorKind::Zebrad,
None,
true,
true,
None,
)
.await;

let rpc_call = |addr: String| {
let subscriber = &state_service_subscriber;
async move { subscriber.z_validate_address(addr).await.unwrap() }
};

integration_tests::rpc::z_validate_address::run_z_validate_suite(&rpc_call).await;
integration_tests::rpc::z_validate_address::run_z_validate_sapling(&rpc_call).await;

test_manager.close().await;
}
}

mod z {
use super::*;

#[tokio::test(flavor = "multi_thread")]
Expand Down
18 changes: 18 additions & 0 deletions zaino-fetch/src/jsonrpsee/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::jsonrpsee::{
block_subsidy::GetBlockSubsidy,
mining_info::GetMiningInfoWire,
peer_info::GetPeerInfo,
z_validate_address::{ZValidateAddressError, ZValidateAddressResponse},
GetBalanceError, GetBalanceResponse, GetBlockCountResponse, GetBlockError, GetBlockHash,
GetBlockResponse, GetBlockchainInfoResponse, GetInfoResponse, GetMempoolInfoResponse,
GetSubtreesError, GetSubtreesResponse, GetTransactionResponse, GetTreestateError,
Expand Down Expand Up @@ -652,6 +653,23 @@ impl JsonRpSeeConnector {
self.send_request("validateaddress", params).await
}

/// Return information about the given address.
///
/// # Parameters
/// - `address`: (string, required) The address to validate.
///
/// zcashd reference: [`z_validateaddress`](https://zcash.github.io/rpc/z_validateaddress.html)
/// method: post
/// tags: util
pub async fn z_validate_address(
&self,
address: String,
) -> Result<ZValidateAddressResponse, RpcRequestError<ZValidateAddressError>> {
tracing::debug!("Sending jsonrpsee connecter z_validate_address.");
let params = vec![serde_json::to_value(address).map_err(RpcRequestError::JsonRpc)?];
self.send_request("z_validateaddress", params).await
}

/// Returns all transaction ids in the memory pool, as a JSON array.
///
/// zcashd reference: [`getrawmempool`](https://zcash.github.io/rpc/getrawmempool.html)
Expand Down
1 change: 1 addition & 0 deletions zaino-fetch/src/jsonrpsee/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod block_subsidy;
pub mod common;
pub mod mining_info;
pub mod peer_info;
pub mod z_validate_address;

use std::{convert::Infallible, num::ParseIntError};

Expand Down
Loading
Loading