Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "zcash-devtool"
version = "0.1.0"
edition = "2021"
rust-version = "1.81"
edition = "2024"
rust-version = "1.85"
license = "MIT OR Apache-2.0"
publish = false

Expand Down
4 changes: 3 additions & 1 deletion src/commands/create_multisig_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ fn multisig_script(

fn validate_args(threshold: u8, pub_keys: &[PublicKey]) -> anyhow::Result<()> {
if threshold < 1 {
return Err(anyhow::anyhow!("a multisignature address must require at least one key to redeem, threshold must be at least 1"));
return Err(anyhow::anyhow!(
"a multisignature address must require at least one key to redeem, threshold must be at least 1"
));
}

if pub_keys.len() < threshold as usize {
Expand Down
6 changes: 3 additions & 3 deletions src/commands/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ use std::io;
use std::io::Cursor;
use std::process;

use bech32::primitives::decode::CheckedHrpstring;
use bech32::Bech32;
use bech32::primitives::decode::CheckedHrpstring;
use clap::Args;
use lazy_static::lazy_static;
use secrecy::Zeroize;

use zcash_address::{
unified::{self, Encoding},
ZcashAddress,
unified::{self, Encoding},
};
use zcash_primitives::{block::BlockHeader, transaction::Transaction};
use zcash_proofs::{default_params_folder, load_parameters, ZcashParameters};
use zcash_proofs::{ZcashParameters, default_params_folder, load_parameters};
use zcash_protocol::{
consensus::{BranchId, NetworkType},
constants,
Expand Down
2 changes: 1 addition & 1 deletion src/commands/inspect/address.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use group::GroupEncoding;
use zcash_address::{
unified::{self, Container, Encoding},
ConversionError, ToAddress, ZcashAddress,
unified::{self, Container, Encoding},
};
use zcash_protocol::consensus::NetworkType;

Expand Down
14 changes: 9 additions & 5 deletions src/commands/inspect/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use zcash_primitives::{block::BlockHeader, transaction::Transaction};
use zcash_protocol::consensus::{BlockHeight, BranchId, Network, NetworkUpgrade, Parameters};

use super::{
transaction::{extract_height_from_coinbase, is_coinbase},
Context, ZUint256,
transaction::{extract_height_from_coinbase, is_coinbase},
};

const MIN_BLOCK_VERSION: i32 = 4;
Expand Down Expand Up @@ -277,7 +277,9 @@ fn inspect_header_inner(header: &BlockHeader, params: Option<Network>) {
eprintln!("⚠️ Invalid Proof-of-Work: {e}");
}
} else {
eprintln!("🔎 To check contextual rules, add \"network\" to context (either \"main\" or \"test\")");
eprintln!(
"🔎 To check contextual rules, add \"network\" to context (either \"main\" or \"test\")"
);
}
}

Expand Down Expand Up @@ -385,15 +387,17 @@ pub(crate) fn inspect(block: &Block, context: Option<Context>) {
} else if Some(height) == params.activation_height(NetworkUpgrade::Heartwood) {
if block.header.final_sapling_root != [0; 32] {
// zcashd: bad-heartwood-root-in-block
eprintln!("⚠️ This is the block that activates Heartwood but header.blockcommitments is not null");
eprintln!(
"⚠️ This is the block that activates Heartwood but header.blockcommitments is not null"
);
}
} else if params.is_nu_active(NetworkUpgrade::Heartwood, height) {
if let Some(chain_history_root) = context.and_then(|c| c.chainhistoryroot) {
if chain_history_root.0 != block.header.final_sapling_root {
// zcashd: bad-heartwood-root-in-block
eprintln!(
"⚠️ [Heartwood] header.blockcommitments doesn't match provided chain history root"
);
"⚠️ [Heartwood] header.blockcommitments doesn't match provided chain history root"
);
eprintln!(" - chainhistoryroot: {chain_history_root}");
eprintln!(
" - header.blockcommitments: {}",
Expand Down
4 changes: 2 additions & 2 deletions src/commands/inspect/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::fmt;
use std::str::FromStr;

use serde::{
de::{Unexpected, Visitor},
Deserialize, Serialize, Serializer,
de::{Unexpected, Visitor},
};

use ::transparent::{
Expand Down Expand Up @@ -262,7 +262,7 @@ impl<'de> Deserialize<'de> for ZScript {

impl Serialize for ZScript {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&hex::encode(&self.0 .0 .0))
serializer.serialize_str(&hex::encode(&self.0.0.0))
}
}

Expand Down
12 changes: 8 additions & 4 deletions src/commands/inspect/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use ::transparent::{
keys::{AccountPrivKey, IncomingViewingKey},
};
use zcash_address::{
unified::{self, Encoding},
ToAddress, ZcashAddress,
unified::{self, Encoding},
};
use zcash_keys::{
encoding::AddressCodec,
Expand Down Expand Up @@ -103,9 +103,11 @@ pub(crate) fn inspect_mnemonic(mnemonic: bip0039::Mnemonic, context: Option<Cont
Ok(addr) => eprintln!(
" - Default address: {}",
match addr {
TransparentAddress::PublicKeyHash(data) => ZcashAddress::from_transparent_p2pkh(addr_net, data),
TransparentAddress::PublicKeyHash(data) =>
ZcashAddress::from_transparent_p2pkh(addr_net, data),
TransparentAddress::ScriptHash(_) => unreachable!(),
}.encode(),
}
.encode(),
),
Err(e) => eprintln!(
" ⚠️ No valid transparent default address for this account under this seed: {e:?}"
Expand Down Expand Up @@ -153,7 +155,9 @@ pub(crate) fn inspect_mnemonic(mnemonic: bip0039::Mnemonic, context: Option<Cont
}
seed.zeroize();
} else {
eprintln!("🔎 To show account details, add \"network\" (either \"main\" or \"test\") and \"accounts\" array to context");
eprintln!(
"🔎 To show account details, add \"network\" (either \"main\" or \"test\") and \"accounts\" array to context"
);
}

eprintln!();
Expand Down
2 changes: 1 addition & 1 deletion src/commands/inspect/lookup.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use tonic::transport::{Channel, ClientTlsConfig};
use zcash_client_backend::proto::{
compact_formats::CompactBlock,
service::{compact_tx_streamer_client::CompactTxStreamerClient, BlockId, TxFilter},
service::{BlockId, TxFilter, compact_tx_streamer_client::CompactTxStreamerClient},
};
use zcash_primitives::transaction::Transaction;
use zcash_protocol::consensus::{BlockHeight, BranchId, Network};
Expand Down
5 changes: 3 additions & 2 deletions src/commands/inspect/script.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use zcash_script::{
opcode::{push_value::LargeValue, PossiblyBad, PushValue},
script, solver, Opcode,
Opcode,
opcode::{PossiblyBad, PushValue, push_value::LargeValue},
script, solver,
};

pub(crate) fn inspect(script: script::FromChain) {
Expand Down
36 changes: 25 additions & 11 deletions src/commands/inspect/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{

use bellman::groth16;
use group::GroupEncoding;
use sapling::{note_encryption::SaplingDomain, SaplingVerificationContext};
use sapling::{SaplingVerificationContext, note_encryption::SaplingDomain};
use secp256k1::{Secp256k1, VerifyOnly};

use ::transparent::{
Expand All @@ -15,16 +15,16 @@ use ::transparent::{
};
use orchard::note_encryption::OrchardDomain;
use zcash_address::{
unified::{self, Encoding},
ToAddress, ZcashAddress,
unified::{self, Encoding},
};
use zcash_note_encryption::try_output_recovery_with_ovk;
#[allow(deprecated)]
use zcash_primitives::transaction::{
Authorization, Transaction, TransactionData, TxId, TxVersion,
components::sapling as sapling_serialization,
sighash::{signature_hash, SignableInput},
sighash::{SignableInput, signature_hash},
txid::TxIdDigester,
Authorization, Transaction, TransactionData, TxId, TxVersion,
};
use zcash_protocol::{
consensus::BlockHeight,
Expand All @@ -34,8 +34,8 @@ use zcash_protocol::{
use zcash_script::{script, solver};

use super::{
context::{Context, ZTxOut},
GROTH16_PARAMS, ORCHARD_VK,
context::{Context, ZTxOut},
};

pub fn is_coinbase(tx: &Transaction) -> bool {
Expand Down Expand Up @@ -160,7 +160,9 @@ pub(crate) fn inspect(
) {
(true, coins) => coins,
(false, Some(_)) => {
eprintln!("⚠️ Context was given \"transparentcoins\" but this transaction has no transparent inputs");
eprintln!(
"⚠️ Context was given \"transparentcoins\" but this transaction has no transparent inputs"
);
Some(vec![])
}
(false, None) => Some(vec![]),
Expand Down Expand Up @@ -261,7 +263,9 @@ pub(crate) fn inspect(
(sig, hash_type, pubkey)
{
if TransparentAddress::from_pubkey(&pubkey) != addr {
eprintln!(" ⚠️ Txin {i} pubkey does not match coin's script_pubkey");
eprintln!(
" ⚠️ Txin {i} pubkey does not match coin's script_pubkey"
);
}

let sighash = signature_hash(
Expand Down Expand Up @@ -298,10 +302,16 @@ pub(crate) fn inspect(
eprintln!(" 🔎 \"transparentcoins\"[{i}] is a P2SH coin.");
}
Some(solver::ScriptKind::MultiSig { required, pubkeys }) => {
eprintln!(" 🔎 \"transparentcoins\"[{i}] is a direct (non-P2SH) {required}-of-{} multi-sig coin.", pubkeys.len());
eprintln!(
" 🔎 \"transparentcoins\"[{i}] is a direct (non-P2SH) {required}-of-{} multi-sig coin.",
pubkeys.len()
);
}
Some(solver::ScriptKind::NullData { data }) => {
eprintln!(" 🔎 \"transparentcoins\"[{i}] is a null data output with {} PushDatas.", data.len());
eprintln!(
" 🔎 \"transparentcoins\"[{i}] is a null data output with {} PushDatas.",
data.len()
);
}
Some(solver::ScriptKind::PubKey { .. }) => {
eprintln!(" 🔎 \"transparentcoins\"[{i}] is a P2PK (not P2PKH) coin.");
Expand Down Expand Up @@ -426,7 +436,9 @@ pub(crate) fn inspect(
eprintln!(" ⚠️ Output {i} is not recoverable with the all-zeros OVK");
}
} else {
eprintln!(" 🔎 To check Sapling coinbase rules, add \"network\" to context (either \"main\" or \"test\")");
eprintln!(
" 🔎 To check Sapling coinbase rules, add \"network\" to context (either \"main\" or \"test\")"
);
}
}

Expand Down Expand Up @@ -500,7 +512,9 @@ pub(crate) fn inspect(
);
eprintln!(" - {zaddr}");
} else {
eprintln!(" 🔎 To show recipient address, add \"network\" to context (either \"main\" or \"test\")");
eprintln!(
" 🔎 To show recipient address, add \"network\" to context (either \"main\" or \"test\")"
);
}

eprintln!(" - {}", render_value(note.value().inner()));
Expand Down
8 changes: 4 additions & 4 deletions src/commands/keystone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ use std::time::Duration;
use anyhow::anyhow;
use clap::{Args, Subcommand};
use minicbor::data::{Int, Tag};
use qrcode::{render::unicode, QrCode};
use qrcode::{QrCode, render::unicode};
use rand::rngs::OsRng;
use tokio::io::{stdout, AsyncWriteExt};
use tokio::io::{AsyncWriteExt, stdout};
use uuid::Uuid;
use zcash_client_backend::data_api::Account;
use zcash_client_sqlite::{util::SystemClock, WalletDb};
use zcash_client_sqlite::{WalletDb, util::SystemClock};

use crate::{config::WalletConfig, data::get_db_paths, ShutdownListener};
use crate::{ShutdownListener, config::WalletConfig, data::get_db_paths};

use super::select_account;

Expand Down
4 changes: 2 additions & 2 deletions src/commands/pczt/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use std::path::PathBuf;

use anyhow::anyhow;
use clap::Args;
use pczt::{roles::combiner::Combiner, Pczt};
use pczt::{Pczt, roles::combiner::Combiner};
use tokio::{
fs::File,
io::{stdout, AsyncReadExt, AsyncWriteExt},
io::{AsyncReadExt, AsyncWriteExt, stdout},
};

// Options accepted for the `pczt combine` command
Expand Down
41 changes: 22 additions & 19 deletions src/commands/pczt/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ use std::{num::NonZeroUsize, str::FromStr};
use anyhow::anyhow;
use clap::Args;
use rand::rngs::OsRng;
use tokio::io::{stdout, AsyncWriteExt};
use tokio::io::{AsyncWriteExt, stdout};
use uuid::Uuid;

use zcash_address::ZcashAddress;
use zcash_client_backend::{
data_api::{
Account as _,
wallet::{
create_pczt_from_proposal, input_selection::GreedyInputSelector, propose_transfer,
ConfirmationsPolicy,
ConfirmationsPolicy, create_pczt_from_proposal, input_selection::GreedyInputSelector,
propose_transfer,
},
Account as _,
},
fees::{standard::MultiOutputChangeStrategy, DustOutputPolicy, SplitPolicy, StandardFeeRule},
fees::{DustOutputPolicy, SplitPolicy, StandardFeeRule, standard::MultiOutputChangeStrategy},
wallet::OvkPolicy,
};
use zcash_client_sqlite::{util::SystemClock, WalletDb};
use zcash_client_sqlite::{WalletDb, util::SystemClock};
use zcash_protocol::{
ShieldedProtocol,
memo::{Memo, MemoBytes},
value::Zatoshis,
ShieldedProtocol,
};
use zip321::{Payment, TransactionRequest};

Expand Down Expand Up @@ -81,18 +81,21 @@ impl Command {
);
let input_selector = GreedyInputSelector::new();

let request = TransactionRequest::new(vec![Payment::new(
ZcashAddress::from_str(&self.address).map_err(|_| error::Error::InvalidRecipient)?,
Some(Zatoshis::from_u64(self.value).map_err(|_| error::Error::InvalidAmount)?),
self.memo
.map(|memo| Memo::from_str(&memo))
.transpose()?
.map(MemoBytes::from),
None,
None,
vec![],
)
.ok_or_else(|| error::Error::TransparentMemo(0))?])
let request = TransactionRequest::new(vec![
Payment::new(
ZcashAddress::from_str(&self.address)
.map_err(|_| error::Error::InvalidRecipient)?,
Some(Zatoshis::from_u64(self.value).map_err(|_| error::Error::InvalidAmount)?),
self.memo
.map(|memo| Memo::from_str(&memo))
.transpose()?
.map(MemoBytes::from),
None,
None,
vec![],
)
.ok_or_else(|| error::Error::TransparentMemo(0))?,
])
.map_err(error::Error::from)?;

let proposal = propose_transfer(
Expand Down
4 changes: 2 additions & 2 deletions src/commands/pczt/create_manual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ use anyhow::anyhow;
use clap::Args;
use pczt::roles::{creator::Creator, io_finalizer::IoFinalizer, updater::Updater};
use rand::rngs::OsRng;
use tokio::io::{stdout, AsyncWriteExt};
use tokio::io::{AsyncWriteExt, stdout};
use transparent::builder::TransparentInputInfo;

use zcash_address::ZcashAddress;
use zcash_client_backend::proto::service::{ChainSpec, TxFilter};
use zcash_keys::address::Address;
use zcash_primitives::transaction::{
Transaction,
builder::{Builder, PcztResult},
fees::zip317,
Transaction,
};
use zcash_protocol::{
consensus::{self, Parameters},
Expand Down
Loading