zebra/zebra-rpc/src/methods.rs

1851 lines
68 KiB
Rust
Raw Normal View History

feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
//! Zebra supported RPC methods.
//!
//! Based on the [`zcashd` RPC methods](https://zcash.github.io/rpc/)
//! as used by `lightwalletd.`
//!
//! Some parts of the `zcashd` RPC documentation are outdated.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
//! So this implementation follows the `zcashd` server and `lightwalletd` client implementations.
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
use std::{collections::HashSet, fmt::Debug, sync::Arc};
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
use chrono::Utc;
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
use futures::{FutureExt, TryFutureExt};
use hex::{FromHex, ToHex};
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
use indexmap::IndexMap;
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
use jsonrpc_core::{self, BoxFuture, Error, ErrorCode, Result};
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
use jsonrpc_derive::rpc;
use tokio::{sync::broadcast, task::JoinHandle};
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
use tower::{Service, ServiceExt};
use tracing::Instrument;
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
Refactor `SentTransactionHash` to be a stricter type (#3706) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Implement `ToHex` and `FromHex` for `Hash` Make it easier to generate hexadecimal strings from `transaction::Hash` instances. * Use `ToHex` in `Debug` and `Display` Reduce repeated code. * Refactor to add `bytes_in_display_order` method Use it to remove repeated code and improve clarity a bit. * Use `hex::serialize` to serialize transaction hash Make the type stricter in its contents, while still serializing the transaction has as a hexadecimal string. * Simplify serialization attribute Deserialization should also use `hex::deserialize`, so using the shorter attribute makes things easier to read and more future proof. * Update zebra-chain/src/transaction/hash.rs * Remove unnecessary lifetime The anonymous lifetime is automatically inferred by the compiler. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
2022-03-08 01:14:21 -08:00
use zebra_chain::{
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
block::{self, Height, SerializedBlock},
chain_tip::ChainTip,
feat(rpc): Implement `z_gettreestate` RPC (#3990) * Impl the elementary structure of the `z_gettreestate` RPC * Fix merging bugs * Fix a merge bug * Fix a merge bug * Move a derive attribute Co-authored-by: teor <teor@riseup.net> * Clarify the support of negative heights * Add Orchard note commitment trees to the response * Add the time to the response * Finalize the `z_gettreestate` RPC * Add a note that verified blocks have coinbase height * Refactor `from_str` for `HashOrHeight` * Fix a mistake in the docs Co-authored-by: teor <teor@riseup.net> * Clarify request types Co-authored-by: teor <teor@riseup.net> * Simplify `hash_or_height` conversion to height Co-authored-by: teor <teor@riseup.net> * Add a TODO about optimization Co-authored-by: teor <teor@riseup.net> * Add a doc comment * Make sure Sapling & Orchard trees don't get mixed up * Serialize Sapling commitment trees * Refactor some comments * Serialize Orchard commitment trees * Serialize block heights * Simplify the serialization of commitment trees * Remove the block time from the RPC response * Simplify the serialization of block heights * Put Sapling & Orchard requests together * Remove a redundant TODO * Add block times to the RPC response * Derive `Clone, Debug, Eq, PartialEq` for `GetTreestate` Co-authored-by: teor <teor@riseup.net> * Derive `Clone`, `Debug`, `Eq` and `PartialEq` for `SerializedTree` * Document the fields of `GetTreestate` * Skip the serialization of empty trees This ensures compatibility with `zcashd` in the `z_gettreestate` RPC. * Document the `impl` of `merkle_tree::Hashable` for nodes * Make the structure of the JSON response consistent with `zcashd` * Derive `Eq` for nodes Co-authored-by: teor <teor@riseup.net> * Convert Sapling commitment trees to a format compatible with zcashd * Refactor the conversion of Sapling commitment trees * Refactor some comments * Refactor comments * Add a description of the conversion Co-authored-by: Conrado Gouvea <conrado@zfnd.org> * Fix comment indenting * Document the conversion between the dense and sparse formats Co-authored-by: teor <teor@riseup.net> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
2022-05-12 00:00:12 -07:00
orchard,
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
parameters::{ConsensusBranchId, Network, NetworkUpgrade},
feat(rpc): Implement `z_gettreestate` RPC (#3990) * Impl the elementary structure of the `z_gettreestate` RPC * Fix merging bugs * Fix a merge bug * Fix a merge bug * Move a derive attribute Co-authored-by: teor <teor@riseup.net> * Clarify the support of negative heights * Add Orchard note commitment trees to the response * Add the time to the response * Finalize the `z_gettreestate` RPC * Add a note that verified blocks have coinbase height * Refactor `from_str` for `HashOrHeight` * Fix a mistake in the docs Co-authored-by: teor <teor@riseup.net> * Clarify request types Co-authored-by: teor <teor@riseup.net> * Simplify `hash_or_height` conversion to height Co-authored-by: teor <teor@riseup.net> * Add a TODO about optimization Co-authored-by: teor <teor@riseup.net> * Add a doc comment * Make sure Sapling & Orchard trees don't get mixed up * Serialize Sapling commitment trees * Refactor some comments * Serialize Orchard commitment trees * Serialize block heights * Simplify the serialization of commitment trees * Remove the block time from the RPC response * Simplify the serialization of block heights * Put Sapling & Orchard requests together * Remove a redundant TODO * Add block times to the RPC response * Derive `Clone, Debug, Eq, PartialEq` for `GetTreestate` Co-authored-by: teor <teor@riseup.net> * Derive `Clone`, `Debug`, `Eq` and `PartialEq` for `SerializedTree` * Document the fields of `GetTreestate` * Skip the serialization of empty trees This ensures compatibility with `zcashd` in the `z_gettreestate` RPC. * Document the `impl` of `merkle_tree::Hashable` for nodes * Make the structure of the JSON response consistent with `zcashd` * Derive `Eq` for nodes Co-authored-by: teor <teor@riseup.net> * Convert Sapling commitment trees to a format compatible with zcashd * Refactor the conversion of Sapling commitment trees * Refactor some comments * Refactor comments * Add a description of the conversion Co-authored-by: Conrado Gouvea <conrado@zfnd.org> * Fix comment indenting * Document the conversion between the dense and sparse formats Co-authored-by: teor <teor@riseup.net> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
2022-05-12 00:00:12 -07:00
sapling,
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
serialization::{SerializationError, ZcashDeserialize},
subtree::NoteCommitmentSubtreeIndex,
transaction::{self, SerializedTransaction, Transaction, UnminedTx},
transparent::{self, Address},
Refactor `SentTransactionHash` to be a stricter type (#3706) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Implement `ToHex` and `FromHex` for `Hash` Make it easier to generate hexadecimal strings from `transaction::Hash` instances. * Use `ToHex` in `Debug` and `Display` Reduce repeated code. * Refactor to add `bytes_in_display_order` method Use it to remove repeated code and improve clarity a bit. * Use `hex::serialize` to serialize transaction hash Make the type stricter in its contents, while still serializing the transaction has as a hexadecimal string. * Simplify serialization attribute Deserialization should also use `hex::deserialize`, so using the shorter attribute makes things easier to read and more future proof. * Update zebra-chain/src/transaction/hash.rs * Remove unnecessary lifetime The anonymous lifetime is automatically inferred by the compiler. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
2022-03-08 01:14:21 -08:00
};
use zebra_node_services::mempool;
use zebra_state::{HashOrHeight, MinedTx, OutputIndex, OutputLocation, TransactionLocation};
use crate::{
constants::{INVALID_PARAMETERS_ERROR_CODE, MISSING_BLOCK_ERROR_CODE},
methods::trees::{GetSubtrees, SubtreeRpcData},
queue::Queue,
};
// We don't use a types/ module here, because it is redundant.
pub mod trees;
#[cfg(feature = "getblocktemplate-rpcs")]
pub mod get_block_template_rpcs;
#[cfg(feature = "getblocktemplate-rpcs")]
pub use get_block_template_rpcs::{GetBlockTemplateRpc, GetBlockTemplateRpcImpl};
#[cfg(test)]
mod tests;
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
#[rpc(server)]
/// RPC method signatures.
pub trait Rpc {
/// Returns software information from the RPC server, as a [`GetInfo`] JSON struct.
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
///
/// zcashd reference: [`getinfo`](https://zcash.github.io/rpc/getinfo.html)
///
/// # Notes
///
/// [The zcashd reference](https://zcash.github.io/rpc/getinfo.html) might not show some fields
/// in Zebra's [`GetInfo`]. Zebra uses the field names and formats from the
/// [zcashd code](https://github.com/zcash/zcash/blob/v4.6.0-1/src/rpc/misc.cpp#L86-L87).
///
/// Some fields from the zcashd reference are missing from Zebra's [`GetInfo`]. It only contains the fields
/// [required for lightwalletd support.](https://github.com/zcash/lightwalletd/blob/v0.4.9/common/common.go#L91-L95)
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
#[rpc(name = "getinfo")]
fn get_info(&self) -> Result<GetInfo>;
/// Returns blockchain state information, as a [`GetBlockChainInfo`] JSON struct.
///
/// zcashd reference: [`getblockchaininfo`](https://zcash.github.io/rpc/getblockchaininfo.html)
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
///
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
/// # Notes
///
/// Some fields from the zcashd reference are missing from Zebra's [`GetBlockChainInfo`]. It only contains the fields
/// [required for lightwalletd support.](https://github.com/zcash/lightwalletd/blob/v0.4.9/common/common.go#L72-L89)
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
#[rpc(name = "getblockchaininfo")]
fn get_blockchain_info(&self) -> Result<GetBlockChainInfo>;
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
/// Returns the total balance of a provided `addresses` in an [`AddressBalance`] instance.
///
/// zcashd reference: [`getaddressbalance`](https://zcash.github.io/rpc/getaddressbalance.html)
///
/// # Parameters
///
/// - `address_strings`: (map) A JSON map with a single entry
/// - `addresses`: (array of strings) A list of base-58 encoded addresses.
///
/// # Notes
///
/// zcashd also accepts a single string parameter instead of an array of strings, but Zebra
/// doesn't because lightwalletd always calls this RPC with an array of addresses.
///
/// zcashd also returns the total amount of Zatoshis received by the addresses, but Zebra
/// doesn't because lightwalletd doesn't use that information.
///
/// The RPC documentation says that the returned object has a string `balance` field, but
/// zcashd actually [returns an
/// integer](https://github.com/zcash/lightwalletd/blob/bdaac63f3ee0dbef62bde04f6817a9f90d483b00/common/common.go#L128-L130).
#[rpc(name = "getaddressbalance")]
fn get_address_balance(
&self,
address_strings: AddressStrings,
) -> BoxFuture<Result<AddressBalance>>;
/// Sends the raw bytes of a signed transaction to the local node's mempool, if the transaction is valid.
/// Returns the [`SentTransactionHash`] for the transaction, as a JSON string.
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
///
/// zcashd reference: [`sendrawtransaction`](https://zcash.github.io/rpc/sendrawtransaction.html)
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
///
/// # Parameters
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
///
/// - `raw_transaction_hex`: (string, required) The hex-encoded raw transaction bytes.
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
///
/// # Notes
///
/// zcashd accepts an optional `allowhighfees` parameter. Zebra doesn't support this parameter,
/// because lightwalletd doesn't use it.
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
#[rpc(name = "sendrawtransaction")]
fn send_raw_transaction(
&self,
raw_transaction_hex: String,
) -> BoxFuture<Result<SentTransactionHash>>;
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
/// Returns the requested block by hash or height, as a [`GetBlock`] JSON string.
/// If the block is not in Zebra's state, returns
/// [error code `-8`.](https://github.com/zcash/zcash/issues/5758)
///
/// zcashd reference: [`getblock`](https://zcash.github.io/rpc/getblock.html)
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
///
/// # Parameters
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
///
/// - `hash | height`: (string, required) The hash or height for the block to be returned.
/// - `verbosity`: (numeric, optional, default=1) 0 for hex encoded data, 1 for a json object,
/// and 2 for json object with transaction data.
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
///
/// # Notes
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
///
/// With verbosity=1, [`lightwalletd` only reads the `tx` field of the
/// result](https://github.com/zcash/lightwalletd/blob/dfac02093d85fb31fb9a8475b884dd6abca966c7/common/common.go#L152),
/// and other clients only read the `hash` and `confirmations` fields,
/// so we only return a few fields for now.
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
///
/// `lightwalletd` and mining clients also do not use verbosity=2, so we don't support it.
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
#[rpc(name = "getblock")]
fn get_block(
&self,
hash_or_height: String,
verbosity: Option<u8>,
) -> BoxFuture<Result<GetBlock>>;
feature(rpc): Implement `getbestblockhash` method (#3754) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex * feature(rpc): add `getbestblockhash` RPC method * feature(rpc): Add a `pub struct SerializedBlockHash` type * tests(rpc): add a unit test for `getbestblockhash` method * tests(rpc): make sure no requests are sent to mempool in getbestblockhash test * tests(rpc): refactor check Co-authored-by: teor <teor@riseup.net> * fix(rpc): fixes after rebase * refactor(rpc): refactor `GetBestBlockHash` * fix(rpc): unused variables Co-authored-by: teor <teor@riseup.net> * docs(rpc): update * fix(rpc): add panic * fix(rpc): fix panic Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-10 21:13:08 -08:00
/// Returns the hash of the current best blockchain tip block, as a [`GetBlockHash`] JSON string.
feature(rpc): Implement `getbestblockhash` method (#3754) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex * feature(rpc): add `getbestblockhash` RPC method * feature(rpc): Add a `pub struct SerializedBlockHash` type * tests(rpc): add a unit test for `getbestblockhash` method * tests(rpc): make sure no requests are sent to mempool in getbestblockhash test * tests(rpc): refactor check Co-authored-by: teor <teor@riseup.net> * fix(rpc): fixes after rebase * refactor(rpc): refactor `GetBestBlockHash` * fix(rpc): unused variables Co-authored-by: teor <teor@riseup.net> * docs(rpc): update * fix(rpc): add panic * fix(rpc): fix panic Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-10 21:13:08 -08:00
///
/// zcashd reference: [`getbestblockhash`](https://zcash.github.io/rpc/getbestblockhash.html)
feature(rpc): Implement `getbestblockhash` method (#3754) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex * feature(rpc): add `getbestblockhash` RPC method * feature(rpc): Add a `pub struct SerializedBlockHash` type * tests(rpc): add a unit test for `getbestblockhash` method * tests(rpc): make sure no requests are sent to mempool in getbestblockhash test * tests(rpc): refactor check Co-authored-by: teor <teor@riseup.net> * fix(rpc): fixes after rebase * refactor(rpc): refactor `GetBestBlockHash` * fix(rpc): unused variables Co-authored-by: teor <teor@riseup.net> * docs(rpc): update * fix(rpc): add panic * fix(rpc): fix panic Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-10 21:13:08 -08:00
#[rpc(name = "getbestblockhash")]
fn get_best_block_hash(&self) -> Result<GetBlockHash>;
/// Returns all transaction ids in the memory pool, as a JSON array.
///
/// zcashd reference: [`getrawmempool`](https://zcash.github.io/rpc/getrawmempool.html)
#[rpc(name = "getrawmempool")]
fn get_raw_mempool(&self) -> BoxFuture<Result<Vec<String>>>;
feat(rpc): Implement `z_gettreestate` RPC (#3990) * Impl the elementary structure of the `z_gettreestate` RPC * Fix merging bugs * Fix a merge bug * Fix a merge bug * Move a derive attribute Co-authored-by: teor <teor@riseup.net> * Clarify the support of negative heights * Add Orchard note commitment trees to the response * Add the time to the response * Finalize the `z_gettreestate` RPC * Add a note that verified blocks have coinbase height * Refactor `from_str` for `HashOrHeight` * Fix a mistake in the docs Co-authored-by: teor <teor@riseup.net> * Clarify request types Co-authored-by: teor <teor@riseup.net> * Simplify `hash_or_height` conversion to height Co-authored-by: teor <teor@riseup.net> * Add a TODO about optimization Co-authored-by: teor <teor@riseup.net> * Add a doc comment * Make sure Sapling & Orchard trees don't get mixed up * Serialize Sapling commitment trees * Refactor some comments * Serialize Orchard commitment trees * Serialize block heights * Simplify the serialization of commitment trees * Remove the block time from the RPC response * Simplify the serialization of block heights * Put Sapling & Orchard requests together * Remove a redundant TODO * Add block times to the RPC response * Derive `Clone, Debug, Eq, PartialEq` for `GetTreestate` Co-authored-by: teor <teor@riseup.net> * Derive `Clone`, `Debug`, `Eq` and `PartialEq` for `SerializedTree` * Document the fields of `GetTreestate` * Skip the serialization of empty trees This ensures compatibility with `zcashd` in the `z_gettreestate` RPC. * Document the `impl` of `merkle_tree::Hashable` for nodes * Make the structure of the JSON response consistent with `zcashd` * Derive `Eq` for nodes Co-authored-by: teor <teor@riseup.net> * Convert Sapling commitment trees to a format compatible with zcashd * Refactor the conversion of Sapling commitment trees * Refactor some comments * Refactor comments * Add a description of the conversion Co-authored-by: Conrado Gouvea <conrado@zfnd.org> * Fix comment indenting * Document the conversion between the dense and sparse formats Co-authored-by: teor <teor@riseup.net> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
2022-05-12 00:00:12 -07:00
/// Returns information about the given block's Sapling & Orchard tree state.
///
/// zcashd reference: [`z_gettreestate`](https://zcash.github.io/rpc/z_gettreestate.html)
///
/// # Parameters
///
/// - `hash | height`: (string, required) The block hash or height.
///
/// # Notes
///
/// The zcashd doc reference above says that the parameter "`height` can be
/// negative where -1 is the last known valid block". On the other hand,
/// `lightwalletd` only uses positive heights, so Zebra does not support
/// negative heights.
#[rpc(name = "z_gettreestate")]
fn z_get_treestate(&self, hash_or_height: String) -> BoxFuture<Result<GetTreestate>>;
/// Returns information about a range of Sapling or Orchard subtrees.
///
/// zcashd reference: [`z_getsubtreesbyindex`](https://zcash.github.io/rpc/z_getsubtreesbyindex.html)
///
/// # Parameters
///
/// - `pool`: (string, required) The pool from which subtrees should be returned.
/// Either "sapling" or "orchard".
/// - `start_index`: (numeric, required) The index of the first 2^16-leaf subtree to return.
/// - `limit`: (numeric, optional) The maximum number of subtree values to return.
///
/// # Notes
///
/// While Zebra is doing its initial subtree index rebuild, subtrees will become available
/// starting at the chain tip. This RPC will return an empty list if the `start_index` subtree
/// exists, but has not been rebuilt yet. This matches `zcashd`'s behaviour when subtrees aren't
/// available yet. (But `zcashd` does its rebuild before syncing any blocks.)
#[rpc(name = "z_getsubtreesbyindex")]
fn z_get_subtrees_by_index(
&self,
pool: String,
start_index: NoteCommitmentSubtreeIndex,
limit: Option<NoteCommitmentSubtreeIndex>,
) -> BoxFuture<Result<GetSubtrees>>;
/// Returns the raw transaction data, as a [`GetRawTransaction`] JSON string or structure.
///
/// zcashd reference: [`getrawtransaction`](https://zcash.github.io/rpc/getrawtransaction.html)
///
/// # Parameters
///
/// - `txid`: (string, required) The transaction ID of the transaction to be returned.
/// - `verbose`: (numeric, optional, default=0) If 0, return a string of hex-encoded data, otherwise return a JSON object.
///
/// # Notes
///
/// We don't currently support the `blockhash` parameter since lightwalletd does not
/// use it.
///
/// In verbose mode, we only expose the `hex` and `height` fields since
/// lightwalletd uses only those:
/// <https://github.com/zcash/lightwalletd/blob/631bb16404e3d8b045e74a7c5489db626790b2f6/common/common.go#L119>
#[rpc(name = "getrawtransaction")]
fn get_raw_transaction(
&self,
txid_hex: String,
verbose: Option<u8>,
) -> BoxFuture<Result<GetRawTransaction>>;
/// Returns the transaction ids made by the provided transparent addresses.
///
/// zcashd reference: [`getaddresstxids`](https://zcash.github.io/rpc/getaddresstxids.html)
///
/// # Parameters
///
/// A [`GetAddressTxIdsRequest`] struct with the following named fields:
/// - `addresses`: (json array of string, required) The addresses to get transactions from.
/// - `start`: (numeric, required) The lower height to start looking for transactions (inclusive).
/// - `end`: (numeric, required) The top height to stop looking for transactions (inclusive).
///
/// # Notes
///
/// Only the multi-argument format is used by lightwalletd and this is what we currently support:
/// <https://github.com/zcash/lightwalletd/blob/631bb16404e3d8b045e74a7c5489db626790b2f6/common/common.go#L97-L102>
#[rpc(name = "getaddresstxids")]
fn get_address_tx_ids(&self, request: GetAddressTxIdsRequest)
-> BoxFuture<Result<Vec<String>>>;
/// Returns all unspent outputs for a list of addresses.
///
/// zcashd reference: [`getaddressutxos`](https://zcash.github.io/rpc/getaddressutxos.html)
///
/// # Parameters
///
/// - `addresses`: (json array of string, required) The addresses to get outputs from.
///
/// # Notes
///
/// lightwalletd always uses the multi-address request, without chaininfo:
/// <https://github.com/zcash/lightwalletd/blob/master/frontend/service.go#L402>
#[rpc(name = "getaddressutxos")]
fn get_address_utxos(
&self,
address_strings: AddressStrings,
) -> BoxFuture<Result<Vec<GetAddressUtxos>>>;
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
}
/// RPC method implementations.
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
#[derive(Clone)]
pub struct RpcImpl<Mempool, State, Tip>
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
where
Mempool: Service<
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
mempool::Request,
Response = mempool::Response,
Error = zebra_node_services::BoxError,
> + Clone
+ Send
+ Sync
+ 'static,
Mempool::Future: Send,
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
State: Service<
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
zebra_state::ReadRequest,
Response = zebra_state::ReadResponse,
Error = zebra_state::BoxError,
> + Clone
+ Send
+ Sync
+ 'static,
State::Future: Send,
Tip: ChainTip + Clone + Send + Sync + 'static,
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
{
add(test): test disabled `lightwalletd` mempool gRPCs via zebrad logs (#5016) * add grpc mempool test research * add a config flag for mempool injection of transactions in test * Only copy the inner state directory in the send transactions test * Preload Zcash parameters in some transaction verification tests * Add a block and transaction Hash method to convert from display order bytes * Update test coverage docs * Add debugging output for mempool transaction verification * Test fetching sent mempool transactions using gRPC * Add extra log checks to the send transaction test * Wait for zebrad mempool activation before running gRPC tests * Update send transaction test for lightwalletd not returning mempool transactions * Check zebrad logs instead of disabled lightwalletd gRPCs * Add a debug option that makes RPCs pretend the sync is finished * Remove an unused debug option * Remove unused test code and downgrade some logs * Fix test log checks * Fix some rustdoc warnings * Fix a compilation error due to new function arguments * Make zebrad sync timeouts consistent and remove outdated code * Document how to increase temporary directory space for tests * Stop checking for a log that doesn't always happen * Remove some commented-out code Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update a comment about run time Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Add new config to new tests from the `main` branch * Add transactions to the list, rather than replacing the list with each new block Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-09-06 06:32:33 -07:00
// Configuration
//
/// Zebra's application version, with build metadata.
build_version: String,
/// Zebra's RPC user agent.
user_agent: String,
add(test): test disabled `lightwalletd` mempool gRPCs via zebrad logs (#5016) * add grpc mempool test research * add a config flag for mempool injection of transactions in test * Only copy the inner state directory in the send transactions test * Preload Zcash parameters in some transaction verification tests * Add a block and transaction Hash method to convert from display order bytes * Update test coverage docs * Add debugging output for mempool transaction verification * Test fetching sent mempool transactions using gRPC * Add extra log checks to the send transaction test * Wait for zebrad mempool activation before running gRPC tests * Update send transaction test for lightwalletd not returning mempool transactions * Check zebrad logs instead of disabled lightwalletd gRPCs * Add a debug option that makes RPCs pretend the sync is finished * Remove an unused debug option * Remove unused test code and downgrade some logs * Fix test log checks * Fix some rustdoc warnings * Fix a compilation error due to new function arguments * Make zebrad sync timeouts consistent and remove outdated code * Document how to increase temporary directory space for tests * Stop checking for a log that doesn't always happen * Remove some commented-out code Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update a comment about run time Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Add new config to new tests from the `main` branch * Add transactions to the list, rather than replacing the list with each new block Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-09-06 06:32:33 -07:00
/// The configured network for this RPC service.
network: Network,
/// Test-only option that makes Zebra say it is at the chain tip,
/// no matter what the estimated height or local clock is.
debug_force_finished_sync: bool,
/// Test-only option that makes RPC responses more like `zcashd`.
#[allow(dead_code)]
debug_like_zcashd: bool,
add(test): test disabled `lightwalletd` mempool gRPCs via zebrad logs (#5016) * add grpc mempool test research * add a config flag for mempool injection of transactions in test * Only copy the inner state directory in the send transactions test * Preload Zcash parameters in some transaction verification tests * Add a block and transaction Hash method to convert from display order bytes * Update test coverage docs * Add debugging output for mempool transaction verification * Test fetching sent mempool transactions using gRPC * Add extra log checks to the send transaction test * Wait for zebrad mempool activation before running gRPC tests * Update send transaction test for lightwalletd not returning mempool transactions * Check zebrad logs instead of disabled lightwalletd gRPCs * Add a debug option that makes RPCs pretend the sync is finished * Remove an unused debug option * Remove unused test code and downgrade some logs * Fix test log checks * Fix some rustdoc warnings * Fix a compilation error due to new function arguments * Make zebrad sync timeouts consistent and remove outdated code * Document how to increase temporary directory space for tests * Stop checking for a log that doesn't always happen * Remove some commented-out code Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update a comment about run time Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Add new config to new tests from the `main` branch * Add transactions to the list, rather than replacing the list with each new block Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-09-06 06:32:33 -07:00
// Services
//
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
/// A handle to the mempool service.
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
mempool: Mempool,
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
/// A handle to the state service.
state: State,
/// Allows efficient access to the best tip of the blockchain.
latest_chain_tip: Tip,
add(test): test disabled `lightwalletd` mempool gRPCs via zebrad logs (#5016) * add grpc mempool test research * add a config flag for mempool injection of transactions in test * Only copy the inner state directory in the send transactions test * Preload Zcash parameters in some transaction verification tests * Add a block and transaction Hash method to convert from display order bytes * Update test coverage docs * Add debugging output for mempool transaction verification * Test fetching sent mempool transactions using gRPC * Add extra log checks to the send transaction test * Wait for zebrad mempool activation before running gRPC tests * Update send transaction test for lightwalletd not returning mempool transactions * Check zebrad logs instead of disabled lightwalletd gRPCs * Add a debug option that makes RPCs pretend the sync is finished * Remove an unused debug option * Remove unused test code and downgrade some logs * Fix test log checks * Fix some rustdoc warnings * Fix a compilation error due to new function arguments * Make zebrad sync timeouts consistent and remove outdated code * Document how to increase temporary directory space for tests * Stop checking for a log that doesn't always happen * Remove some commented-out code Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update a comment about run time Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Add new config to new tests from the `main` branch * Add transactions to the list, rather than replacing the list with each new block Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-09-06 06:32:33 -07:00
// Tasks
//
/// A sender component of a channel used to send transactions to the mempool queue.
queue_sender: broadcast::Sender<UnminedTx>,
}
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
impl<Mempool, State, Tip> Debug for RpcImpl<Mempool, State, Tip>
where
Mempool: Service<
mempool::Request,
Response = mempool::Response,
Error = zebra_node_services::BoxError,
> + Clone
+ Send
+ Sync
+ 'static,
Mempool::Future: Send,
State: Service<
zebra_state::ReadRequest,
Response = zebra_state::ReadResponse,
Error = zebra_state::BoxError,
> + Clone
+ Send
+ Sync
+ 'static,
State::Future: Send,
Tip: ChainTip + Clone + Send + Sync + 'static,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Skip fields without Debug impls, and skip channels
f.debug_struct("RpcImpl")
.field("build_version", &self.build_version)
.field("user_agent", &self.user_agent)
.field("network", &self.network)
.field("debug_force_finished_sync", &self.debug_force_finished_sync)
.field("debug_like_zcashd", &self.debug_like_zcashd)
.finish()
}
}
impl<Mempool, State, Tip> RpcImpl<Mempool, State, Tip>
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
where
Mempool: Service<
mempool::Request,
Response = mempool::Response,
Error = zebra_node_services::BoxError,
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
> + Clone
+ Send
+ Sync
+ 'static,
Mempool::Future: Send,
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
State: Service<
zebra_state::ReadRequest,
Response = zebra_state::ReadResponse,
Error = zebra_state::BoxError,
> + Clone
+ Send
+ Sync
+ 'static,
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
State::Future: Send,
Tip: ChainTip + Clone + Send + Sync + 'static,
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
{
/// Create a new instance of the RPC handler.
//
// TODO:
// - put some of the configs or services in their own struct?
#[allow(clippy::too_many_arguments)]
pub fn new<VersionString, UserAgentString>(
build_version: VersionString,
user_agent: UserAgentString,
add(test): test disabled `lightwalletd` mempool gRPCs via zebrad logs (#5016) * add grpc mempool test research * add a config flag for mempool injection of transactions in test * Only copy the inner state directory in the send transactions test * Preload Zcash parameters in some transaction verification tests * Add a block and transaction Hash method to convert from display order bytes * Update test coverage docs * Add debugging output for mempool transaction verification * Test fetching sent mempool transactions using gRPC * Add extra log checks to the send transaction test * Wait for zebrad mempool activation before running gRPC tests * Update send transaction test for lightwalletd not returning mempool transactions * Check zebrad logs instead of disabled lightwalletd gRPCs * Add a debug option that makes RPCs pretend the sync is finished * Remove an unused debug option * Remove unused test code and downgrade some logs * Fix test log checks * Fix some rustdoc warnings * Fix a compilation error due to new function arguments * Make zebrad sync timeouts consistent and remove outdated code * Document how to increase temporary directory space for tests * Stop checking for a log that doesn't always happen * Remove some commented-out code Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update a comment about run time Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Add new config to new tests from the `main` branch * Add transactions to the list, rather than replacing the list with each new block Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-09-06 06:32:33 -07:00
network: Network,
debug_force_finished_sync: bool,
debug_like_zcashd: bool,
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
mempool: Mempool,
state: State,
latest_chain_tip: Tip,
) -> (Self, JoinHandle<()>)
where
VersionString: ToString + Clone + Send + 'static,
UserAgentString: ToString + Clone + Send + 'static,
{
let (runner, queue_sender) = Queue::start();
let mut build_version = build_version.to_string();
let user_agent = user_agent.to_string();
// Match zcashd's version format, if the version string has anything in it
if !build_version.is_empty() && !build_version.starts_with('v') {
build_version.insert(0, 'v');
}
let rpc_impl = RpcImpl {
build_version,
user_agent,
add(test): test disabled `lightwalletd` mempool gRPCs via zebrad logs (#5016) * add grpc mempool test research * add a config flag for mempool injection of transactions in test * Only copy the inner state directory in the send transactions test * Preload Zcash parameters in some transaction verification tests * Add a block and transaction Hash method to convert from display order bytes * Update test coverage docs * Add debugging output for mempool transaction verification * Test fetching sent mempool transactions using gRPC * Add extra log checks to the send transaction test * Wait for zebrad mempool activation before running gRPC tests * Update send transaction test for lightwalletd not returning mempool transactions * Check zebrad logs instead of disabled lightwalletd gRPCs * Add a debug option that makes RPCs pretend the sync is finished * Remove an unused debug option * Remove unused test code and downgrade some logs * Fix test log checks * Fix some rustdoc warnings * Fix a compilation error due to new function arguments * Make zebrad sync timeouts consistent and remove outdated code * Document how to increase temporary directory space for tests * Stop checking for a log that doesn't always happen * Remove some commented-out code Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update a comment about run time Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Add new config to new tests from the `main` branch * Add transactions to the list, rather than replacing the list with each new block Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-09-06 06:32:33 -07:00
network,
debug_force_finished_sync,
debug_like_zcashd,
mempool: mempool.clone(),
state: state.clone(),
latest_chain_tip: latest_chain_tip.clone(),
queue_sender,
};
// run the process queue
let rpc_tx_queue_task_handle = tokio::spawn(
runner
.run(mempool, state, latest_chain_tip, network)
.in_current_span(),
);
(rpc_impl, rpc_tx_queue_task_handle)
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
}
}
impl<Mempool, State, Tip> Rpc for RpcImpl<Mempool, State, Tip>
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
where
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
Mempool: Service<
mempool::Request,
Response = mempool::Response,
Error = zebra_node_services::BoxError,
feat(mine): Add an internal Zcash miner to Zebra (#8136) * Patch equihash to use the solver branch * Add an internal-miner feature and set up its dependencies * Remove 'Experimental' from mining RPC docs * Fix a nightly clippy::question_mark lint * Move a byte array utility function to zebra-chain * fixup! Add an internal-miner feature and set up its dependencies * Add an equihash::Solution::solve() method with difficulty checks * Check solution is valid before returning it * Add a TODO to check for peers before mining * Move config validation into GetBlockTemplateRpcImpl::new() * fixup! fixup! Add an internal-miner feature and set up its dependencies * Use the same generic constraints for GetBlockTemplateRpcImpl struct and impls * Start adding an internal miner component * Add the miner task to the start command * Add basic miner code * Split out a method to mine one block * Spawn to a blocking thread * Wait until a valid template is available * Handle shutdown * Run mining on low priority threads * Ignore some invalid solutions * Use a difference nonce for each solver thread * Update TODOs * Change the patch into a renamed dependency to simplify crate releases * Clean up instrumentation and TODOs * Make RPC instances cloneable and clean up generics * Make LongPollId Copy so it's easier to use * Add API to restart mining if there's a new block template * Actually restart mining if there's a new block template * Tidy instrumentation * fixup! Move config validation into GetBlockTemplateRpcImpl::new() * fixup! Make RPC instances cloneable and clean up generics * Run the template generator and one miner concurrently * Reduce logging * Fix a bug in getblocktemplate RPC tip change detection * Work around some watch channel change bugs * Rate-limit template changes in the receiver * Run one mining solver per available core * Use updated C code with double-free protection * Update to the latest solver branch * Return and submit all valid solutions * Document what INPUT_LENGTH means * Fix watch channel change detection * Don't return early when a mining task fails * Spawn async miner tasks to avoid cooperative blocking, deadlocks, and improve shutdown responsiveness * Make existing parallelism docs and configs consistent * Add a mining parallelism config * Use the minimum of the configured or available threads for mining * Ignore optional feature fields in tests * Downgrade some frequent logs to debug * Document new zebrad features and tasks * Describe the internal-miner feature in the CHANGELOG * Update dependency to de-duplicate equihash solutions * Use futures::StreamExt instead of TryStreamExt * Fix a panic message typo
2024-01-11 06:41:01 -08:00
> + Clone
+ Send
+ Sync
+ 'static,
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
Mempool::Future: Send,
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
State: Service<
zebra_state::ReadRequest,
Response = zebra_state::ReadResponse,
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
Error = zebra_state::BoxError,
> + Clone
+ Send
+ Sync
+ 'static,
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
State::Future: Send,
Tip: ChainTip + Clone + Send + Sync + 'static,
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
{
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
fn get_info(&self) -> Result<GetInfo> {
let response = GetInfo {
build: self.build_version.clone(),
subversion: self.user_agent.clone(),
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
};
Ok(response)
}
// TODO: use a generic error constructor (#5548)
#[allow(clippy::unwrap_in_result)]
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
fn get_blockchain_info(&self) -> Result<GetBlockChainInfo> {
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
let network = self.network;
// `chain` field
let chain = self.network.bip70_network_name();
// `blocks` and `best_block_hash` fields
let (tip_height, tip_hash) = self
.latest_chain_tip
.best_tip_height_and_hash()
.ok_or_else(|| Error {
code: ErrorCode::ServerError(0),
message: "No Chain tip available yet".to_string(),
data: None,
})?;
// `estimated_height` field
let current_block_time =
self.latest_chain_tip
.best_tip_block_time()
.ok_or_else(|| Error {
code: ErrorCode::ServerError(0),
message: "No Chain tip available yet".to_string(),
data: None,
})?;
let zebra_estimated_height = self
.latest_chain_tip
.estimate_network_chain_tip_height(network, Utc::now())
.ok_or_else(|| Error {
code: ErrorCode::ServerError(0),
message: "No Chain tip available yet".to_string(),
data: None,
})?;
add(test): test disabled `lightwalletd` mempool gRPCs via zebrad logs (#5016) * add grpc mempool test research * add a config flag for mempool injection of transactions in test * Only copy the inner state directory in the send transactions test * Preload Zcash parameters in some transaction verification tests * Add a block and transaction Hash method to convert from display order bytes * Update test coverage docs * Add debugging output for mempool transaction verification * Test fetching sent mempool transactions using gRPC * Add extra log checks to the send transaction test * Wait for zebrad mempool activation before running gRPC tests * Update send transaction test for lightwalletd not returning mempool transactions * Check zebrad logs instead of disabled lightwalletd gRPCs * Add a debug option that makes RPCs pretend the sync is finished * Remove an unused debug option * Remove unused test code and downgrade some logs * Fix test log checks * Fix some rustdoc warnings * Fix a compilation error due to new function arguments * Make zebrad sync timeouts consistent and remove outdated code * Document how to increase temporary directory space for tests * Stop checking for a log that doesn't always happen * Remove some commented-out code Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update a comment about run time Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Add new config to new tests from the `main` branch * Add transactions to the list, rather than replacing the list with each new block Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-09-06 06:32:33 -07:00
let mut estimated_height =
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
if current_block_time > Utc::now() || zebra_estimated_height < tip_height {
tip_height
} else {
zebra_estimated_height
};
add(test): test disabled `lightwalletd` mempool gRPCs via zebrad logs (#5016) * add grpc mempool test research * add a config flag for mempool injection of transactions in test * Only copy the inner state directory in the send transactions test * Preload Zcash parameters in some transaction verification tests * Add a block and transaction Hash method to convert from display order bytes * Update test coverage docs * Add debugging output for mempool transaction verification * Test fetching sent mempool transactions using gRPC * Add extra log checks to the send transaction test * Wait for zebrad mempool activation before running gRPC tests * Update send transaction test for lightwalletd not returning mempool transactions * Check zebrad logs instead of disabled lightwalletd gRPCs * Add a debug option that makes RPCs pretend the sync is finished * Remove an unused debug option * Remove unused test code and downgrade some logs * Fix test log checks * Fix some rustdoc warnings * Fix a compilation error due to new function arguments * Make zebrad sync timeouts consistent and remove outdated code * Document how to increase temporary directory space for tests * Stop checking for a log that doesn't always happen * Remove some commented-out code Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update a comment about run time Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Add new config to new tests from the `main` branch * Add transactions to the list, rather than replacing the list with each new block Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-09-06 06:32:33 -07:00
// If we're testing the mempool, force the estimated height to be the actual tip height.
if self.debug_force_finished_sync {
estimated_height = tip_height;
}
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
// `upgrades` object
//
// Get the network upgrades in height order, like `zcashd`.
let mut upgrades = IndexMap::new();
for (activation_height, network_upgrade) in network.activation_list() {
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
// Zebra defines network upgrades based on incompatible consensus rule changes,
// but zcashd defines them based on ZIPs.
//
// All the network upgrades with a consensus branch ID are the same in Zebra and zcashd.
if let Some(branch_id) = network_upgrade.branch_id() {
// zcashd's RPC seems to ignore Disabled network upgrades, so Zebra does too.
let status = if tip_height >= activation_height {
NetworkUpgradeStatus::Active
} else {
NetworkUpgradeStatus::Pending
};
let upgrade = NetworkUpgradeInfo {
name: network_upgrade,
activation_height,
status,
};
upgrades.insert(ConsensusBranchIdHex(branch_id), upgrade);
}
}
// `consensus` object
let next_block_height =
(tip_height + 1).expect("valid chain tips are a lot less than Height::MAX");
let consensus = TipConsensusBranch {
chain_tip: ConsensusBranchIdHex(
NetworkUpgrade::current(network, tip_height)
.branch_id()
.unwrap_or(ConsensusBranchId::RPC_MISSING_ID),
),
next_block: ConsensusBranchIdHex(
NetworkUpgrade::current(network, next_block_height)
.branch_id()
.unwrap_or(ConsensusBranchId::RPC_MISSING_ID),
),
};
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
let response = GetBlockChainInfo {
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
chain,
blocks: tip_height,
best_block_hash: tip_hash,
estimated_height,
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
upgrades,
consensus,
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
};
Ok(response)
}
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
// TODO: use a generic error constructor (#5548)
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
fn get_address_balance(
&self,
address_strings: AddressStrings,
) -> BoxFuture<Result<AddressBalance>> {
let state = self.state.clone();
async move {
let valid_addresses = address_strings.valid_addresses()?;
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
let request = zebra_state::ReadRequest::AddressBalance(valid_addresses);
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
let response = state.oneshot(request).await.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
match response {
zebra_state::ReadResponse::AddressBalance(balance) => Ok(AddressBalance {
balance: u64::from(balance),
}),
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
_ => unreachable!("Unexpected response from state service: {response:?}"),
}
}
.boxed()
}
// TODO: use HexData or GetRawTransaction::Bytes to handle the transaction data argument
// use a generic error constructor (#5548)
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
fn send_raw_transaction(
&self,
raw_transaction_hex: String,
) -> BoxFuture<Result<SentTransactionHash>> {
let mempool = self.mempool.clone();
let queue_sender = self.queue_sender.clone();
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
async move {
let raw_transaction_bytes = Vec::from_hex(raw_transaction_hex).map_err(|_| {
Error::invalid_params("raw transaction is not specified as a hex string")
})?;
let raw_transaction = Transaction::zcash_deserialize(&*raw_transaction_bytes)
.map_err(|_| Error::invalid_params("raw transaction is structurally invalid"))?;
let transaction_hash = raw_transaction.hash();
// send transaction to the rpc queue, ignore any error.
let unmined_transaction = UnminedTx::from(raw_transaction.clone());
let _ = queue_sender.send(unmined_transaction);
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
let transaction_parameter = mempool::Gossip::Tx(raw_transaction.into());
let request = mempool::Request::Queue(vec![transaction_parameter]);
let response = mempool.oneshot(request).await.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let queue_results = match response {
mempool::Response::Queued(results) => results,
_ => unreachable!("incorrect response variant from mempool service"),
};
assert_eq!(
queue_results.len(),
1,
"mempool service returned more results than expected"
);
add(test): test disabled `lightwalletd` mempool gRPCs via zebrad logs (#5016) * add grpc mempool test research * add a config flag for mempool injection of transactions in test * Only copy the inner state directory in the send transactions test * Preload Zcash parameters in some transaction verification tests * Add a block and transaction Hash method to convert from display order bytes * Update test coverage docs * Add debugging output for mempool transaction verification * Test fetching sent mempool transactions using gRPC * Add extra log checks to the send transaction test * Wait for zebrad mempool activation before running gRPC tests * Update send transaction test for lightwalletd not returning mempool transactions * Check zebrad logs instead of disabled lightwalletd gRPCs * Add a debug option that makes RPCs pretend the sync is finished * Remove an unused debug option * Remove unused test code and downgrade some logs * Fix test log checks * Fix some rustdoc warnings * Fix a compilation error due to new function arguments * Make zebrad sync timeouts consistent and remove outdated code * Document how to increase temporary directory space for tests * Stop checking for a log that doesn't always happen * Remove some commented-out code Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update a comment about run time Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Add new config to new tests from the `main` branch * Add transactions to the list, rather than replacing the list with each new block Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-09-06 06:32:33 -07:00
tracing::debug!("sent transaction to mempool: {:?}", &queue_results[0]);
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
match &queue_results[0] {
Refactor `SentTransactionHash` to be a stricter type (#3706) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Implement `ToHex` and `FromHex` for `Hash` Make it easier to generate hexadecimal strings from `transaction::Hash` instances. * Use `ToHex` in `Debug` and `Display` Reduce repeated code. * Refactor to add `bytes_in_display_order` method Use it to remove repeated code and improve clarity a bit. * Use `hex::serialize` to serialize transaction hash Make the type stricter in its contents, while still serializing the transaction has as a hexadecimal string. * Simplify serialization attribute Deserialization should also use `hex::deserialize`, so using the shorter attribute makes things easier to read and more future proof. * Update zebra-chain/src/transaction/hash.rs * Remove unnecessary lifetime The anonymous lifetime is automatically inferred by the compiler. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
2022-03-08 01:14:21 -08:00
Ok(()) => Ok(SentTransactionHash(transaction_hash)),
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
Err(error) => Err(Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
}),
}
}
.boxed()
}
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
// TODO:
// - use a generic error constructor (#5548)
// - use `height_from_signed_int()` to handle negative heights
// (this might be better in the state request, because it needs the state height)
// - create a function that handles block hashes or heights, and use it in `z_get_treestate()`
fn get_block(
&self,
hash_or_height: String,
verbosity: Option<u8>,
) -> BoxFuture<Result<GetBlock>> {
// From <https://zcash.github.io/rpc/getblock.html>
const DEFAULT_GETBLOCK_VERBOSITY: u8 = 1;
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
let mut state = self.state.clone();
let verbosity = verbosity.unwrap_or(DEFAULT_GETBLOCK_VERBOSITY);
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
async move {
let hash_or_height: HashOrHeight =
hash_or_height
.parse()
.map_err(|error: SerializationError| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
if verbosity == 0 {
// # Performance
//
// This RPC is used in `lightwalletd`'s initial sync of 2 million blocks,
// so it needs to load block data very efficiently.
let request = zebra_state::ReadRequest::Block(hash_or_height);
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
match response {
zebra_state::ReadResponse::Block(Some(block)) => {
Ok(GetBlock::Raw(block.into()))
}
zebra_state::ReadResponse::Block(None) => Err(Error {
code: MISSING_BLOCK_ERROR_CODE,
message: "Block not found".to_string(),
data: None,
}),
_ => unreachable!("unmatched response to a block request"),
}
} else if verbosity == 1 {
// # Performance
//
// This RPC is used in `lightwalletd`'s initial sync of 2 million blocks,
// so it needs to load all its fields very efficiently.
//
// Currently, we get the block hash and transaction IDs from indexes,
// which is much more efficient than loading all the block data,
// then hashing the block header and all the transactions.
// Get the block hash from the height -> hash index, if needed
//
// # Concurrency
//
// For consistency, this lookup must be performed first, then all the other
// lookups must be based on the hash.
//
// All possible responses are valid, even if the best chain changes. Clients
// must be able to handle chain forks, including a hash for a block that is
// later discovered to be on a side chain.
let hash = match hash_or_height {
HashOrHeight::Hash(hash) => hash,
HashOrHeight::Height(height) => {
let request = zebra_state::ReadRequest::BestChainBlockHash(height);
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
match response {
zebra_state::ReadResponse::BlockHash(Some(hash)) => hash,
zebra_state::ReadResponse::BlockHash(None) => {
return Err(Error {
code: MISSING_BLOCK_ERROR_CODE,
message: "block height not in best chain".to_string(),
data: None,
})
}
_ => unreachable!("unmatched response to a block hash request"),
}
}
};
// TODO: do the txids and confirmations state queries in parallel?
// Get transaction IDs from the transaction index by block hash
//
// # Concurrency
//
// We look up by block hash so the hash, transaction IDs, and confirmations
// are consistent.
//
// A block's transaction IDs are never modified, so all possible responses are
// valid. Clients that query block heights must be able to handle chain forks,
// including getting transaction IDs from any chain fork.
let request = zebra_state::ReadRequest::TransactionIdsForBlock(hash.into());
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let tx = match response {
zebra_state::ReadResponse::TransactionIdsForBlock(Some(tx_ids)) => {
tx_ids.iter().map(|tx_id| tx_id.encode_hex()).collect()
}
zebra_state::ReadResponse::TransactionIdsForBlock(None) => Err(Error {
code: MISSING_BLOCK_ERROR_CODE,
message: "Block not found".to_string(),
data: None,
})?,
_ => unreachable!("unmatched response to a transaction_ids_for_block request"),
};
// Get block confirmations from the block height index
//
// # Concurrency
//
// We look up by block hash so the hash, transaction IDs, and confirmations
// are consistent.
//
// All possible responses are valid, even if a block is added to the chain, or
// the best chain changes. Clients must be able to handle chain forks, including
// different confirmation values before or after added blocks, and switching
// between -1 and multiple different confirmation values.
// From <https://zcash.github.io/rpc/getblock.html>
const NOT_IN_BEST_CHAIN_CONFIRMATIONS: i64 = -1;
let request = zebra_state::ReadRequest::Depth(hash);
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let confirmations = match response {
// Confirmations are one more than the depth.
// Depth is limited by height, so it will never overflow an i64.
zebra_state::ReadResponse::Depth(Some(depth)) => i64::from(depth) + 1,
zebra_state::ReadResponse::Depth(None) => NOT_IN_BEST_CHAIN_CONFIRMATIONS,
_ => unreachable!("unmatched response to a depth request"),
};
// TODO: look up the height if we only have a hash,
// this needs a new state request for the height -> hash index
let height = hash_or_height.height();
// Sapling trees
//
// # Concurrency
//
// We look up by block hash so the hash, transaction IDs, and confirmations
// are consistent.
let request = zebra_state::ReadRequest::SaplingTree(hash.into());
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let sapling_note_commitment_tree_count = match response {
zebra_state::ReadResponse::SaplingTree(Some(nct)) => nct.count(),
zebra_state::ReadResponse::SaplingTree(None) => 0,
_ => unreachable!("unmatched response to a SaplingTree request"),
};
// Orchard trees
//
// # Concurrency
//
// We look up by block hash so the hash, transaction IDs, and confirmations
// are consistent.
let request = zebra_state::ReadRequest::OrchardTree(hash.into());
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let orchard_note_commitment_tree_count = match response {
zebra_state::ReadResponse::OrchardTree(Some(nct)) => nct.count(),
zebra_state::ReadResponse::OrchardTree(None) => 0,
_ => unreachable!("unmatched response to a OrchardTree request"),
};
let sapling = SaplingTrees {
size: sapling_note_commitment_tree_count,
};
let orchard = OrchardTrees {
size: orchard_note_commitment_tree_count,
};
let trees = GetBlockTrees { sapling, orchard };
Ok(GetBlock::Object {
hash: GetBlockHash(hash),
confirmations,
height,
tx,
trees,
})
} else {
Err(Error {
code: ErrorCode::InvalidParams,
message: "Invalid verbosity value".to_string(),
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
data: None,
})
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
}
}
.boxed()
}
feature(rpc): Implement `getbestblockhash` method (#3754) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex * feature(rpc): add `getbestblockhash` RPC method * feature(rpc): Add a `pub struct SerializedBlockHash` type * tests(rpc): add a unit test for `getbestblockhash` method * tests(rpc): make sure no requests are sent to mempool in getbestblockhash test * tests(rpc): refactor check Co-authored-by: teor <teor@riseup.net> * fix(rpc): fixes after rebase * refactor(rpc): refactor `GetBestBlockHash` * fix(rpc): unused variables Co-authored-by: teor <teor@riseup.net> * docs(rpc): update * fix(rpc): add panic * fix(rpc): fix panic Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-10 21:13:08 -08:00
// TODO: use a generic error constructor (#5548)
fn get_best_block_hash(&self) -> Result<GetBlockHash> {
self.latest_chain_tip
.best_tip_hash()
.map(GetBlockHash)
.ok_or(Error {
code: ErrorCode::ServerError(0),
message: "No blocks in state".to_string(),
data: None,
})
feature(rpc): Implement `getbestblockhash` method (#3754) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex * feature(rpc): add `getbestblockhash` RPC method * feature(rpc): Add a `pub struct SerializedBlockHash` type * tests(rpc): add a unit test for `getbestblockhash` method * tests(rpc): make sure no requests are sent to mempool in getbestblockhash test * tests(rpc): refactor check Co-authored-by: teor <teor@riseup.net> * fix(rpc): fixes after rebase * refactor(rpc): refactor `GetBestBlockHash` * fix(rpc): unused variables Co-authored-by: teor <teor@riseup.net> * docs(rpc): update * fix(rpc): add panic * fix(rpc): fix panic Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-10 21:13:08 -08:00
}
// TODO: use a generic error constructor (#5548)
fn get_raw_mempool(&self) -> BoxFuture<Result<Vec<String>>> {
#[cfg(feature = "getblocktemplate-rpcs")]
use zebra_chain::block::MAX_BLOCK_BYTES;
#[cfg(feature = "getblocktemplate-rpcs")]
// Determines whether the output of this RPC is sorted like zcashd
let should_use_zcashd_order = self.debug_like_zcashd;
let mut mempool = self.mempool.clone();
async move {
#[cfg(feature = "getblocktemplate-rpcs")]
let request = if should_use_zcashd_order {
mempool::Request::FullTransactions
} else {
mempool::Request::TransactionIds
};
#[cfg(not(feature = "getblocktemplate-rpcs"))]
let request = mempool::Request::TransactionIds;
// `zcashd` doesn't check if it is synced to the tip here, so we don't either.
let response = mempool
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
match response {
#[cfg(feature = "getblocktemplate-rpcs")]
mempool::Response::FullTransactions {
mut transactions,
last_seen_tip_hash: _,
} => {
// Sort transactions in descending order by fee/size, using hash in serialized byte order as a tie-breaker
transactions.sort_by_cached_key(|tx| {
// zcashd uses modified fee here but Zebra doesn't currently
// support prioritizing transactions
std::cmp::Reverse((
i64::from(tx.miner_fee) as u128 * MAX_BLOCK_BYTES as u128
/ tx.transaction.size as u128,
// transaction hashes are compared in their serialized byte-order.
tx.transaction.id.mined_id(),
))
});
let tx_ids: Vec<String> = transactions
.iter()
.map(|unmined_tx| unmined_tx.transaction.id.mined_id().encode_hex())
.collect();
Ok(tx_ids)
}
mempool::Response::TransactionIds(unmined_transaction_ids) => {
let mut tx_ids: Vec<String> = unmined_transaction_ids
.iter()
.map(|id| id.mined_id().encode_hex())
.collect();
// Sort returned transaction IDs in numeric/string order.
tx_ids.sort();
Ok(tx_ids)
}
_ => unreachable!("unmatched response to a transactionids request"),
}
}
.boxed()
}
// TODO: use HexData or SentTransactionHash to handle the transaction ID
// use a generic error constructor (#5548)
fn get_raw_transaction(
&self,
txid_hex: String,
verbose: Option<u8>,
) -> BoxFuture<Result<GetRawTransaction>> {
let mut state = self.state.clone();
let mut mempool = self.mempool.clone();
let verbose = verbose.unwrap_or(0);
let verbose = verbose != 0;
async move {
let txid = transaction::Hash::from_hex(txid_hex).map_err(|_| {
Error::invalid_params("transaction ID is not specified as a hex string")
})?;
// Check the mempool first.
//
// # Correctness
//
// Transactions are removed from the mempool after they are mined into blocks,
// so the transaction could be just in the mempool, just in the state, or in both.
// (And the mempool and state transactions could have different authorising data.)
// But it doesn't matter which transaction we choose, because the effects are the same.
let mut txid_set = HashSet::new();
txid_set.insert(txid);
let request = mempool::Request::TransactionsByMinedId(txid_set);
let response = mempool
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
match response {
mempool::Response::Transactions(unmined_transactions) => {
if !unmined_transactions.is_empty() {
let tx = unmined_transactions[0].transaction.clone();
return Ok(GetRawTransaction::from_transaction(tx, None, 0, verbose));
}
}
_ => unreachable!("unmatched response to a transactionids request"),
};
// Now check the state
let request = zebra_state::ReadRequest::Transaction(txid);
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
match response {
zebra_state::ReadResponse::Transaction(Some(MinedTx {
tx,
height,
confirmations,
})) => Ok(GetRawTransaction::from_transaction(
tx,
Some(height),
confirmations,
verbose,
)),
zebra_state::ReadResponse::Transaction(None) => Err(Error {
code: ErrorCode::ServerError(0),
message: "Transaction not found".to_string(),
data: None,
}),
_ => unreachable!("unmatched response to a transaction request"),
}
}
.boxed()
}
// TODO:
// - use a generic error constructor (#5548)
// - use `height_from_signed_int()` to handle negative heights
// (this might be better in the state request, because it needs the state height)
// - create a function that handles block hashes or heights, and use it in `get_block()`
feat(rpc): Implement `z_gettreestate` RPC (#3990) * Impl the elementary structure of the `z_gettreestate` RPC * Fix merging bugs * Fix a merge bug * Fix a merge bug * Move a derive attribute Co-authored-by: teor <teor@riseup.net> * Clarify the support of negative heights * Add Orchard note commitment trees to the response * Add the time to the response * Finalize the `z_gettreestate` RPC * Add a note that verified blocks have coinbase height * Refactor `from_str` for `HashOrHeight` * Fix a mistake in the docs Co-authored-by: teor <teor@riseup.net> * Clarify request types Co-authored-by: teor <teor@riseup.net> * Simplify `hash_or_height` conversion to height Co-authored-by: teor <teor@riseup.net> * Add a TODO about optimization Co-authored-by: teor <teor@riseup.net> * Add a doc comment * Make sure Sapling & Orchard trees don't get mixed up * Serialize Sapling commitment trees * Refactor some comments * Serialize Orchard commitment trees * Serialize block heights * Simplify the serialization of commitment trees * Remove the block time from the RPC response * Simplify the serialization of block heights * Put Sapling & Orchard requests together * Remove a redundant TODO * Add block times to the RPC response * Derive `Clone, Debug, Eq, PartialEq` for `GetTreestate` Co-authored-by: teor <teor@riseup.net> * Derive `Clone`, `Debug`, `Eq` and `PartialEq` for `SerializedTree` * Document the fields of `GetTreestate` * Skip the serialization of empty trees This ensures compatibility with `zcashd` in the `z_gettreestate` RPC. * Document the `impl` of `merkle_tree::Hashable` for nodes * Make the structure of the JSON response consistent with `zcashd` * Derive `Eq` for nodes Co-authored-by: teor <teor@riseup.net> * Convert Sapling commitment trees to a format compatible with zcashd * Refactor the conversion of Sapling commitment trees * Refactor some comments * Refactor comments * Add a description of the conversion Co-authored-by: Conrado Gouvea <conrado@zfnd.org> * Fix comment indenting * Document the conversion between the dense and sparse formats Co-authored-by: teor <teor@riseup.net> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
2022-05-12 00:00:12 -07:00
fn z_get_treestate(&self, hash_or_height: String) -> BoxFuture<Result<GetTreestate>> {
let mut state = self.state.clone();
async move {
// Convert the [`hash_or_height`] string into an actual hash or height.
let hash_or_height = hash_or_height
.parse()
.map_err(|error: SerializationError| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
// Fetch the block referenced by [`hash_or_height`] from the state.
// TODO: If this RPC is called a lot, just get the block header,
// rather than the whole block.
let block_request = zebra_state::ReadRequest::Block(hash_or_height);
let block_response = state
.ready()
.and_then(|service| service.call(block_request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
// The block hash, height, and time are all required fields in the
// RPC response. For this reason, we throw an error early if the
// state didn't return the requested block so that we prevent
// further state queries.
let block = match block_response {
zebra_state::ReadResponse::Block(Some(block)) => block,
zebra_state::ReadResponse::Block(None) => {
return Err(Error {
code: MISSING_BLOCK_ERROR_CODE,
feat(rpc): Implement `z_gettreestate` RPC (#3990) * Impl the elementary structure of the `z_gettreestate` RPC * Fix merging bugs * Fix a merge bug * Fix a merge bug * Move a derive attribute Co-authored-by: teor <teor@riseup.net> * Clarify the support of negative heights * Add Orchard note commitment trees to the response * Add the time to the response * Finalize the `z_gettreestate` RPC * Add a note that verified blocks have coinbase height * Refactor `from_str` for `HashOrHeight` * Fix a mistake in the docs Co-authored-by: teor <teor@riseup.net> * Clarify request types Co-authored-by: teor <teor@riseup.net> * Simplify `hash_or_height` conversion to height Co-authored-by: teor <teor@riseup.net> * Add a TODO about optimization Co-authored-by: teor <teor@riseup.net> * Add a doc comment * Make sure Sapling & Orchard trees don't get mixed up * Serialize Sapling commitment trees * Refactor some comments * Serialize Orchard commitment trees * Serialize block heights * Simplify the serialization of commitment trees * Remove the block time from the RPC response * Simplify the serialization of block heights * Put Sapling & Orchard requests together * Remove a redundant TODO * Add block times to the RPC response * Derive `Clone, Debug, Eq, PartialEq` for `GetTreestate` Co-authored-by: teor <teor@riseup.net> * Derive `Clone`, `Debug`, `Eq` and `PartialEq` for `SerializedTree` * Document the fields of `GetTreestate` * Skip the serialization of empty trees This ensures compatibility with `zcashd` in the `z_gettreestate` RPC. * Document the `impl` of `merkle_tree::Hashable` for nodes * Make the structure of the JSON response consistent with `zcashd` * Derive `Eq` for nodes Co-authored-by: teor <teor@riseup.net> * Convert Sapling commitment trees to a format compatible with zcashd * Refactor the conversion of Sapling commitment trees * Refactor some comments * Refactor comments * Add a description of the conversion Co-authored-by: Conrado Gouvea <conrado@zfnd.org> * Fix comment indenting * Document the conversion between the dense and sparse formats Co-authored-by: teor <teor@riseup.net> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
2022-05-12 00:00:12 -07:00
message: "the requested block was not found".to_string(),
data: None,
})
}
_ => unreachable!("unmatched response to a block request"),
};
// Fetch the Sapling & Orchard treestates referenced by
// [`hash_or_height`] from the state.
let sapling_request = zebra_state::ReadRequest::SaplingTree(hash_or_height);
let sapling_response = state
.ready()
.and_then(|service| service.call(sapling_request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let orchard_request = zebra_state::ReadRequest::OrchardTree(hash_or_height);
let orchard_response = state
.ready()
.and_then(|service| service.call(orchard_request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
// We've got all the data we need for the RPC response, so we
// assemble the response.
let hash = block.hash();
let height = block
.coinbase_height()
.expect("verified blocks have a valid height");
let time = u32::try_from(block.header.time.timestamp())
.expect("Timestamps of valid blocks always fit into u32.");
let sapling_tree = match sapling_response {
zebra_state::ReadResponse::SaplingTree(maybe_tree) => {
sapling::tree::SerializedTree::from(maybe_tree)
}
_ => unreachable!("unmatched response to a sapling tree request"),
};
let orchard_tree = match orchard_response {
zebra_state::ReadResponse::OrchardTree(maybe_tree) => {
orchard::tree::SerializedTree::from(maybe_tree)
}
_ => unreachable!("unmatched response to an orchard tree request"),
};
Ok(GetTreestate {
hash,
height,
time,
sapling: Treestate {
commitments: Commitments {
final_state: sapling_tree,
},
},
orchard: Treestate {
commitments: Commitments {
final_state: orchard_tree,
},
},
})
}
.boxed()
}
fn z_get_subtrees_by_index(
&self,
pool: String,
start_index: NoteCommitmentSubtreeIndex,
limit: Option<NoteCommitmentSubtreeIndex>,
) -> BoxFuture<Result<GetSubtrees>> {
let mut state = self.state.clone();
async move {
const POOL_LIST: &[&str] = &["sapling", "orchard"];
if pool == "sapling" {
let request = zebra_state::ReadRequest::SaplingSubtrees { start_index, limit };
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let subtrees = match response {
zebra_state::ReadResponse::SaplingSubtrees(subtrees) => subtrees,
_ => unreachable!("unmatched response to a subtrees request"),
};
let subtrees = subtrees
.values()
.map(|subtree| SubtreeRpcData {
root: subtree.root.encode_hex(),
end_height: subtree.end_height,
})
.collect();
Ok(GetSubtrees {
pool,
start_index,
subtrees,
})
} else if pool == "orchard" {
let request = zebra_state::ReadRequest::OrchardSubtrees { start_index, limit };
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let subtrees = match response {
zebra_state::ReadResponse::OrchardSubtrees(subtrees) => subtrees,
_ => unreachable!("unmatched response to a subtrees request"),
};
let subtrees = subtrees
.values()
.map(|subtree| SubtreeRpcData {
root: subtree.root.encode_hex(),
end_height: subtree.end_height,
})
.collect();
Ok(GetSubtrees {
pool,
start_index,
subtrees,
})
} else {
Err(Error {
code: INVALID_PARAMETERS_ERROR_CODE,
message: format!("invalid pool name, must be one of: {:?}", POOL_LIST),
data: None,
})
}
}
.boxed()
}
// TODO: use a generic error constructor (#5548)
fn get_address_tx_ids(
&self,
request: GetAddressTxIdsRequest,
) -> BoxFuture<Result<Vec<String>>> {
let mut state = self.state.clone();
let latest_chain_tip = self.latest_chain_tip.clone();
let start = Height(request.start);
let end = Height(request.end);
async move {
let chain_height = best_chain_tip_height(&latest_chain_tip)?;
// height range checks
check_height_range(start, end, chain_height)?;
let valid_addresses = AddressStrings {
addresses: request.addresses,
}
.valid_addresses()?;
let request = zebra_state::ReadRequest::TransactionIdsByAddresses {
addresses: valid_addresses,
height_range: start..=end,
};
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let hashes = match response {
zebra_state::ReadResponse::AddressesTransactionIds(hashes) => {
let mut last_tx_location = TransactionLocation::from_usize(Height(0), 0);
hashes
.iter()
.map(|(tx_loc, tx_id)| {
change(state): Write finalized blocks to the state in a separate thread, to avoid network and RPC hangs (#5134) * Add a new block commit task and channels, that don't do anything yet * Add last_block_hash_sent to the state service, to avoid database accesses * Update last_block_hash_sent regardless of commit errors * Rename a field to StateService.max_queued_finalized_height * Commit finalized blocks to the state in a separate task * Check for panics in the block write task * Wait for the block commit task in tests, and check for errors * Always run a proptest that sleeps once * Add extra debugging to state shutdowns * Work around a RocksDB shutdown bug * Close the finalized block channel when we're finished with it * Only reset state queue once per error * Update some TODOs * Add a module doc comment * Drop channels and check for closed channels in the block commit task * Close state channels and tasks on drop * Remove some duplicate fields across StateService and ReadStateService * Try tweaking the shutdown steps * Update and clarify some comments * Clarify another comment * Don't try to cancel RocksDB background work on drop * Fix up some comments * Remove some duplicate code * Remove redundant workarounds for shutdown issues * Remode a redundant channel close in the block commit task * Remove a mistaken `!force` shutdown condition * Remove duplicate force-shutdown code and explain it better * Improve RPC error logging * Wait for chain tip updates in the RPC tests * Wait 2 seconds for chain tip updates before skipping them * Remove an unnecessary block_in_place() * Fix some test error messages that were changed by earlier fixes * Expand some comments, fix typos Co-authored-by: Marek <mail@marek.onl> * Actually drop children of failed blocks * Explain why we drop descendants of failed blocks * Clarify a comment * Wait for chain tip updates in a failing test on macOS * Clean duplicate finalized blocks when the non-finalized state activates * Send an error when receiving a duplicate finalized block * Update checkpoint block behaviour, document its consensus rule * Wait for chain tip changes in inbound_block_height_lookahead_limit test * Wait for the genesis block to commit in the fake peer set mempool tests * Disable unreliable mempool verification check in the send transaction test * Appease rustfmt * Use clear_finalized_block_queue() everywhere that blocks are dropped * Document how Finalized and NonFinalized clones are different * Use the same check as commit_finalized() for finalized block heights Co-authored-by: Marek <mail@marek.onl> Co-authored-by: Marek <mail@marek.onl>
2022-09-28 09:09:56 -07:00
// Check that the returned transactions are in chain order.
assert!(
*tx_loc > last_tx_location,
"Transactions were not in chain order:\n\
{tx_loc:?} {tx_id:?} was after:\n\
{last_tx_location:?}",
);
last_tx_location = *tx_loc;
tx_id.to_string()
})
.collect()
}
_ => unreachable!("unmatched response to a TransactionsByAddresses request"),
};
Ok(hashes)
}
.boxed()
}
// TODO: use a generic error constructor (#5548)
fn get_address_utxos(
&self,
address_strings: AddressStrings,
) -> BoxFuture<Result<Vec<GetAddressUtxos>>> {
let mut state = self.state.clone();
let mut response_utxos = vec![];
async move {
let valid_addresses = address_strings.valid_addresses()?;
// get utxos data for addresses
let request = zebra_state::ReadRequest::UtxosByAddresses(valid_addresses);
let response = state
.ready()
.and_then(|service| service.call(request))
.await
.map_err(|error| Error {
code: ErrorCode::ServerError(0),
message: error.to_string(),
data: None,
})?;
let utxos = match response {
zebra_state::ReadResponse::AddressUtxos(utxos) => utxos,
_ => unreachable!("unmatched response to a UtxosByAddresses request"),
};
let mut last_output_location = OutputLocation::from_usize(Height(0), 0, 0);
for utxo_data in utxos.utxos() {
let address = utxo_data.0;
let txid = *utxo_data.1;
let height = utxo_data.2.height();
let output_index = utxo_data.2.output_index();
let script = utxo_data.3.lock_script.clone();
let satoshis = u64::from(utxo_data.3.value);
let output_location = *utxo_data.2;
change(state): Write finalized blocks to the state in a separate thread, to avoid network and RPC hangs (#5134) * Add a new block commit task and channels, that don't do anything yet * Add last_block_hash_sent to the state service, to avoid database accesses * Update last_block_hash_sent regardless of commit errors * Rename a field to StateService.max_queued_finalized_height * Commit finalized blocks to the state in a separate task * Check for panics in the block write task * Wait for the block commit task in tests, and check for errors * Always run a proptest that sleeps once * Add extra debugging to state shutdowns * Work around a RocksDB shutdown bug * Close the finalized block channel when we're finished with it * Only reset state queue once per error * Update some TODOs * Add a module doc comment * Drop channels and check for closed channels in the block commit task * Close state channels and tasks on drop * Remove some duplicate fields across StateService and ReadStateService * Try tweaking the shutdown steps * Update and clarify some comments * Clarify another comment * Don't try to cancel RocksDB background work on drop * Fix up some comments * Remove some duplicate code * Remove redundant workarounds for shutdown issues * Remode a redundant channel close in the block commit task * Remove a mistaken `!force` shutdown condition * Remove duplicate force-shutdown code and explain it better * Improve RPC error logging * Wait for chain tip updates in the RPC tests * Wait 2 seconds for chain tip updates before skipping them * Remove an unnecessary block_in_place() * Fix some test error messages that were changed by earlier fixes * Expand some comments, fix typos Co-authored-by: Marek <mail@marek.onl> * Actually drop children of failed blocks * Explain why we drop descendants of failed blocks * Clarify a comment * Wait for chain tip updates in a failing test on macOS * Clean duplicate finalized blocks when the non-finalized state activates * Send an error when receiving a duplicate finalized block * Update checkpoint block behaviour, document its consensus rule * Wait for chain tip changes in inbound_block_height_lookahead_limit test * Wait for the genesis block to commit in the fake peer set mempool tests * Disable unreliable mempool verification check in the send transaction test * Appease rustfmt * Use clear_finalized_block_queue() everywhere that blocks are dropped * Document how Finalized and NonFinalized clones are different * Use the same check as commit_finalized() for finalized block heights Co-authored-by: Marek <mail@marek.onl> Co-authored-by: Marek <mail@marek.onl>
2022-09-28 09:09:56 -07:00
// Check that the returned UTXOs are in chain order.
assert!(
output_location > last_output_location,
"UTXOs were not in chain order:\n\
{output_location:?} {address:?} {txid:?} was after:\n\
{last_output_location:?}",
);
let entry = GetAddressUtxos {
address,
txid,
output_index,
script,
satoshis,
height,
};
response_utxos.push(entry);
last_output_location = output_location;
}
Ok(response_utxos)
}
.boxed()
}
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
}
/// Returns the best chain tip height of `latest_chain_tip`,
/// or an RPC error if there are no blocks in the state.
pub fn best_chain_tip_height<Tip>(latest_chain_tip: &Tip) -> Result<Height>
where
Tip: ChainTip + Clone + Send + Sync + 'static,
{
latest_chain_tip.best_tip_height().ok_or(Error {
code: ErrorCode::ServerError(0),
message: "No blocks in state".to_string(),
data: None,
})
}
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
/// Response to a `getinfo` RPC request.
///
/// See the notes for the [`Rpc::get_info` method].
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
pub struct GetInfo {
/// The node version build number
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
build: String,
/// The server sub-version identifier, used as the network protocol user-agent
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
subversion: String,
}
/// Response to a `getblockchaininfo` RPC request.
///
/// See the notes for the [`Rpc::get_blockchain_info` method].
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
pub struct GetBlockChainInfo {
/// Current network name as defined in BIP70 (main, test, regtest)
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
chain: String,
/// The current number of blocks processed in the server, numeric
blocks: Height,
/// The hash of the currently best block, in big-endian order, hex-encoded
#[serde(rename = "bestblockhash", with = "hex")]
best_block_hash: block::Hash,
/// If syncing, the estimated height of the chain, else the current best height, numeric.
///
/// In Zebra, this is always the height estimate, so it might be a little inaccurate.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[serde(rename = "estimatedheight")]
estimated_height: Height,
/// Status of network upgrades
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
upgrades: IndexMap<ConsensusBranchIdHex, NetworkUpgradeInfo>,
/// Branch IDs of the current and upcoming consensus rules
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
consensus: TipConsensusBranch,
}
/// A wrapper type with a list of transparent address strings.
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
///
/// This is used for the input parameter of [`Rpc::get_address_balance`],
/// [`Rpc::get_address_tx_ids`] and [`Rpc::get_address_utxos`].
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
#[derive(Clone, Debug, Eq, PartialEq, Hash, serde::Deserialize)]
pub struct AddressStrings {
/// A list of transparent address strings.
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
addresses: Vec<String>,
}
impl AddressStrings {
/// Creates a new `AddressStrings` given a vector.
#[cfg(test)]
pub fn new(addresses: Vec<String>) -> AddressStrings {
AddressStrings { addresses }
}
/// Given a list of addresses as strings:
/// - check if provided list have all valid transparent addresses.
/// - return valid addresses as a set of `Address`.
pub fn valid_addresses(self) -> Result<HashSet<Address>> {
let valid_addresses: HashSet<Address> = self
.addresses
.into_iter()
.map(|address| {
address.parse().map_err(|error| {
Error::invalid_params(format!("invalid address {address:?}: {error}"))
})
})
.collect::<Result<_>>()?;
Ok(valid_addresses)
}
}
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
/// The transparent balance of a set of addresses.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, serde::Serialize)]
pub struct AddressBalance {
/// The total transparent balance.
balance: u64,
feat(rpc): Implement `getaddressbalance` RPC (#4138) * Add `Amount::serialize_as_string` helper method A helper method that makes it easier to serialize an `Amount` as a string. This is needed for the response type of the `getaccountbalance` RPC. * Implement state service call for address balance Add `Read{Request,Response}::AddressBalance` variants and implement the handler that calls the query function. * Create an `AddressBalance` response type Only contains the `balance` field which is needed by `lightwalletd`. That field is serialized as a string, following the RPC specification. * Implement `get_address_balance` RPC Query the read-only state service for the information, and wrap it in an `AddressBalance` response type so that it is serialized correctly. * Run `rustfmt` inside `proptest!` block Fix some minor formatting details. * Test `get_address_balance` with valid addresses Check that the RPC leads to a query to the mocked state service for a balance amount. * Test `get_address_balance` with invalid addresses An error message should be returned by the RPC. * Rename metric to `address_balance` Keep it consistent with how it's named in other places. Co-authored-by: teor <teor@riseup.net> * Revert "Add `Amount::serialize_as_string` helper method" This reverts commit 01b432e3d2ac2313a90d55d06b3fa855c0b71330. * Serialize amount as an integer This is different from what the documentation says, but it's what lightwalletd expects. * Add reference to RPC documentation Make sure it is linked to for easy access. * Create an `AddressStrings` type To be used as the input for the `get_address_balance` RPC method. * Use `AddressStrings` in `get_address_balance` RPC Fix the input parameter so that the list of address strings is placed inside a JSON map. * Update property tests to use `AddressStrings` Make sure the proper input type is created. Co-authored-by: teor <teor@riseup.net>
2022-04-20 11:27:00 -07:00
}
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
/// A hex-encoded [`ConsensusBranchId`] string.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
struct ConsensusBranchIdHex(#[serde(with = "hex")] ConsensusBranchId);
/// Information about [`NetworkUpgrade`] activation.
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
struct NetworkUpgradeInfo {
/// Name of upgrade, string.
///
/// Ignored by lightwalletd, but useful for debugging.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
name: NetworkUpgrade,
/// Block height of activation, numeric.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[serde(rename = "activationheight")]
activation_height: Height,
/// Status of upgrade, string.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
status: NetworkUpgradeStatus,
}
/// The activation status of a [`NetworkUpgrade`].
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
enum NetworkUpgradeStatus {
/// The network upgrade is currently active.
///
/// Includes all network upgrades that have previously activated,
/// even if they are not the most recent network upgrade.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[serde(rename = "active")]
Active,
/// The network upgrade does not have an activation height.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[serde(rename = "disabled")]
Disabled,
/// The network upgrade has an activation height, but we haven't reached it yet.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[serde(rename = "pending")]
Pending,
}
/// The [`ConsensusBranchId`]s for the tip and the next block.
///
/// These branch IDs are different when the next block is a network upgrade activation block.
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
struct TipConsensusBranch {
/// Branch ID used to validate the current chain tip, big-endian, hex-encoded.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[serde(rename = "chaintip")]
chain_tip: ConsensusBranchIdHex,
/// Branch ID used to validate the next block, big-endian, hex-encoded.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[serde(rename = "nextblock")]
next_block: ConsensusBranchIdHex,
feature(rpc): add an rpc server to Zebra (#3589) * feature(rpc): add an rpc component * feat(rpc): add a stub for getblockchaininfo This is the first RPC used by lightwalletd, so we need it for testing. * fix(rpc): remove non-standard "jsonrpc: 1.0" from lightwalletd * fix(rpc): re-enable default RPC security checks * deps(rpc): remove not needed dependency * fix(rpc): check if RPC task has stopped * fix(rpc): reduce config by using Option * fix(rpc): use tokio executor * security(rpc): turn off rpc by default * docs(rpc): update a TODO comment Co-authored-by: teor <teor@riseup.net> * fix(rpc): blocking tasks Co-authored-by: teor <teor@riseup.net> * rename(rpc): rpc.rs to methods.rs * refactor(rpc): move the server to the zebra-rpc crate * fix(rpc): clippy derive Default for RPC Config * fix(dependencies): remove unused dependency features in zebra-rpc We expect to use all the listed tokio features to implement and test RPC methods. * doc(rpc): fix testnet port, add security note * fix(rpc): change Rust function names and update method doc TODOs * fix(rpc): add "TODO" to fake RPC responses * doc(rpc): update module docs * fix(rpc): simplify server struct derives * fix(rpc): simplify server code * doc(rpc): explain how request fixes securely handle user-supplied data * refactor(rpc): move the compatibility fix to a separate module * fix(rpc): move the open log inside the spawn, and instrument it * doc(rpc): fix toml format and provide a config example Co-authored-by: teor <teor@riseup.net>
2022-02-22 03:26:29 -08:00
}
Implement `sendrawtransaction` RPC (#3685) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Remove mempool service usage line It contained incomplete information that's not really necessary. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Fix formatting `rustfmt` was not executed on the file for the previous commit because I had edited it on GitHub. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
2022-03-03 23:00:24 -08:00
/// Response to a `sendrawtransaction` RPC request.
///
/// Contains the hex-encoded hash of the sent transaction.
///
/// See the notes for the [`Rpc::send_raw_transaction` method].
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
Refactor `SentTransactionHash` to be a stricter type (#3706) * Stub `sendrawtransaction` RPC method Register the RPC method, and stub an implementation that currently just panics. The method has a single `String` parameter with the hexadecimal string of the raw transaction's bytes and returns a `SentTransactionHash` wrapper type that's just a hexadecimal `String` of the sent transaction's hash. * Add mempool service instance to `RpcImpl` Use a type parameter to represent the mempool service using the interface defined by `zebra-node-services`. * Update test vector to use a mock mempool service Update the test to be compatible with the changes to `RpcImpl`. The mock mempool service is expected to not be used during the test. * Use a `tower::Buffer` for the mempool service Make it simpler to send requests to the service in a concurrent manner. * Return a `Future` from `send_raw_transaction` Make the call asynchronous. * Implement `sendrawtransaction` RPC Deserialize the transaction and send it to be queued for verification and subsequent inclusion in the mempool. * Test if mempool receives sent raw transaction Use a mock service as the mempool service and check that it receives a sent raw transaction. * Test using non-hexadecimal string parameter The method should return an error. * Test with bytes that fail deserialization Check that the method returns an invalid parameters error if the input can't be deserialized as a `Transaction`. * Test if mempool errors are forwarded to caller Mempool service errors should be sent back to the remote caller as server errors. * Test transactions rejected by the mempool service Transactions that are rejected by the mempool service should result in a server error being sent to the caller. * Improve error message Add the word "structurally" to make it clear that the issue is in the transaction's deserialization. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Add note regarding missing `allowhighfees` param. The parameter isn't supported yet because `lightwalletd` doesn't use it. * Update the documentation to be consistent Follow the convention adopted by the `get_info` RPC method. * Implement `ToHex` and `FromHex` for `Hash` Make it easier to generate hexadecimal strings from `transaction::Hash` instances. * Use `ToHex` in `Debug` and `Display` Reduce repeated code. * Refactor to add `bytes_in_display_order` method Use it to remove repeated code and improve clarity a bit. * Use `hex::serialize` to serialize transaction hash Make the type stricter in its contents, while still serializing the transaction has as a hexadecimal string. * Simplify serialization attribute Deserialization should also use `hex::deserialize`, so using the shorter attribute makes things easier to read and more future proof. * Update zebra-chain/src/transaction/hash.rs * Remove unnecessary lifetime The anonymous lifetime is automatically inferred by the compiler. Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
2022-03-08 01:14:21 -08:00
pub struct SentTransactionHash(#[serde(with = "hex")] transaction::Hash);
feature(rpc): implement getblock api call (#3707) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-09 17:12:41 -08:00
/// Response to a `getblock` RPC request.
///
/// See the notes for the [`Rpc::get_block`] method.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
#[serde(untagged)]
pub enum GetBlock {
/// The request block, hex-encoded.
Raw(#[serde(with = "hex")] SerializedBlock),
/// The block object.
Object {
/// The hash of the requested block.
hash: GetBlockHash,
/// The number of confirmations of this block in the best chain,
/// or -1 if it is not in the best chain.
confirmations: i64,
/// The height of the requested block.
#[serde(skip_serializing_if = "Option::is_none")]
height: Option<Height>,
/// List of transaction IDs in block order, hex-encoded.
//
// TODO: use a typed Vec<transaction::Hash> here
tx: Vec<String>,
/// Information about the note commitment trees.
trees: GetBlockTrees,
},
}
feature(rpc): Implement `getbestblockhash` method (#3754) * feature(rpc): start adding a `getblock` method * fix(rpc): replace oneshot * fix(rpc): replace a panic with error * fix(rpc): fix test * feature(rpc): add hex to response * refactor(rpc): use generic instead of alias * docs(rpc): improve docs for getblock method * test(rpc): add a test for getblock method * deps(rpc): remove non needed tower features Co-authored-by: teor <teor@riseup.net> * docs(rpc): add a note to getblock doc * refactor(rpc): replace alias * fix(rpc): use `zcash_serialize_to_vec()` instead of logging format * tests(rpc): add network argument to `populated_state()` * refactor(rpc): use an error for state service readiness * fix(rpc): add parameter * fix(rpc): clippy * nit(rpc): remove new line from imports * fix(rpc): remove commented code * fix(rpc): simplify error Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * Use a `SerializedBlock` type to help serializing blocks (#3725) * Create a `SerializedBlock` helper type Create a type that can be used as a byte slice, but is guaranteed to represent a valid block. * Use `into_iter` instead of `iter` There's no need to borrow the elements, they can be moved out directly. This will be necessary because `&Arc<T>` doesn't implement `Borrow<T>`, so a `SerializedBlock` can't be built directly from an `&Arc<Block>`. * Use `SerializedBlock` in `GetBlock` Make the type stricter to avoid storing possibly invalid values. The bytes are still serialized as a hexadecimal string, through the usage of `hex`. The `serde::Deserialize` can't be derived because `hex` requires the type to also implement `FromHex`. * feature(rpc): add suggestions from code review Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * tests(rpc): make sure mempool has no requests in get_block test * fix(rpc): change height argument type in getblock method * fix(rpc): rustfmt * fix(rpc): replace panic * fix(rpc): change getblock response * fix(rpc): fix lightwalletd test * tests(rpc): add a getblock error test * fix(rpc): try another regex * feature(rpc): add `getbestblockhash` RPC method * feature(rpc): Add a `pub struct SerializedBlockHash` type * tests(rpc): add a unit test for `getbestblockhash` method * tests(rpc): make sure no requests are sent to mempool in getbestblockhash test * tests(rpc): refactor check Co-authored-by: teor <teor@riseup.net> * fix(rpc): fixes after rebase * refactor(rpc): refactor `GetBestBlockHash` * fix(rpc): unused variables Co-authored-by: teor <teor@riseup.net> * docs(rpc): update * fix(rpc): add panic * fix(rpc): fix panic Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
2022-03-10 21:13:08 -08:00
/// Response to a `getbestblockhash` and `getblockhash` RPC request.
///
/// Contains the hex-encoded hash of the requested block.
///
/// Also see the notes for the [`Rpc::get_best_block_hash`] and `get_block_hash` methods.
feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-03-25 05:25:31 -07:00
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
change(test): Create test harness for calling getblocktemplate in proposal mode, but don't use it yet (#5884) * adds ValidateBlock request to state * adds `Request` enum in block verifier skips solution check for BlockProposal requests calls CheckBlockValidity instead of Commit block for BlockProposal requests * uses new Request in references to chain verifier * adds getblocktemplate proposal mode response type * makes getblocktemplate-rpcs feature in zebra-consensus select getblocktemplate-rpcs in zebra-state * Adds PR review revisions * adds info log in CheckBlockProposalValidity * Reverts replacement of match statement * adds `GetBlockTemplate::capabilities` fn * conditions calling checkpoint verifier on !request.is_proposal * updates references to validate_and_commit_non_finalized * adds snapshot test, updates test vectors * adds `should_count_metrics` to NonFinalizedState * Returns an error from chain verifier for block proposal requests below checkpoint height adds feature flags * adds "proposal" to GET_BLOCK_TEMPLATE_CAPABILITIES_FIELD * adds back block::Request to zebra-consensus lib * updates snapshots * Removes unnecessary network arg * skips req in tracing intstrument for read state * Moves out block proposal validation to its own fn * corrects `difficulty_threshold_is_valid` docs adds/fixes some comments, adds TODOs general cleanup from a self-review. * Update zebra-state/src/service.rs * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * Update zebra-rpc/src/methods/get_block_template_rpcs.rs Co-authored-by: teor <teor@riseup.net> * check best chain tip * Update zebra-state/src/service.rs Co-authored-by: teor <teor@riseup.net> * Applies cleanup suggestions from code review * updates gbt acceptance test to make a block proposal * fixes json parsing mistake * adds retries * returns reject reason if there are no retries left * moves result deserialization to RPCRequestClient method, adds docs, moves jsonrpc_core to dev-dependencies * moves sleep(EXPECTED_TX_TIME) out of loop * updates/adds info logs in retry loop * Revert "moves sleep(EXPECTED_TX_TIME) out of loop" This reverts commit f7f0926f4050519687a79afc16656c3f345c004b. * adds `allow(dead_code)` * tests with curtime, mintime, & maxtime * Fixes doc comment * Logs error responses from chain_verifier CheckProposal requests * Removes retry loop, adds num_txs log * removes verbose info log * sorts mempool_txs before generating merkle root * Make imports conditional on a feature * Disable new CI tests until bugs are fixed Co-authored-by: teor <teor@riseup.net> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-01-16 20:03:40 -08:00
pub struct GetBlockHash(#[serde(with = "hex")] pub block::Hash);
feat(rpc): Implement `z_gettreestate` RPC (#3990) * Impl the elementary structure of the `z_gettreestate` RPC * Fix merging bugs * Fix a merge bug * Fix a merge bug * Move a derive attribute Co-authored-by: teor <teor@riseup.net> * Clarify the support of negative heights * Add Orchard note commitment trees to the response * Add the time to the response * Finalize the `z_gettreestate` RPC * Add a note that verified blocks have coinbase height * Refactor `from_str` for `HashOrHeight` * Fix a mistake in the docs Co-authored-by: teor <teor@riseup.net> * Clarify request types Co-authored-by: teor <teor@riseup.net> * Simplify `hash_or_height` conversion to height Co-authored-by: teor <teor@riseup.net> * Add a TODO about optimization Co-authored-by: teor <teor@riseup.net> * Add a doc comment * Make sure Sapling & Orchard trees don't get mixed up * Serialize Sapling commitment trees * Refactor some comments * Serialize Orchard commitment trees * Serialize block heights * Simplify the serialization of commitment trees * Remove the block time from the RPC response * Simplify the serialization of block heights * Put Sapling & Orchard requests together * Remove a redundant TODO * Add block times to the RPC response * Derive `Clone, Debug, Eq, PartialEq` for `GetTreestate` Co-authored-by: teor <teor@riseup.net> * Derive `Clone`, `Debug`, `Eq` and `PartialEq` for `SerializedTree` * Document the fields of `GetTreestate` * Skip the serialization of empty trees This ensures compatibility with `zcashd` in the `z_gettreestate` RPC. * Document the `impl` of `merkle_tree::Hashable` for nodes * Make the structure of the JSON response consistent with `zcashd` * Derive `Eq` for nodes Co-authored-by: teor <teor@riseup.net> * Convert Sapling commitment trees to a format compatible with zcashd * Refactor the conversion of Sapling commitment trees * Refactor some comments * Refactor comments * Add a description of the conversion Co-authored-by: Conrado Gouvea <conrado@zfnd.org> * Fix comment indenting * Document the conversion between the dense and sparse formats Co-authored-by: teor <teor@riseup.net> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
2022-05-12 00:00:12 -07:00
/// Response to a `z_gettreestate` RPC request.
///
/// Contains the hex-encoded Sapling & Orchard note commitment trees, and their
/// corresponding [`block::Hash`], [`Height`], and block time.
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
pub struct GetTreestate {
/// The block hash corresponding to the treestate, hex-encoded.
#[serde(with = "hex")]
hash: block::Hash,
/// The block height corresponding to the treestate, numeric.
height: Height,
/// Unix time when the block corresponding to the treestate was mined,
/// numeric.
///
/// UTC seconds since the Unix 1970-01-01 epoch.
time: u32,
/// A treestate containing a Sapling note commitment tree, hex-encoded.
#[serde(skip_serializing_if = "Treestate::is_empty")]
sapling: Treestate<sapling::tree::SerializedTree>,
/// A treestate containing an Orchard note commitment tree, hex-encoded.
#[serde(skip_serializing_if = "Treestate::is_empty")]
orchard: Treestate<orchard::tree::SerializedTree>,
}
/// A treestate that is included in the [`z_gettreestate`][1] RPC response.
///
/// [1]: https://zcash.github.io/rpc/z_gettreestate.html
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
struct Treestate<Tree: AsRef<[u8]>> {
/// Contains an Orchard or Sapling serialized note commitment tree,
/// hex-encoded.
commitments: Commitments<Tree>,
}
/// A wrapper that contains either an Orchard or Sapling note commitment tree.
///
/// Note that in the original [`z_gettreestate`][1] RPC, [`Commitments`] also
/// contains the field `finalRoot`. Zebra does *not* use this field.
///
/// [1]: https://zcash.github.io/rpc/z_gettreestate.html
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
struct Commitments<Tree: AsRef<[u8]>> {
/// Orchard or Sapling serialized note commitment tree, hex-encoded.
#[serde(with = "hex")]
#[serde(rename = "finalState")]
final_state: Tree,
}
impl<Tree: AsRef<[u8]>> Treestate<Tree> {
/// Returns `true` if there's no serialized commitment tree.
fn is_empty(&self) -> bool {
self.commitments.final_state.as_ref().is_empty()
}
}
/// Response to a `getrawtransaction` RPC request.
///
/// See the notes for the [`Rpc::get_raw_transaction` method].
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
#[serde(untagged)]
pub enum GetRawTransaction {
/// The raw transaction, encoded as hex bytes.
Raw(#[serde(with = "hex")] SerializedTransaction),
/// The transaction object.
Object {
/// The raw transaction, encoded as hex bytes.
#[serde(with = "hex")]
hex: SerializedTransaction,
/// The height of the block in the best chain that contains the transaction, or -1 if
/// the transaction is in the mempool.
height: i32,
/// The confirmations of the block in the best chain that contains the transaction,
/// or 0 if the transaction is in the mempool.
confirmations: u32,
},
}
/// Response to a `getaddressutxos` RPC request.
///
/// See the notes for the [`Rpc::get_address_utxos` method].
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
pub struct GetAddressUtxos {
/// The transparent address, base58check encoded
address: transparent::Address,
/// The output txid, in big-endian order, hex-encoded
#[serde(with = "hex")]
txid: transaction::Hash,
/// The transparent output index, numeric
#[serde(rename = "outputIndex")]
output_index: OutputIndex,
/// The transparent output script, hex encoded
#[serde(with = "hex")]
script: transparent::Script,
/// The amount of zatoshis in the transparent output
satoshis: u64,
/// The block height, numeric.
///
/// We put this field last, to match the zcashd order.
height: Height,
}
/// A struct to use as parameter of the `getaddresstxids`.
///
/// See the notes for the [`Rpc::get_address_tx_ids` method].
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize)]
pub struct GetAddressTxIdsRequest {
// A list of addresses to get transactions from.
addresses: Vec<String>,
// The height to start looking for transactions.
start: u32,
// The height to end looking for transactions.
end: u32,
}
impl GetRawTransaction {
/// Converts `tx` and `height` into a new `GetRawTransaction` in the `verbose` format.
#[allow(clippy::unwrap_in_result)]
fn from_transaction(
tx: Arc<Transaction>,
height: Option<block::Height>,
confirmations: u32,
verbose: bool,
) -> Self {
if verbose {
GetRawTransaction::Object {
hex: tx.into(),
height: match height {
Some(height) => height
.0
.try_into()
.expect("valid block heights are limited to i32::MAX"),
None => -1,
},
confirmations,
}
} else {
GetRawTransaction::Raw(tx.into())
}
}
}
/// Information about the sapling and orchard note commitment trees if any.
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct GetBlockTrees {
#[serde(skip_serializing_if = "SaplingTrees::is_empty")]
sapling: SaplingTrees,
#[serde(skip_serializing_if = "OrchardTrees::is_empty")]
orchard: OrchardTrees,
}
/// Sapling note commitment tree information.
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct SaplingTrees {
size: u64,
}
impl SaplingTrees {
fn is_empty(&self) -> bool {
self.size == 0
}
}
/// Orchard note commitment tree information.
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct OrchardTrees {
size: u64,
}
impl OrchardTrees {
fn is_empty(&self) -> bool {
self.size == 0
}
}
/// Check if provided height range is valid for address indexes.
fn check_height_range(start: Height, end: Height, chain_height: Height) -> Result<()> {
if start == Height(0) || end == Height(0) {
change(state): Write finalized blocks to the state in a separate thread, to avoid network and RPC hangs (#5134) * Add a new block commit task and channels, that don't do anything yet * Add last_block_hash_sent to the state service, to avoid database accesses * Update last_block_hash_sent regardless of commit errors * Rename a field to StateService.max_queued_finalized_height * Commit finalized blocks to the state in a separate task * Check for panics in the block write task * Wait for the block commit task in tests, and check for errors * Always run a proptest that sleeps once * Add extra debugging to state shutdowns * Work around a RocksDB shutdown bug * Close the finalized block channel when we're finished with it * Only reset state queue once per error * Update some TODOs * Add a module doc comment * Drop channels and check for closed channels in the block commit task * Close state channels and tasks on drop * Remove some duplicate fields across StateService and ReadStateService * Try tweaking the shutdown steps * Update and clarify some comments * Clarify another comment * Don't try to cancel RocksDB background work on drop * Fix up some comments * Remove some duplicate code * Remove redundant workarounds for shutdown issues * Remode a redundant channel close in the block commit task * Remove a mistaken `!force` shutdown condition * Remove duplicate force-shutdown code and explain it better * Improve RPC error logging * Wait for chain tip updates in the RPC tests * Wait 2 seconds for chain tip updates before skipping them * Remove an unnecessary block_in_place() * Fix some test error messages that were changed by earlier fixes * Expand some comments, fix typos Co-authored-by: Marek <mail@marek.onl> * Actually drop children of failed blocks * Explain why we drop descendants of failed blocks * Clarify a comment * Wait for chain tip updates in a failing test on macOS * Clean duplicate finalized blocks when the non-finalized state activates * Send an error when receiving a duplicate finalized block * Update checkpoint block behaviour, document its consensus rule * Wait for chain tip changes in inbound_block_height_lookahead_limit test * Wait for the genesis block to commit in the fake peer set mempool tests * Disable unreliable mempool verification check in the send transaction test * Appease rustfmt * Use clear_finalized_block_queue() everywhere that blocks are dropped * Document how Finalized and NonFinalized clones are different * Use the same check as commit_finalized() for finalized block heights Co-authored-by: Marek <mail@marek.onl> Co-authored-by: Marek <mail@marek.onl>
2022-09-28 09:09:56 -07:00
return Err(Error::invalid_params(format!(
"start {start:?} and end {end:?} must both be greater than zero"
)));
}
change(state): Write finalized blocks to the state in a separate thread, to avoid network and RPC hangs (#5134) * Add a new block commit task and channels, that don't do anything yet * Add last_block_hash_sent to the state service, to avoid database accesses * Update last_block_hash_sent regardless of commit errors * Rename a field to StateService.max_queued_finalized_height * Commit finalized blocks to the state in a separate task * Check for panics in the block write task * Wait for the block commit task in tests, and check for errors * Always run a proptest that sleeps once * Add extra debugging to state shutdowns * Work around a RocksDB shutdown bug * Close the finalized block channel when we're finished with it * Only reset state queue once per error * Update some TODOs * Add a module doc comment * Drop channels and check for closed channels in the block commit task * Close state channels and tasks on drop * Remove some duplicate fields across StateService and ReadStateService * Try tweaking the shutdown steps * Update and clarify some comments * Clarify another comment * Don't try to cancel RocksDB background work on drop * Fix up some comments * Remove some duplicate code * Remove redundant workarounds for shutdown issues * Remode a redundant channel close in the block commit task * Remove a mistaken `!force` shutdown condition * Remove duplicate force-shutdown code and explain it better * Improve RPC error logging * Wait for chain tip updates in the RPC tests * Wait 2 seconds for chain tip updates before skipping them * Remove an unnecessary block_in_place() * Fix some test error messages that were changed by earlier fixes * Expand some comments, fix typos Co-authored-by: Marek <mail@marek.onl> * Actually drop children of failed blocks * Explain why we drop descendants of failed blocks * Clarify a comment * Wait for chain tip updates in a failing test on macOS * Clean duplicate finalized blocks when the non-finalized state activates * Send an error when receiving a duplicate finalized block * Update checkpoint block behaviour, document its consensus rule * Wait for chain tip changes in inbound_block_height_lookahead_limit test * Wait for the genesis block to commit in the fake peer set mempool tests * Disable unreliable mempool verification check in the send transaction test * Appease rustfmt * Use clear_finalized_block_queue() everywhere that blocks are dropped * Document how Finalized and NonFinalized clones are different * Use the same check as commit_finalized() for finalized block heights Co-authored-by: Marek <mail@marek.onl> Co-authored-by: Marek <mail@marek.onl>
2022-09-28 09:09:56 -07:00
if start > end {
return Err(Error::invalid_params(format!(
"start {start:?} must be less than or equal to end {end:?}"
)));
}
if start > chain_height || end > chain_height {
change(state): Write finalized blocks to the state in a separate thread, to avoid network and RPC hangs (#5134) * Add a new block commit task and channels, that don't do anything yet * Add last_block_hash_sent to the state service, to avoid database accesses * Update last_block_hash_sent regardless of commit errors * Rename a field to StateService.max_queued_finalized_height * Commit finalized blocks to the state in a separate task * Check for panics in the block write task * Wait for the block commit task in tests, and check for errors * Always run a proptest that sleeps once * Add extra debugging to state shutdowns * Work around a RocksDB shutdown bug * Close the finalized block channel when we're finished with it * Only reset state queue once per error * Update some TODOs * Add a module doc comment * Drop channels and check for closed channels in the block commit task * Close state channels and tasks on drop * Remove some duplicate fields across StateService and ReadStateService * Try tweaking the shutdown steps * Update and clarify some comments * Clarify another comment * Don't try to cancel RocksDB background work on drop * Fix up some comments * Remove some duplicate code * Remove redundant workarounds for shutdown issues * Remode a redundant channel close in the block commit task * Remove a mistaken `!force` shutdown condition * Remove duplicate force-shutdown code and explain it better * Improve RPC error logging * Wait for chain tip updates in the RPC tests * Wait 2 seconds for chain tip updates before skipping them * Remove an unnecessary block_in_place() * Fix some test error messages that were changed by earlier fixes * Expand some comments, fix typos Co-authored-by: Marek <mail@marek.onl> * Actually drop children of failed blocks * Explain why we drop descendants of failed blocks * Clarify a comment * Wait for chain tip updates in a failing test on macOS * Clean duplicate finalized blocks when the non-finalized state activates * Send an error when receiving a duplicate finalized block * Update checkpoint block behaviour, document its consensus rule * Wait for chain tip changes in inbound_block_height_lookahead_limit test * Wait for the genesis block to commit in the fake peer set mempool tests * Disable unreliable mempool verification check in the send transaction test * Appease rustfmt * Use clear_finalized_block_queue() everywhere that blocks are dropped * Document how Finalized and NonFinalized clones are different * Use the same check as commit_finalized() for finalized block heights Co-authored-by: Marek <mail@marek.onl> Co-authored-by: Marek <mail@marek.onl>
2022-09-28 09:09:56 -07:00
return Err(Error::invalid_params(format!(
"start {start:?} and end {end:?} must both be less than or equal to the chain tip {chain_height:?}"
)));
}
Ok(())
}
/// Given a potentially negative index, find the corresponding `Height`.
///
/// This function is used to parse the integer index argument of `get_block_hash`.
/// This is based on zcashd's implementation:
/// <https://github.com/zcash/zcash/blob/c267c3ee26510a974554f227d40a89e3ceb5bb4d/src/rpc/blockchain.cpp#L589-L618>
//
// TODO: also use this function in `get_block` and `z_get_treestate`
#[allow(dead_code)]
pub fn height_from_signed_int(index: i32, tip_height: Height) -> Result<Height> {
if index >= 0 {
let height = index.try_into().expect("Positive i32 always fits in u32");
if height > tip_height.0 {
return Err(Error::invalid_params(
"Provided index is greater than the current tip",
));
}
Ok(Height(height))
} else {
// `index + 1` can't overflow, because `index` is always negative here.
let height = i32::try_from(tip_height.0)
.expect("tip height fits in i32, because Height::MAX fits in i32")
.checked_add(index + 1);
let sanitized_height = match height {
None => return Err(Error::invalid_params("Provided index is not valid")),
Some(h) => {
if h < 0 {
return Err(Error::invalid_params(
"Provided negative index ends up with a negative height",
));
}
let h: u32 = h.try_into().expect("Positive i32 always fits in u32");
if h > tip_height.0 {
return Err(Error::invalid_params(
"Provided index is greater than the current tip",
));
}
h
}
};
Ok(Height(sanitized_height))
}
}