mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 07:11:36 +02:00
Merge upstream staging into contracts
Catches up with #773, #779 and #781. Only the import blocks in command.rs and api/foreign.rs conflicted.
This commit is contained in:
Generated
+30
-241
@@ -415,29 +415,6 @@ version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-rs"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4342d8937fc7e5dd9b1c60292261c0670c882a2cd1719cfc11b1af41731e32ad"
|
||||
dependencies = [
|
||||
"aws-lc-sys",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-sys"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d9ceb1da931507a12f4fccea479dccd00da1943e1b4ae72d8e502d707361444"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cmake",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.76"
|
||||
@@ -750,12 +727,6 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "chacha20"
|
||||
version = "0.8.2"
|
||||
@@ -862,15 +833,6 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "coarsetime"
|
||||
version = "0.1.37"
|
||||
@@ -882,16 +844,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
|
||||
dependencies = [
|
||||
"bytes 1.12.0",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compression-codecs"
|
||||
version = "0.4.38"
|
||||
@@ -1626,12 +1578,6 @@ dependencies = [
|
||||
"phf 0.11.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.20"
|
||||
@@ -2073,12 +2019,6 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "fslock-guard"
|
||||
version = "0.8.0"
|
||||
@@ -3039,6 +2979,22 @@ dependencies = [
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||
dependencies = [
|
||||
"bytes 1.12.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.20"
|
||||
@@ -3403,55 +3359,6 @@ version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.22.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.4",
|
||||
"combine",
|
||||
"jni-macros",
|
||||
"jni-sys",
|
||||
"log",
|
||||
"simd_cesu8",
|
||||
"thiserror 2.0.18",
|
||||
"walkdir",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-macros"
|
||||
version = "0.22.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.46",
|
||||
"rustc_version",
|
||||
"simd_cesu8",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
|
||||
dependencies = [
|
||||
"jni-sys-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys-macros"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
|
||||
dependencies = [
|
||||
"quote 1.0.46",
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.34"
|
||||
@@ -3729,12 +3636,6 @@ dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru-slab"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.2.0"
|
||||
@@ -4672,63 +4573,6 @@ version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8"
|
||||
dependencies = [
|
||||
"bytes 1.12.0",
|
||||
"cfg_aliases",
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash 2.1.3",
|
||||
"rustls",
|
||||
"socket2",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-proto"
|
||||
version = "0.11.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"bytes 1.12.0",
|
||||
"getrandom 0.4.3",
|
||||
"lru-slab",
|
||||
"rand 0.10.2",
|
||||
"rand_pcg 0.10.2",
|
||||
"ring",
|
||||
"rustc-hash 2.1.3",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
"thiserror 2.0.18",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694"
|
||||
dependencies = [
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
@@ -4802,7 +4646,7 @@ dependencies = [
|
||||
"rand_isaac",
|
||||
"rand_jitter 0.1.4",
|
||||
"rand_os",
|
||||
"rand_pcg 0.1.2",
|
||||
"rand_pcg",
|
||||
"rand_xorshift",
|
||||
"winapi",
|
||||
]
|
||||
@@ -5023,15 +4867,6 @@ dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a"
|
||||
dependencies = [
|
||||
"rand_core 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
@@ -5198,19 +5033,18 @@ dependencies = [
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"rustls-platform-verifier",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-native-tls",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower-service",
|
||||
@@ -5456,7 +5290,6 @@ version = "0.23.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
@@ -5493,44 +5326,15 @@ version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046"
|
||||
dependencies = [
|
||||
"web-time",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-platform-verifier"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
|
||||
dependencies = [
|
||||
"core-foundation 0.10.1",
|
||||
"core-foundation-sys",
|
||||
"jni",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-platform-verifier-android",
|
||||
"rustls-webpki",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-platform-verifier-android"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
@@ -6022,22 +5826,6 @@ version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
|
||||
|
||||
[[package]]
|
||||
name = "simd_cesu8"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
|
||||
dependencies = [
|
||||
"rustc_version",
|
||||
"simdutf8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simdutf8"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
@@ -6597,6 +6385,16 @@ dependencies = [
|
||||
"syn 2.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.26.4"
|
||||
@@ -8366,15 +8164,6 @@ dependencies = [
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-root-certs"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ use crate::try_slatepack_sync_workflow;
|
||||
use crate::util::secp::key::SecretKey;
|
||||
use crate::util::Mutex;
|
||||
use ed25519_dalek::VerifyingKey as DalekPublicKey;
|
||||
use libwallet::SlatepackAddress;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// ForeignAPI Middleware Check callback
|
||||
@@ -345,7 +346,7 @@ where
|
||||
&self,
|
||||
slate: &Slate,
|
||||
dest_acct_name: Option<&str>,
|
||||
r_addr: Option<String>,
|
||||
r_addr: Option<SlatepackAddress>,
|
||||
) -> Result<Slate, Error> {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let tor_config = r_addr
|
||||
|
||||
@@ -22,6 +22,7 @@ use crate::libwallet::{
|
||||
use crate::{Foreign, ForeignCheckMiddlewareFn};
|
||||
use easy_jsonrpc_mw;
|
||||
use grin_wallet_config::initial_setup_wallet;
|
||||
use libwallet::SlatepackAddress;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Public definition used to generate Foreign jsonrpc api.
|
||||
@@ -312,6 +313,16 @@ where
|
||||
) -> Result<VersionedSlate, Error> {
|
||||
let version = in_slate.version();
|
||||
let slate_from = Slate::from(in_slate);
|
||||
let dest = match dest {
|
||||
None => None,
|
||||
Some(a) => match SlatepackAddress::try_from(a.as_str()) {
|
||||
Ok(d) => Some(d),
|
||||
Err(_) => {
|
||||
error!("Error parsing Slatepack address: {}", a);
|
||||
None
|
||||
}
|
||||
},
|
||||
};
|
||||
let out_slate = Foreign::receive_tx(
|
||||
self,
|
||||
&slate_from,
|
||||
|
||||
+44
-44
@@ -707,6 +707,12 @@ where
|
||||
args: InitTxArgs,
|
||||
) -> Result<Slate, Error> {
|
||||
let send_args = args.send_args.clone();
|
||||
let dest = match send_args.as_ref() {
|
||||
Some(args) if !args.dest.is_empty() => {
|
||||
Some(SlatepackAddress::try_from(args.dest.as_str())?)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let (slate, tor_config) = {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let tor_config = send_args
|
||||
@@ -725,10 +731,11 @@ where
|
||||
Error::TorConfig("Tor config was not loaded with send arguments".into())
|
||||
})?;
|
||||
let can_send = tc.send_tor(sa.skip_tor);
|
||||
if self.doctest_mode || !can_send {
|
||||
if self.doctest_mode || !can_send || dest.is_none() {
|
||||
return Ok(slate);
|
||||
}
|
||||
let res = try_slatepack_sync_workflow(&slate, &sa.dest, Some(tc), None, false);
|
||||
let res =
|
||||
try_slatepack_sync_workflow(&slate, &dest.unwrap(), Some(tc), None, false);
|
||||
match res {
|
||||
Ok(s) => {
|
||||
self.tx_lock_outputs(keychain_mask, &s)?;
|
||||
@@ -928,6 +935,12 @@ where
|
||||
args: InitTxArgs,
|
||||
) -> Result<Slate, Error> {
|
||||
let send_args = args.send_args.clone();
|
||||
let dest = match send_args.as_ref() {
|
||||
Some(args) if !args.dest.is_empty() => {
|
||||
Some(SlatepackAddress::try_from(args.dest.as_str())?)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let (slate, tor_config) = {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let tor_config = send_args
|
||||
@@ -946,10 +959,11 @@ where
|
||||
Error::TorConfig("Tor config was not loaded with send arguments".into())
|
||||
})?;
|
||||
let can_send = tc.send_tor(sa.skip_tor);
|
||||
if self.doctest_mode || !can_send {
|
||||
if self.doctest_mode || !can_send || dest.is_none() {
|
||||
return Ok(slate);
|
||||
}
|
||||
let res = try_slatepack_sync_workflow(&slate, &sa.dest, Some(tc), None, true);
|
||||
let dest = dest.unwrap();
|
||||
let res = try_slatepack_sync_workflow(&slate, &dest, Some(tc), None, true);
|
||||
match res {
|
||||
Ok(s) => {
|
||||
// Update slate state.
|
||||
@@ -963,7 +977,7 @@ where
|
||||
}
|
||||
}
|
||||
// Output slatepack message to file.
|
||||
match output_slatepack_file(&self, keychain_mask, &s, &sa.dest) {
|
||||
match output_slatepack_file(&self, keychain_mask, &s, Some(dest)) {
|
||||
Ok(_) => {}
|
||||
Err(e) => error!("Error on saving output slatepack message: {}", e),
|
||||
}
|
||||
@@ -2650,7 +2664,7 @@ where
|
||||
/// attempt to send slate synchronously with TOR
|
||||
pub fn try_slatepack_sync_workflow(
|
||||
slate: &Slate,
|
||||
dest: &str,
|
||||
dest: &SlatepackAddress,
|
||||
tor_config: Option<TorConfig>,
|
||||
tor_sender: Option<TorSlateSender>,
|
||||
send_to_finalize: bool,
|
||||
@@ -2672,42 +2686,32 @@ pub fn try_slatepack_sync_workflow(
|
||||
};
|
||||
};
|
||||
|
||||
// Try parsing Slatepack address.
|
||||
match SlatepackAddress::try_from(dest) {
|
||||
Ok(address) => {
|
||||
let tor_addr = OnionV3Address::try_from(&address).map_err(|_| {
|
||||
Error::SlatepackAddress(format!(
|
||||
"Destination {} is not a valid Onion address.",
|
||||
dest
|
||||
))
|
||||
})?;
|
||||
// Try sending to the destination via Tor.
|
||||
let sender = match tor_sender {
|
||||
None => {
|
||||
if let Some(tc) = tor_config {
|
||||
match TorSlateSender::new(&tor_addr.to_http_str(), tc) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
debug!("Send (Tor): Cannot create TOR Slate sender {:?}", e);
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(Error::TorConfig("Tor config is not set".to_string()));
|
||||
let tor_addr = OnionV3Address::try_from(dest).map_err(|_| {
|
||||
Error::SlatepackAddress(format!(
|
||||
"Destination {} is not a valid Onion address.",
|
||||
dest
|
||||
))
|
||||
})?;
|
||||
let sender = match tor_sender {
|
||||
None => {
|
||||
if let Some(tc) = tor_config {
|
||||
match TorSlateSender::new(&tor_addr.to_http_str(), tc) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
debug!("Send (Tor): Cannot create TOR Slate sender {:?}", e);
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
Some(s) => s,
|
||||
};
|
||||
warn!("Attempting to send transaction via Tor");
|
||||
match send_sync(sender, "Tor") {
|
||||
Ok(_) => Ok(ret_slate),
|
||||
Err(e) => Err(e),
|
||||
} else {
|
||||
return Err(Error::TorConfig("Tor config is not set".to_string()));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Destination {} is not a valid Slatepack address.", dest);
|
||||
Err(e)
|
||||
}
|
||||
Some(s) => s,
|
||||
};
|
||||
warn!("Attempting to send transaction via Tor");
|
||||
match send_sync(sender, "Tor") {
|
||||
Ok(_) => Ok(ret_slate),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2786,19 +2790,15 @@ fn output_slatepack_file<L, C, K>(
|
||||
api: &Owner<L, C, K>,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
slate: &Slate,
|
||||
dest: &str,
|
||||
dest: Option<SlatepackAddress>,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
L: WalletLCProvider<'static, C, K> + 'static,
|
||||
C: NodeClient + 'static,
|
||||
K: Keychain + 'static,
|
||||
{
|
||||
let address = match SlatepackAddress::try_from(dest) {
|
||||
Ok(a) => Some(a),
|
||||
Err(_) => None,
|
||||
};
|
||||
// encrypt for recipient by default
|
||||
let recipients = match address.clone() {
|
||||
let recipients = match dest {
|
||||
Some(a) => vec![a],
|
||||
None => vec![],
|
||||
};
|
||||
|
||||
@@ -1761,7 +1761,7 @@ pub trait OwnerRpc {
|
||||
"params": {
|
||||
"token": "d202964900000000d302964900000000d402964900000000d502964900000000",
|
||||
"secret_indices": [0],
|
||||
"message": "BEGINSLATEPACK. 8GQrdcwdLKJD28F 3a9siP7ZhZgAh7w BR2EiZHza5WMWmZ Cc8zBUemrrYRjhq j3VBwA8vYnvXXKU BDmQBN2yKgmR8mX UzvXHezfznA61d7 qFZYChhz94vd8Ew NEPLz7jmcVN2C3w wrfHbeiLubYozP2 uhLouFiYRrbe3fQ 4uhWGfT3sQYXScT dAeo29EaZJpfauh j8VL5jsxST2SPHq nzXFC2w9yYVjt7D ju7GSgHEp5aHz9R xstGbHjbsb4JQod kYLuELta1ohUwDD pvjhyJmsbLcsPei k5AQhZsJ8RJGBtY bou6cU7tZeFJvor 4LB9CBfFB3pmVWD vSLd5RPS75dcnHP nbXD8mSDZ8hJS2Q A9wgvppWzuWztJ2 dLUU8f9tLJgsRBw YZAs71HiVeg7. ENDSLATEPACK."
|
||||
"message": "BEGINSLATEPACK. t9EcGgrKr1GFCQB SK2jPCxME6Hgpqx bntpQm3zKFycoPY nW4UeoL4KQ7ExNK At6EQsvpz6MjUs8 6WG8KHEbMfqufJQ ZJTw2gkcdJmJjiJ f29oGgYqqXDZox4 ujPSjrtoxCN4h3e i1sZ8dYsm3dPeXL 7VQLsYNjAefciqj ZJXPm4Pqd7VDdd4 okGBGBu3YJvYzT6 arAxeCEx66us31h AJLcDweFwyWBkW5 J1DLiYAjt5ftFTo CjpfW9KjiLq2LM5 jepXWEHJPSDAYVK 4macDZUhRbJiG6E hrQcPrJBVC716mb Hw5E1PFrE6on5wq oEmrS4j9vaB5nw8 Z9ZyXvPc2LN7tER yt6pSHZeY9EpYdY zv4bthzfRfF8ePT TMeMpV2gpgyRXQa CPD2TR. ENDSLATEPACK."
|
||||
},
|
||||
"id": 1
|
||||
}
|
||||
@@ -1905,9 +1905,9 @@ pub trait OwnerRpc {
|
||||
"proof": {
|
||||
"amount": "60000000000",
|
||||
"excess": "09eac5f5872fa5e08e0c29fd900f1b8f77ff3ad1d0d1c46aeb202cbf92363fe0af",
|
||||
"recipient_address": "slatepack10qlk22rxjap2ny8qltc2tl996kenxr3hhwuu6hrzs6tdq08yaqgqnlumr7",
|
||||
"recipient_address": "tgrin10qlk22rxjap2ny8qltc2tl996kenxr3hhwuu6hrzs6tdq08yaqgqq6t83r",
|
||||
"recipient_sig": "02868f2d2b983981f8f98043701687a8531ed2de564ea3df48e9e7e0229ccbe8359efe506896df2efbe3528e977252c50e4a41ca3cc9896e7c5a30bbb1d33604",
|
||||
"sender_address": "slatepack1xtxavwfgs48ckf3gk8wwgcndmn0nt4tvkl8a7ltyejjcy2mc6nfskdvkdu",
|
||||
"sender_address": "tgrin1xtxavwfgs48ckf3gk8wwgcndmn0nt4tvkl8a7ltyejjcy2mc6nfs9gm2lp",
|
||||
"sender_sig": "c511764f3f61ed3d1cbca9514df8bc6811fad5662b1cb0e0587b9c9e49db9f33183cce71af6cb24b507fabf525a2bc405c6e84e63a60334edff0b451ae5e6102"
|
||||
}
|
||||
},
|
||||
@@ -2720,7 +2720,8 @@ pub fn run_doctest_owner(
|
||||
true => {
|
||||
let address = "783f6528669742a990e0faf0a5fca5d5b3330e37bbb9cd5c628696d03ce4e810";
|
||||
let address = OnionV3Address::try_from(address).unwrap();
|
||||
Some(SlatepackAddress::try_from(address).unwrap())
|
||||
let sp = SlatepackAddress::try_from(address).unwrap();
|
||||
Some(sp)
|
||||
}
|
||||
false => None,
|
||||
};
|
||||
|
||||
+49
-33
@@ -322,12 +322,12 @@ pub struct SendArgs {
|
||||
pub selection_strategy: String,
|
||||
pub estimate_selection_strategies: bool,
|
||||
pub late_lock: bool,
|
||||
pub dest: String,
|
||||
pub dest: Option<String>,
|
||||
pub change_outputs: usize,
|
||||
pub fluff: bool,
|
||||
pub max_outputs: usize,
|
||||
pub target_slate_version: Option<u16>,
|
||||
pub payment_proof_address: Option<SlatepackAddress>,
|
||||
pub payment_proof_address: Option<String>,
|
||||
pub ttl_blocks: Option<u64>,
|
||||
pub skip_tor: Option<bool>,
|
||||
pub outfile: Option<String>,
|
||||
@@ -348,6 +348,15 @@ where
|
||||
C: NodeClient + 'static,
|
||||
K: keychain::Keychain + 'static,
|
||||
{
|
||||
let dest = if args.estimate_selection_strategies {
|
||||
None
|
||||
} else {
|
||||
args.dest
|
||||
.as_deref()
|
||||
.map(SlatepackAddress::try_from)
|
||||
.transpose()?
|
||||
};
|
||||
|
||||
let mut slate = Slate::blank(2, false);
|
||||
let mut amount = args.amount;
|
||||
if args.use_max_amount {
|
||||
@@ -376,6 +385,11 @@ where
|
||||
.collect::<Result<Vec<_>, grin_wallet_libwallet::Error>>()?;
|
||||
display::estimate(amount, strategies, dark_scheme);
|
||||
} else {
|
||||
let payment_proof_recipient_address = args
|
||||
.payment_proof_address
|
||||
.as_deref()
|
||||
.map(SlatepackAddress::try_from)
|
||||
.transpose()?;
|
||||
let init_args = InitTxArgs {
|
||||
src_acct_name: None,
|
||||
amount,
|
||||
@@ -385,7 +399,7 @@ where
|
||||
num_change_outputs: args.change_outputs as u32,
|
||||
selection_strategy_is_use_all: args.selection_strategy == "all",
|
||||
target_slate_version: args.target_slate_version,
|
||||
payment_proof_recipient_address: args.payment_proof_address.clone(),
|
||||
payment_proof_recipient_address,
|
||||
ttl_blocks: args.ttl_blocks,
|
||||
send_args: None,
|
||||
late_lock: Some(args.late_lock),
|
||||
@@ -397,7 +411,9 @@ where
|
||||
info!(
|
||||
"Tx created: {} grin to {} (strategy '{}')",
|
||||
core::amount_to_hr_string(amount, false),
|
||||
args.dest,
|
||||
dest.as_ref()
|
||||
.map(ToString::to_string)
|
||||
.unwrap_or_else(|| "no destination".to_string()),
|
||||
args.selection_strategy,
|
||||
);
|
||||
s
|
||||
@@ -422,7 +438,7 @@ where
|
||||
owner_api,
|
||||
keychain_mask,
|
||||
&slate,
|
||||
args.dest.as_str(),
|
||||
dest.clone(),
|
||||
args.outfile,
|
||||
true,
|
||||
false,
|
||||
@@ -431,11 +447,12 @@ where
|
||||
};
|
||||
|
||||
let can_send = tor_config.send_tor(args.skip_tor);
|
||||
if test_mode || !can_send {
|
||||
if test_mode || !can_send || dest.is_none() {
|
||||
return output_sp();
|
||||
}
|
||||
|
||||
let res = try_slatepack_sync_workflow(&slate, &args.dest, Some(tor_config), None, false);
|
||||
let dest = dest.as_ref().unwrap();
|
||||
let res = try_slatepack_sync_workflow(&slate, dest, Some(tor_config), None, false);
|
||||
|
||||
match res {
|
||||
Ok(s) => {
|
||||
@@ -464,7 +481,7 @@ pub fn output_slatepack<L, C, K>(
|
||||
owner_api: &mut Owner<L, C, K>,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
slate: &Slate,
|
||||
dest: &str,
|
||||
dest: Option<SlatepackAddress>,
|
||||
out_file_override: Option<String>,
|
||||
lock: bool,
|
||||
finalizing: bool,
|
||||
@@ -476,12 +493,8 @@ where
|
||||
K: keychain::Keychain + 'static,
|
||||
{
|
||||
// Output the slatepack file to stdout and to a file
|
||||
let address = match SlatepackAddress::try_from(dest) {
|
||||
Ok(a) => Some(a),
|
||||
Err(_) => None,
|
||||
};
|
||||
// encrypt for recipient by default
|
||||
let recipients = match address.clone() {
|
||||
let recipients = match dest.clone() {
|
||||
Some(a) => vec![a],
|
||||
None => vec![],
|
||||
};
|
||||
@@ -527,7 +540,7 @@ where
|
||||
println!();
|
||||
}
|
||||
}
|
||||
if address.is_some() {
|
||||
if dest.is_some() {
|
||||
println!("The slatepack data is encrypted for the recipient only");
|
||||
} else {
|
||||
println!("The slatepack data is NOT encrypted");
|
||||
@@ -783,17 +796,12 @@ where
|
||||
},
|
||||
)?;
|
||||
|
||||
let dest = match ret_address {
|
||||
Some(a) => String::try_from(&a)?,
|
||||
None => String::from(""),
|
||||
};
|
||||
|
||||
let output_sp = || -> Result<(), Error> {
|
||||
Ok(output_slatepack(
|
||||
owner_api,
|
||||
keychain_mask,
|
||||
&slate,
|
||||
&dest,
|
||||
ret_address.clone(),
|
||||
args.outfile,
|
||||
false,
|
||||
false,
|
||||
@@ -802,11 +810,12 @@ where
|
||||
};
|
||||
|
||||
let can_send = tor_config.send_tor(args.skip_tor);
|
||||
if test_mode || !can_send {
|
||||
if test_mode || !can_send || ret_address.is_none() {
|
||||
return output_sp();
|
||||
}
|
||||
|
||||
let res = try_slatepack_sync_workflow(&slate, &dest, Some(tor_config), None, true);
|
||||
let dest = ret_address.as_ref().unwrap();
|
||||
let res = try_slatepack_sync_workflow(&slate, dest, Some(tor_config), None, true);
|
||||
|
||||
match res {
|
||||
Ok(s) => {
|
||||
@@ -974,7 +983,7 @@ where
|
||||
owner_api,
|
||||
keychain_mask,
|
||||
&slate,
|
||||
"",
|
||||
None,
|
||||
args.outfile,
|
||||
false,
|
||||
true,
|
||||
@@ -987,7 +996,7 @@ where
|
||||
/// Issue Invoice Args
|
||||
pub struct IssueInvoiceArgs {
|
||||
/// Slatepack address
|
||||
pub dest: String,
|
||||
pub dest: Option<String>,
|
||||
/// issue invoice tx args
|
||||
pub issue_args: IssueInvoiceTxArgs,
|
||||
/// output file override
|
||||
@@ -1006,6 +1015,11 @@ where
|
||||
C: NodeClient + 'static,
|
||||
K: keychain::Keychain + 'static,
|
||||
{
|
||||
let dest = args
|
||||
.dest
|
||||
.as_deref()
|
||||
.map(SlatepackAddress::try_from)
|
||||
.transpose()?;
|
||||
let issue_args = args.issue_args.clone();
|
||||
|
||||
let slate = owner_api.issue_invoice_tx(keychain_mask, issue_args)?;
|
||||
@@ -1014,7 +1028,7 @@ where
|
||||
owner_api,
|
||||
keychain_mask,
|
||||
&slate,
|
||||
args.dest.as_str(),
|
||||
dest,
|
||||
args.outfile,
|
||||
false,
|
||||
false,
|
||||
@@ -1027,7 +1041,7 @@ where
|
||||
pub struct ProcessInvoiceArgs {
|
||||
pub minimum_confirmations: u64,
|
||||
pub selection_strategy: String,
|
||||
pub ret_address: Option<SlatepackAddress>,
|
||||
pub ret_address: Option<String>,
|
||||
pub max_outputs: usize,
|
||||
pub slate: Slate,
|
||||
pub estimate_selection_strategies: bool,
|
||||
@@ -1052,11 +1066,12 @@ where
|
||||
C: NodeClient + 'static,
|
||||
K: keychain::Keychain + 'static,
|
||||
{
|
||||
let ret_address = args
|
||||
.ret_address
|
||||
.as_deref()
|
||||
.map(SlatepackAddress::try_from)
|
||||
.transpose()?;
|
||||
let mut slate = args.slate.clone();
|
||||
let dest = match args.ret_address.clone() {
|
||||
Some(a) => String::try_from(&a)?,
|
||||
None => String::from(""),
|
||||
};
|
||||
|
||||
if args.estimate_selection_strategies {
|
||||
let strategies = vec!["smallest", "all"]
|
||||
@@ -1115,7 +1130,7 @@ where
|
||||
owner_api,
|
||||
keychain_mask,
|
||||
&slate,
|
||||
&dest,
|
||||
ret_address.clone(),
|
||||
args.outfile,
|
||||
true,
|
||||
false,
|
||||
@@ -1124,11 +1139,12 @@ where
|
||||
};
|
||||
|
||||
let can_send = tor_config.send_tor(args.skip_tor);
|
||||
if test_mode || !can_send {
|
||||
if test_mode || !can_send || ret_address.is_none() {
|
||||
return output_sp();
|
||||
}
|
||||
|
||||
let res = try_slatepack_sync_workflow(&slate, &dest, Some(tor_config), None, true);
|
||||
let dest = ret_address.as_ref().unwrap();
|
||||
let res = try_slatepack_sync_workflow(&slate, dest, Some(tor_config), None, true);
|
||||
|
||||
match res {
|
||||
Ok(s) => {
|
||||
|
||||
@@ -129,7 +129,7 @@ fn send_preflight() {
|
||||
let args = InitTxArgs {
|
||||
amount: 1,
|
||||
send_args: Some(InitTxSendArgs {
|
||||
dest: "unused".into(),
|
||||
dest: "tgrin1xtxavwfgs48ckf3gk8wwgcndmn0nt4tvkl8a7ltyejjcy2mc6nfs9gm2lp".into(),
|
||||
post_tx: false,
|
||||
fluff: false,
|
||||
skip_tor: Some(true),
|
||||
|
||||
@@ -18,6 +18,7 @@ extern crate grin_wallet_controller as wallet;
|
||||
extern crate grin_wallet_impls as impls;
|
||||
|
||||
use grin_core as core;
|
||||
use grin_wallet_config::GlobalWalletConfig;
|
||||
use grin_wallet_libwallet as libwallet;
|
||||
use std::path::PathBuf;
|
||||
|
||||
@@ -28,8 +29,8 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use grin_wallet_libwallet::{
|
||||
InitTxArgs, IssueInvoiceTxArgs, Slate, Slatepack, SlatepackAddress, Slatepacker,
|
||||
SlatepackerArgs,
|
||||
InitTxArgs, InitTxSendArgs, IssueInvoiceTxArgs, Slate, Slatepack, SlatepackAddress,
|
||||
Slatepacker, SlatepackerArgs,
|
||||
};
|
||||
|
||||
use ed25519_dalek::SigningKey as edDalekSecretKey;
|
||||
@@ -601,6 +602,110 @@ fn slatepack_api_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Do not create transaction for invalid or wrong network Slatepack address.
|
||||
fn slatepack_address_validation(test_dir: &'static str) -> Result<(), libwallet::Error> {
|
||||
let mut wallet_proxy = create_wallet_proxy(test_dir);
|
||||
let chain = wallet_proxy.chain.clone();
|
||||
let stopper = wallet_proxy.running.clone();
|
||||
let config_path = PathBuf::from(test_dir).join("grin-wallet.toml");
|
||||
GlobalWalletConfig::for_chain(&core::global::ChainTypes::AutomatedTesting, &config_path)
|
||||
.write_to_file(config_path.to_str().unwrap(), false, None, None)
|
||||
.unwrap();
|
||||
|
||||
create_wallet_and_add!(
|
||||
client1,
|
||||
wallet1,
|
||||
mask1_i,
|
||||
test_dir,
|
||||
"wallet1",
|
||||
None,
|
||||
&mut wallet_proxy,
|
||||
false
|
||||
);
|
||||
let mask1 = (&mask1_i).as_ref();
|
||||
|
||||
create_wallet_and_add!(
|
||||
client2,
|
||||
wallet2,
|
||||
mask2_i,
|
||||
test_dir,
|
||||
"wallet2",
|
||||
None,
|
||||
&mut wallet_proxy,
|
||||
false
|
||||
);
|
||||
let mask2 = (&mask2_i).as_ref();
|
||||
|
||||
let proxy_thread = thread::spawn(move || {
|
||||
if let Err(e) = wallet_proxy.run() {
|
||||
error!("Wallet Proxy error: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
let reward = core::consensus::REWARD;
|
||||
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 6, false);
|
||||
let mut slate = Slate::blank(2, true);
|
||||
|
||||
wallet::controller::owner_single_use(wallet2.clone(), mask2, config_path.clone(), |api, m| {
|
||||
slate = api.issue_invoice_tx(
|
||||
m,
|
||||
IssueInvoiceTxArgs {
|
||||
amount: reward,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
wallet::controller::owner_single_use(wallet1.clone(), mask1, config_path, |api, m| {
|
||||
let args = InitTxArgs {
|
||||
src_acct_name: Some("mining".to_owned()),
|
||||
amount: reward,
|
||||
minimum_confirmations: 2,
|
||||
max_outputs: 500,
|
||||
num_change_outputs: 1,
|
||||
selection_strategy_is_use_all: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut wrong_net_args = args.clone();
|
||||
wrong_net_args.send_args = Some(InitTxSendArgs {
|
||||
dest: "grin1dvge9z4uqgqlpspmljrd7smh3grrw9xu2r9lkz3u67s3emj3ud2sd5gk9p".to_string(),
|
||||
post_tx: false,
|
||||
fluff: false,
|
||||
skip_tor: Some(true),
|
||||
});
|
||||
assert!(api.init_send_tx(m, wrong_net_args.clone()).is_err());
|
||||
assert!(api.process_invoice_tx(m, &slate, wrong_net_args).is_err());
|
||||
|
||||
let mut invalid_args = args.clone();
|
||||
invalid_args.send_args = Some(InitTxSendArgs {
|
||||
dest: "tgrinaddr10qlk22rxjap2ny8qltc2tl996kenxr3hhwuu6hrzs6tdq08yaqgqnlumr7"
|
||||
.to_string(),
|
||||
post_tx: false,
|
||||
fluff: false,
|
||||
skip_tor: Some(true),
|
||||
});
|
||||
assert!(api.init_send_tx(m, invalid_args.clone()).is_err());
|
||||
assert!(api.process_invoice_tx(m, &slate, invalid_args).is_err());
|
||||
|
||||
let mut valid_args = args;
|
||||
valid_args.send_args = Some(InitTxSendArgs {
|
||||
dest: "tgrin1xtxavwfgs48ckf3gk8wwgcndmn0nt4tvkl8a7ltyejjcy2mc6nfs9gm2lp".to_string(),
|
||||
post_tx: false,
|
||||
fluff: false,
|
||||
skip_tor: Some(true),
|
||||
});
|
||||
api.process_invoice_tx(m, &slate, valid_args.clone())?;
|
||||
api.init_send_tx(m, valid_args)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
stopper.store(false, Ordering::Relaxed);
|
||||
proxy_thread.join().expect("wallet proxy thread panicked");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slatepack_exchange_json() {
|
||||
let test_dir = "test_output/slatepack_exchange_json";
|
||||
@@ -677,3 +782,13 @@ fn slatepack_api() {
|
||||
}
|
||||
clean_output_dir(test_dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slatepack_address() {
|
||||
let test_dir = "test_output/slatepack_address";
|
||||
setup(test_dir);
|
||||
if let Err(e) = slatepack_address_validation(test_dir) {
|
||||
panic!("Libwallet Error: {}", e);
|
||||
}
|
||||
clean_output_dir(test_dir);
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ ring = "0.17.14"
|
||||
chrono = { version = "0.4.11", features = ["serde"] }
|
||||
lazy_static = "1"
|
||||
tokio = { version = "1.52.3", features = ["full"] }
|
||||
reqwest = { version = "0.13.3", features = ["socks"] }
|
||||
reqwest = { version = "0.13.4", default-features = false, features = ["socks", "native-tls", "system-proxy", "charset", "http2"] }
|
||||
|
||||
#Socks/Tor/Bridge/Proxy
|
||||
ed25519-dalek = "2"
|
||||
|
||||
@@ -72,7 +72,6 @@ impl Client {
|
||||
|
||||
let mut builder = ClientBuilder::new()
|
||||
.timeout(request_timeout)
|
||||
.use_rustls_tls()
|
||||
.default_headers(headers);
|
||||
|
||||
if let Some(p) = proxy {
|
||||
|
||||
@@ -9,6 +9,9 @@ keywords = [ "crypto", "grin", "mimblewimble" ]
|
||||
exclude = ["**/*.grin", "**/*.grin2"]
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
mwixnet-test = []
|
||||
|
||||
[dependencies]
|
||||
blake2-rfc = "0.2"
|
||||
rand = "0.6"
|
||||
|
||||
@@ -614,6 +614,19 @@ where
|
||||
C: NodeClient,
|
||||
K: Keychain,
|
||||
{
|
||||
let payment_proof_address = if let Some(a) = &args.payment_proof_recipient_address {
|
||||
if a.valid_network() {
|
||||
Some(a)
|
||||
} else {
|
||||
return Err(Error::PaymentProofRetrieval(format!(
|
||||
"Wrong network for address {}",
|
||||
a
|
||||
)));
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let parent_key_id = match &args.src_acct_name {
|
||||
Some(d) => {
|
||||
let pm = w.get_acct_path(d.clone())?;
|
||||
@@ -683,7 +696,7 @@ where
|
||||
// probably want to allow sender to specify which one
|
||||
let deriv_path = 0u32;
|
||||
|
||||
if let Some(a) = args.payment_proof_recipient_address {
|
||||
if let Some(a) = payment_proof_address {
|
||||
let k = w.keychain(keychain_mask)?;
|
||||
|
||||
let sec_addr_key = address::address_from_derivation_path(&k, &parent_key_id, deriv_path)?;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Onion modules for mxmixnet
|
||||
mod onion;
|
||||
pub mod onion;
|
||||
mod types;
|
||||
|
||||
pub use onion::{
|
||||
|
||||
@@ -69,7 +69,6 @@ impl AsRef<VerifyingKey> for DalekPublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// Serializes an Option<DalekPublicKey> to and from hex
|
||||
pub mod option_dalek_pubkey_serde {
|
||||
use super::DalekPublicKey;
|
||||
@@ -152,7 +151,6 @@ impl AsRef<ed25519_dalek::Signature> for DalekSignature {
|
||||
}
|
||||
|
||||
/// Serializes a DalekSignature to and from hex
|
||||
#[cfg(test)]
|
||||
pub mod dalek_sig_serde {
|
||||
use super::DalekSignature;
|
||||
use grin_util::ToHex;
|
||||
@@ -179,8 +177,6 @@ pub mod dalek_sig_serde {
|
||||
}
|
||||
|
||||
/// Dalek signature sign wrapper
|
||||
// TODO: This is likely duplicated throughout crate, check
|
||||
#[cfg(test)]
|
||||
pub fn sign(sk: &SecretKey, message: &[u8]) -> Result<DalekSignature, DalekError> {
|
||||
use ed25519_dalek::{Signer, SigningKey};
|
||||
let secret = SigningKey::from_bytes(&sk.0);
|
||||
|
||||
@@ -18,7 +18,7 @@ pub use grin_util::secp::{
|
||||
self as secp256k1zkp,
|
||||
constants::SECRET_KEY_SIZE,
|
||||
key::{SecretKey, ZERO_KEY},
|
||||
pedersen::Commitment,
|
||||
pedersen::{Commitment, RangeProof},
|
||||
rand::thread_rng,
|
||||
ContextFlag, Secp256k1,
|
||||
};
|
||||
@@ -47,7 +47,6 @@ pub fn read_secret_key<R: Reader>(reader: &mut R) -> Result<SecretKey, ser::Erro
|
||||
}
|
||||
|
||||
/// Build a Pedersen Commitment using the provided value and blinding factor
|
||||
#[cfg(test)]
|
||||
pub fn commit(value: u64, blind: &SecretKey) -> Result<Commitment, secp256k1zkp::Error> {
|
||||
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||
let commit = secp.commit(value, blind.clone())?;
|
||||
@@ -76,7 +75,6 @@ pub fn sub_value(commitment: &Commitment, value: u64) -> Result<Commitment, secp
|
||||
}
|
||||
|
||||
/// Signs the message with the provided SecretKey
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)]
|
||||
pub fn sign(
|
||||
sk: &SecretKey,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
//! Onion module definition
|
||||
|
||||
mod crypto;
|
||||
pub mod crypto;
|
||||
pub mod onion;
|
||||
pub mod util;
|
||||
|
||||
@@ -48,7 +48,7 @@ pub struct Hop {
|
||||
}
|
||||
|
||||
/// Crate a new hop
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "mwixnet-test"))]
|
||||
pub fn new_hop(
|
||||
server_key: &SecretKey,
|
||||
hop_excess: &SecretKey,
|
||||
@@ -119,7 +119,7 @@ pub fn create_onion(
|
||||
|
||||
/// Internal tests
|
||||
#[allow(missing_docs, dead_code)]
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "mwixnet-test"))]
|
||||
pub mod test_util {
|
||||
use super::*;
|
||||
use crypto::dalek::DalekPublicKey;
|
||||
|
||||
@@ -41,15 +41,18 @@ pub struct SlatepackAddress {
|
||||
pub pub_key: edDalekPublicKey,
|
||||
}
|
||||
|
||||
fn slatepack_hrp() -> &'static str {
|
||||
match global::get_chain_type() {
|
||||
global::ChainTypes::Mainnet => "grin",
|
||||
_ => "tgrin",
|
||||
}
|
||||
}
|
||||
|
||||
impl SlatepackAddress {
|
||||
/// new with default hrp
|
||||
pub fn new(pub_key: &edDalekPublicKey) -> Self {
|
||||
let hrp = match global::get_chain_type() {
|
||||
global::ChainTypes::Mainnet => "grin",
|
||||
_ => "tgrin",
|
||||
};
|
||||
Self {
|
||||
hrp: String::from(hrp),
|
||||
hrp: String::from(slatepack_hrp()),
|
||||
pub_key: pub_key.clone(),
|
||||
}
|
||||
}
|
||||
@@ -75,11 +78,19 @@ impl SlatepackAddress {
|
||||
let x_key = xDalekPublicKey::try_from(self)?;
|
||||
Ok(bech32::encode("age", x_key.as_bytes().to_base32())?.to_string())
|
||||
}
|
||||
|
||||
/// Check if address network is valid.
|
||||
pub fn valid_network(&self) -> bool {
|
||||
valid_network(&self.hrp)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for SlatepackAddress {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(&String::try_from(self).unwrap())
|
||||
match String::try_from(self) {
|
||||
Ok(encoded) => formatter.write_str(&encoded),
|
||||
Err(_) => formatter.write_str("<invalid Slatepack address>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +98,12 @@ impl TryFrom<&str> for SlatepackAddress {
|
||||
type Error = Error;
|
||||
fn try_from(encoded: &str) -> Result<Self, Self::Error> {
|
||||
let (hrp, data) = bech32::decode(&encoded)?;
|
||||
if !valid_network(&hrp) {
|
||||
return Err(Error::SlatepackAddress(format!(
|
||||
"wrong address prefix for chain {:?}",
|
||||
global::get_chain_type()
|
||||
)));
|
||||
}
|
||||
let bytes = Vec::<u8>::from_base32(&data)?;
|
||||
let b = <&[u8; 32]>::try_from(bytes.as_slice())
|
||||
.map_err(|_| Error::SlatepackAddress("Wrong encoded data".to_string()))?;
|
||||
@@ -242,10 +259,52 @@ impl Readable for SlatepackAddress {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if encoded HRP is for valid network.
|
||||
fn valid_network(hrp: &str) -> bool {
|
||||
slatepack_hrp() == hrp
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slatepack_address() -> Result<(), Error> {
|
||||
use rand::{thread_rng, Rng};
|
||||
global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
|
||||
|
||||
// Check validation.
|
||||
let bytes: [u8; 32] = thread_rng().gen();
|
||||
let pub_key = edDalekPublicKey::from(&edDalekSecretKey::from_bytes(&bytes));
|
||||
let wrong_net_addr = SlatepackAddress {
|
||||
hrp: "grin".to_string(),
|
||||
pub_key,
|
||||
};
|
||||
assert!(!wrong_net_addr.valid_network());
|
||||
let right_addr = SlatepackAddress {
|
||||
hrp: "tgrin".to_string(),
|
||||
pub_key,
|
||||
};
|
||||
assert!(right_addr.valid_network());
|
||||
let invalid_addr = SlatepackAddress {
|
||||
hrp: "invalid hrp".to_string(),
|
||||
pub_key,
|
||||
};
|
||||
assert!(!invalid_addr.valid_network());
|
||||
assert_eq!(invalid_addr.to_string(), "<invalid Slatepack address>");
|
||||
|
||||
let valid_addr = "tgrin1xtxavwfgs48ckf3gk8wwgcndmn0nt4tvkl8a7ltyejjcy2mc6nfs9gm2lp";
|
||||
let parsed_valid_addr = SlatepackAddress::try_from(valid_addr);
|
||||
assert!(parsed_valid_addr.is_ok());
|
||||
|
||||
let valid_addr2 = "TGRIN1XTXAVWFGS48CKF3GK8WWGCNDMN0NT4TVKL8A7LTYEJJCY2MC6NFS9GM2LP";
|
||||
let parsed_valid_addr2 = SlatepackAddress::try_from(valid_addr2);
|
||||
assert!(parsed_valid_addr2.is_ok());
|
||||
|
||||
let invalid_addr = "slatepack10qlk22rxjap2ny8qltc2tl996kenxr3hhwuu6hrzs6tdq08yaqgqnlumr7";
|
||||
let parsed_invalid_addr = SlatepackAddress::try_from(invalid_addr);
|
||||
assert!(parsed_invalid_addr.is_err());
|
||||
|
||||
let wrong_net_addr = "grin1dvge9z4uqgqlpspmljrd7smh3grrw9xu2r9lkz3u67s3emj3ud2sd5gk9p";
|
||||
let parsed_wrong_net_addr = SlatepackAddress::try_from(wrong_net_addr);
|
||||
assert!(parsed_wrong_net_addr.is_err());
|
||||
|
||||
let sec_key_bytes: [u8; 32] = thread_rng().gen();
|
||||
|
||||
let ed_sec_key = edDalekSecretKey::from_bytes(&sec_key_bytes);
|
||||
|
||||
@@ -132,7 +132,7 @@ subcommands:
|
||||
default_value: "1"
|
||||
takes_value: true
|
||||
- dest:
|
||||
help: Intended recipient's Slatepack Address (or http listener address (DEPRECATED))
|
||||
help: Intended recipient's Slatepack Address
|
||||
short: d
|
||||
long: dest
|
||||
takes_value: true
|
||||
|
||||
+28
-15
@@ -476,7 +476,11 @@ pub fn parse_send_args(args: &ArgMatches) -> Result<command::SendArgs, ParseErro
|
||||
let late_lock = args.is_present("late_lock");
|
||||
|
||||
// dest
|
||||
let dest = args.value_of("dest").unwrap_or_else(|| "default");
|
||||
let dest = if let Some(dest) = args.value_of("dest") {
|
||||
Some(dest.to_owned())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// change_outputs
|
||||
let change_outputs = parse_required(args, "change_outputs")?;
|
||||
@@ -503,17 +507,16 @@ pub fn parse_send_args(args: &ArgMatches) -> Result<command::SendArgs, ParseErro
|
||||
};
|
||||
|
||||
let payment_proof_address = {
|
||||
match args.is_present("no_payment_proof") {
|
||||
false => match SlatepackAddress::try_from(dest) {
|
||||
Ok(a) => Some(a),
|
||||
Err(_) => {
|
||||
if !estimate_selection_strategies {
|
||||
println!("No recipient Slatepack address or provided address invalid. No payment proof will be requested.");
|
||||
}
|
||||
None
|
||||
}
|
||||
},
|
||||
true => None,
|
||||
if let Some(a) = dest.clone() {
|
||||
match args.is_present("no_payment_proof") {
|
||||
false => Some(a),
|
||||
true => None,
|
||||
}
|
||||
} else {
|
||||
if !estimate_selection_strategies {
|
||||
println!("No recipient Slatepack address or provided address invalid. No payment proof will be requested.");
|
||||
}
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
@@ -540,7 +543,7 @@ pub fn parse_send_args(args: &ArgMatches) -> Result<command::SendArgs, ParseErro
|
||||
selection_strategy: selection_strategy.to_owned(),
|
||||
estimate_selection_strategies,
|
||||
late_lock,
|
||||
dest: dest.to_owned(),
|
||||
dest,
|
||||
change_outputs,
|
||||
fluff,
|
||||
max_outputs,
|
||||
@@ -702,14 +705,18 @@ pub fn parse_issue_invoice_args(
|
||||
};
|
||||
|
||||
// dest, for encryption
|
||||
let dest = args.value_of("dest").unwrap_or_else(|| "default");
|
||||
let dest = if let Some(dest) = args.value_of("dest") {
|
||||
Some(dest.to_owned())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let outfile = parse_optional(args, "outfile")?;
|
||||
|
||||
let slatepack_qr = args.is_present("slatepack_qr");
|
||||
|
||||
Ok(command::IssueInvoiceArgs {
|
||||
dest: dest.into(),
|
||||
dest,
|
||||
issue_args: IssueInvoiceTxArgs {
|
||||
dest_acct_name: None,
|
||||
amount,
|
||||
@@ -802,6 +809,12 @@ pub fn parse_process_invoice_args(
|
||||
|
||||
let slatepack_qr = args.is_present("slatepack_qr");
|
||||
|
||||
let ret_address = if let Some(a) = ret_address {
|
||||
Some(a.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(command::ProcessInvoiceArgs {
|
||||
minimum_confirmations: min_c,
|
||||
selection_strategy: selection_strategy.to_owned(),
|
||||
|
||||
Reference in New Issue
Block a user