diff --git a/docs/tutorial.md b/docs/tutorial.md new file mode 100644 index 000000000..62b15ff5c --- /dev/null +++ b/docs/tutorial.md @@ -0,0 +1,24 @@ +This is a tutorial to launch zaino, connected to a local validator. + +Step 0: Git check out zaino. + +Step 1: Set up zebra v3.1.0. +``` +git clone git@github.com:ZcashFoundation/zebra.git +git checkout v3.1.0 +cargo install --path zebrad --locked +``` + +EASY PATH: +Use included Testnet Configuration + +In the zaino git root, run +``` +zebrad -c example_configs/zebrad_config_3.1.0.toml +``` +in another shell, +``` +cargo run --release -- start -c example_configs/zainod.toml +``` + + diff --git a/example_configs/zainod.toml b/example_configs/zainod.toml new file mode 100644 index 000000000..136a7b2c3 --- /dev/null +++ b/example_configs/zainod.toml @@ -0,0 +1,35 @@ +# Zaino Configuration +# +# Generated with `zainod generate-config` +# +# Configuration sources are layered (highest priority first): +# 1. Environment variables (prefix: ZAINO_) +# 2. TOML configuration file +# 3. Built-in defaults +# +# For detailed documentation, see: +# https://github.com/zingolabs/zaino + +backend = 'fetch' +zebra_db_path = '/home/cupress/.cache/zebra' +network = 'Testnet' + +[grpc_settings] +listen_address = '127.0.0.1:8137' + +[validator_settings] +validator_grpc_listen_address = '127.0.0.1:18232' +validator_jsonrpc_listen_address = '127.0.0.1:18231' +validator_user = 'xxxxxx' +validator_password = 'xxxxxx' + +[service] +timeout = 30 +channel_size = 32 +[storage.cache] +capacity = 10000 +shard_power = 4 + +[storage.database] +path = '/home/cupress/.cache/zaino' +size = 128 diff --git a/example_configs/zebrad_config_3.1.0.toml b/example_configs/zebrad_config_3.1.0.toml new file mode 100644 index 000000000..85580b4cd --- /dev/null +++ b/example_configs/zebrad_config_3.1.0.toml @@ -0,0 +1,103 @@ +# Default configuration for zebrad. +# +# This file can be used as a skeleton for custom configs. +# +# Unspecified fields use default values. Optional fields are Some(field) if the +# field is present and None if it is absent. +# +# This file is generated as an example using zebrad's current defaults. +# You should set only the config options you want to keep, and delete the rest. +# Only a subset of fields are present in the skeleton, since optional values +# whose default is None are omitted. +# +# The config format (including a complete list of sections and fields) is +# documented here: +# https://docs.rs/zebrad/latest/zebrad/config/struct.ZebradConfig.html +# +# CONFIGURATION SOURCES (in order of precedence, highest to lowest): +# +# 1. Environment variables with ZEBRA_ prefix (highest precedence) +# - Format: ZEBRA_SECTION__KEY (double underscore for nested keys) +# - Examples: +# - ZEBRA_NETWORK__NETWORK=Testnet +# - ZEBRA_RPC__LISTEN_ADDR=127.0.0.1:8232 +# - ZEBRA_STATE__CACHE_DIR=/path/to/cache +# - ZEBRA_TRACING__FILTER=debug +# - ZEBRA_METRICS__ENDPOINT_ADDR=0.0.0.0:9999 +# +# 2. Configuration file (TOML format) +# - At the path specified via -c flag, e.g. `zebrad -c myconfig.toml start`, or +# - At the default path in the user's preference directory (platform-dependent, see below) +# +# 3. Hard-coded defaults (lowest precedence) +# +# The user's preference directory and the default path to the `zebrad` config are platform dependent, +# based on `dirs::preference_dir`, see https://docs.rs/dirs/latest/dirs/fn.preference_dir.html : +# +# | Platform | Value | Example | +# | -------- | ------------------------------------- | ---------------------------------------------- | +# | Linux | `$XDG_CONFIG_HOME` or `$HOME/.config` | `/home/alice/.config/zebrad.toml` | +# | macOS | `$HOME/Library/Preferences` | `/Users/Alice/Library/Preferences/zebrad.toml` | +# | Windows | `{FOLDERID_RoamingAppData}` | `C:\Users\Alice\AppData\Local\zebrad.toml` | + +[consensus] +checkpoint_sync = true + +[health] +enforce_on_test_networks = false +min_connected_peers = 1 +ready_max_blocks_behind = 2 +ready_max_tip_age = "5m" + +[mempool] +eviction_memory_time = "1h" +tx_cost_limit = 80000000 + +[metrics] + +[mining] +internal_miner = false + +[network] +cache_dir = true +crawl_new_peer_interval = "1m 1s" +initial_mainnet_peers = [ + "dnsseed.z.cash:8233", + "dnsseed.str4d.xyz:8233", + "mainnet.seeder.zfnd.org:8233", +] +initial_testnet_peers = [ + "dnsseed.testnet.z.cash:18233", + "testnet.seeder.zfnd.org:18233", +] +listen_addr = "[::]:8233" +max_connections_per_ip = 1 +network = "Testnet" +peerset_initial_target_size = 25 + +[rpc] +cookie_dir = "/home/cupress/.cache/zebra" +debug_force_finished_sync = false +enable_cookie_auth = false +max_response_body_size = 52428800 +parallel_cpu_threads = 0 +listen_addr = '127.0.0.1:18231' +indexer_listen_addr = '127.0.0.1:18232' + +[state] +cache_dir = "/home/cupress/.cache/zebra" +delete_old_database = true +ephemeral = false +should_backup_non_finalized_state = true + +[sync] +checkpoint_verify_concurrency_limit = 1000 +download_concurrency_limit = 50 +full_verify_concurrency_limit = 20 +parallel_cpu_threads = 0 + +[tracing] +buffer_limit = 128000 +force_use_color = false +use_color = true +use_journald = false diff --git a/wj/notes/zainodstart.txt b/wj/notes/zainodstart.txt new file mode 100644 index 000000000..c060845b9 --- /dev/null +++ b/wj/notes/zainodstart.txt @@ -0,0 +1,82 @@ +zebra off: +[zaino-fetch/src/jsonrpsee/connector.rs:919:17] e = ReqwestError( + reqwest::Error { + kind: Request, + url: "http://127.0.0.1:18232/", + source: hyper_util::client::legacy::Error( + Connect, + ConnectError( + "tcp connect error", + 127.0.0.1:18232, + Os { + code: 111, + kind: ConnectionRefused, + message: "Connection refused", + }, + ), + ), + }, +) + +zebra 4.1 on: +listen_addr = '127.0.0.1:18232' + +[zaino-fetch/src/jsonrpsee/connector.rs:919:17] e = ReqwestError( + reqwest::Error { + kind: Request, + url: "http://127.0.0.1:18232/", + source: hyper_util::client::legacy::Error( + SendRequest, + hyper::Error( + Parse( + Version, + ), + ), + ), + }, +) + +zebra on: +indexer_listen_addr = '127.0.0.1:18232' +[zaino-fetch/src/jsonrpsee/connector.rs:919:17] e = ReqwestError( + reqwest::Error { + kind: Request, + url: "http://127.0.0.1:18232/", + source: hyper_util::client::legacy::Error( + SendRequest, + hyper::Error( + Parse( + Version, + ), + ), + ), + }, +) +[zaino-fetch/src/jsonrpsee/connector.rs:919:17] e = ReqwestError( + reqwest::Error { + kind: Request, + url: "http://127.0.0.1:18232/", + source: hyper_util::client::legacy::Error( + Canceled, + hyper::Error( + Canceled, + hyper::Error( + UnexpectedMessage, + ), + ), + ), + }, +) +[zaino-fetch/src/jsonrpsee/connector.rs:919:17] e = ReqwestError( + reqwest::Error { + kind: Request, + url: "http://127.0.0.1:18232/", + source: hyper_util::client::legacy::Error( + Canceled, + hyper::Error( + Canceled, + "connection was not ready", + ), + ), + }, +) diff --git a/zaino-fetch/src/jsonrpsee/connector.rs b/zaino-fetch/src/jsonrpsee/connector.rs index b59519d5f..6f002f661 100644 --- a/zaino-fetch/src/jsonrpsee/connector.rs +++ b/zaino-fetch/src/jsonrpsee/connector.rs @@ -830,13 +830,30 @@ impl JsonRpSeeConnector { } } +#[derive(Debug)] // +#[derive(thiserror::Error)] // +pub(crate) enum TestNodeConnectionError { + #[error("Building Reqwest Client: {{0}}")] + ClientBuild(reqwest::Error), + #[error("Reqwest Response: {{0}}")] + ReqwestResponse(reqwest::Error), + #[error("Response Body: {{0}}")] + ResponseBody(reqwest::Error), + #[error("Json body: {{0}}")] + BodyJson(serde_json::Error), +} + /// Tests connection with zebrad / zebrad. -async fn test_node_connection(url: Url, auth_method: AuthMethod) -> Result<(), TransportError> { +async fn test_node_connection( + url: Url, + auth_method: AuthMethod, +) -> Result<(), TestNodeConnectionError> { let client = Client::builder() .connect_timeout(std::time::Duration::from_secs(2)) .timeout(std::time::Duration::from_secs(5)) .redirect(reqwest::redirect::Policy::none()) - .build()?; + .build() + .map_err(TestNodeConnectionError::ClientBuild)?; let request_body = r#"{"jsonrpc":"2.0","method":"getinfo","params":[],"id":1}"#; let mut request_builder = client @@ -862,13 +879,13 @@ async fn test_node_connection(url: Url, auth_method: AuthMethod) -> Result<(), T let response = request_builder .send() .await - .map_err(TransportError::ReqwestError)?; + .map_err(TestNodeConnectionError::ReqwestResponse)?; let body_bytes = response .bytes() .await - .map_err(TransportError::ReqwestError)?; - let _response: RpcResponse = serde_json::from_slice(&body_bytes) - .map_err(|e| TransportError::BadNodeData(Box::new(e), ""))?; + .map_err(TestNodeConnectionError::ResponseBody)?; + let _response: RpcResponse = + serde_json::from_slice(&body_bytes).map_err(TestNodeConnectionError::BodyJson)?; Ok(()) } @@ -910,18 +927,20 @@ pub async fn test_node_and_return_url( let url: Url = format!("http://{}:{}", host, addr.port()).parse()?; let mut interval = tokio::time::interval(tokio::time::Duration::from_millis(500)); - for _ in 0..3 { + for _ in 0..6 { match test_node_connection(url.clone(), auth_method.clone()).await { Ok(_) => { return Ok(url); } - Err(_) => { + Err(e) => { + dbg!(e); + // TOdo actually show this error. tokio::time::sleep(std::time::Duration::from_secs(3)).await; } } interval.tick().await; } - error!("Error: Could not establish connection with node. Please check config and confirm node is listening at {url} and the correct authorisation details have been entered. Exiting.."); + error!("Error: Zainod needs to connect to a zcash Validator node. (either zcashd or zebrad). Failed to connect to a Validator at {url}. Perhaps the Validator is not running or perhaps there was an authentication error."); std::process::exit(1); }