mirror of
https://github.com/mimblewimble/grin-wallet.git
synced 2025-01-20 19:11:09 +03:00
Less cloning and additional pattern simplifications (#326)
* API cleanup * Config cleanup * Impl cleanup * Libwallet cleanup * Additionnal simplification
This commit is contained in:
parent
2d264db91a
commit
1116bc5545
35 changed files with 554 additions and 616 deletions
|
@ -674,9 +674,7 @@ pub fn run_doctest_foreign(
|
|||
let _ = lc.set_top_level_directory(&format!("{}/wallet2", test_dir));
|
||||
lc.create_wallet(None, Some(rec_phrase_2), 32, empty_string.clone(), false)
|
||||
.unwrap();
|
||||
let mask2 = lc
|
||||
.open_wallet(None, empty_string.clone(), use_token, true)
|
||||
.unwrap();
|
||||
let mask2 = lc.open_wallet(None, empty_string, use_token, true).unwrap();
|
||||
let wallet2 = Arc::new(Mutex::new(wallet2));
|
||||
|
||||
wallet_proxy.add_wallet(
|
||||
|
|
|
@ -1344,7 +1344,7 @@ where
|
|||
|
||||
fn get_stored_tx(&self, tx: &TxLogEntry) -> Result<Option<TransactionV3>, ErrorKind> {
|
||||
Owner::get_stored_tx(self, None, tx)
|
||||
.map(|x| x.map(|y| TransactionV3::from(y)))
|
||||
.map(|x| x.map(TransactionV3::from))
|
||||
.map_err(|e| e.kind())
|
||||
}
|
||||
|
||||
|
@ -1458,9 +1458,7 @@ pub fn run_doctest_owner(
|
|||
let _ = lc.set_top_level_directory(&format!("{}/wallet2", test_dir));
|
||||
lc.create_wallet(None, Some(rec_phrase_2), 32, empty_string.clone(), false)
|
||||
.unwrap();
|
||||
let mask2 = lc
|
||||
.open_wallet(None, empty_string.clone(), use_token, true)
|
||||
.unwrap();
|
||||
let mask2 = lc.open_wallet(None, empty_string, use_token, true).unwrap();
|
||||
let wallet2 = Arc::new(Mutex::new(wallet2));
|
||||
|
||||
if mask2.is_some() {
|
||||
|
@ -1558,7 +1556,7 @@ pub fn run_doctest_owner(
|
|||
}
|
||||
|
||||
if payment_proof {
|
||||
let _ = api_impl::owner::post_tx(&client1, &slate_outer.tx, true).unwrap();
|
||||
api_impl::owner::post_tx(&client1, &slate_outer.tx, true).unwrap();
|
||||
}
|
||||
|
||||
if perform_tx && lock_tx && finalize_tx {
|
||||
|
|
|
@ -2130,7 +2130,7 @@ where
|
|||
tx: &TxLogEntry,
|
||||
) -> Result<Option<TransactionV3>, ErrorKind> {
|
||||
Owner::get_stored_tx(self, (&token.keychain_mask).as_ref(), tx)
|
||||
.map(|x| x.map(|y| TransactionV3::from(y)))
|
||||
.map(|x| x.map(TransactionV3::from))
|
||||
.map_err(|e| e.kind())
|
||||
}
|
||||
|
||||
|
@ -2173,21 +2173,19 @@ where
|
|||
let secp = secp_inst.lock();
|
||||
let sec_key = SecretKey::new(&secp, &mut thread_rng());
|
||||
|
||||
let mut shared_pubkey = ecdh_pubkey.ecdh_pubkey.clone();
|
||||
let mut shared_pubkey = ecdh_pubkey.ecdh_pubkey;
|
||||
shared_pubkey
|
||||
.mul_assign(&secp, &sec_key)
|
||||
.map_err(|e| ErrorKind::Secp(e))?;
|
||||
.map_err(ErrorKind::Secp)?;
|
||||
|
||||
let x_coord = shared_pubkey.serialize_vec(&secp, true);
|
||||
let shared_key =
|
||||
SecretKey::from_slice(&secp, &x_coord[1..]).map_err(|e| ErrorKind::Secp(e))?;
|
||||
let shared_key = SecretKey::from_slice(&secp, &x_coord[1..]).map_err(ErrorKind::Secp)?;
|
||||
{
|
||||
let mut s = self.shared_key.lock();
|
||||
*s = Some(shared_key);
|
||||
}
|
||||
|
||||
let pub_key =
|
||||
PublicKey::from_secret_key(&secp, &sec_key).map_err(|e| ErrorKind::Secp(e))?;
|
||||
let pub_key = PublicKey::from_secret_key(&secp, &sec_key).map_err(ErrorKind::Secp)?;
|
||||
|
||||
Ok(ECDHPubkey {
|
||||
ecdh_pubkey: pub_key,
|
||||
|
@ -2247,7 +2245,7 @@ where
|
|||
let n = name.as_ref().map(|s| s.as_str());
|
||||
let res =
|
||||
Owner::get_mnemonic(self, n, ZeroingString::from(password)).map_err(|e| e.kind())?;
|
||||
Ok(format!("{}", &*res))
|
||||
Ok((&*res).to_string())
|
||||
}
|
||||
|
||||
fn change_password(
|
||||
|
|
|
@ -237,11 +237,11 @@ fn comments() -> HashMap<String, String> {
|
|||
|
||||
fn get_key(line: &str) -> String {
|
||||
if line.contains('[') && line.contains(']') {
|
||||
return line.to_owned();
|
||||
line.to_owned()
|
||||
} else if line.contains('=') {
|
||||
return line.split('=').collect::<Vec<&str>>()[0].trim().to_owned();
|
||||
line.split('=').collect::<Vec<&str>>()[0].trim().to_owned()
|
||||
} else {
|
||||
return "NOT_FOUND".to_owned();
|
||||
"NOT_FOUND".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,9 +59,9 @@ fn get_grin_path(
|
|||
}
|
||||
|
||||
if !grin_path.exists() {
|
||||
return Err(ConfigError::PathNotFoundError(String::from(
|
||||
Err(ConfigError::PathNotFoundError(String::from(
|
||||
grin_path.to_str().unwrap(),
|
||||
)));
|
||||
)))
|
||||
} else {
|
||||
Ok(grin_path)
|
||||
}
|
||||
|
@ -253,21 +253,12 @@ impl GlobalWalletConfig {
|
|||
match decoded {
|
||||
Ok(gc) => {
|
||||
self.members = Some(gc);
|
||||
return Ok(self);
|
||||
Ok(self)
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(ConfigError::ParseError(
|
||||
String::from(
|
||||
self.config_file_path
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.clone(),
|
||||
),
|
||||
Err(e) => Err(ConfigError::ParseError(
|
||||
String::from(self.config_file_path.as_mut().unwrap().to_str().unwrap()),
|
||||
format!("{}", e),
|
||||
));
|
||||
}
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,10 +300,8 @@ impl GlobalWalletConfig {
|
|||
let encoded: Result<String, toml::ser::Error> =
|
||||
toml::to_string(self.members.as_mut().unwrap());
|
||||
match encoded {
|
||||
Ok(enc) => return Ok(enc),
|
||||
Err(e) => {
|
||||
return Err(ConfigError::SerializationError(format!("{}", e)));
|
||||
}
|
||||
Ok(enc) => Ok(enc),
|
||||
Err(e) => Err(ConfigError::SerializationError(format!("{}", e))),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ use std::path::MAIN_SEPARATOR;
|
|||
use crate::tor::config as tor_config;
|
||||
use crate::tor::process as tor_process;
|
||||
|
||||
const TOR_CONFIG_PATH: &'static str = "tor/sender";
|
||||
const TOR_CONFIG_PATH: &str = "tor/sender";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HttpSlateSender {
|
||||
|
@ -78,10 +78,9 @@ impl HttpSlateSender {
|
|||
let err_string = format!("{}", e);
|
||||
if err_string.contains("404") {
|
||||
// Report that the other version of the wallet is out of date
|
||||
report = format!(
|
||||
"Other wallet is incompatible and requires an upgrade. \
|
||||
report = "Other wallet is incompatible and requires an upgrade. \
|
||||
Please urge the other wallet owner to upgrade and try the transaction again."
|
||||
);
|
||||
.to_string();
|
||||
}
|
||||
error!("{}", report);
|
||||
ErrorKind::ClientCallback(report)
|
||||
|
@ -107,7 +106,7 @@ impl HttpSlateSender {
|
|||
|
||||
// trivial tests for now, but will be expanded later
|
||||
if foreign_api_version < 2 {
|
||||
let report = format!("Other wallet reports unrecognized API format.");
|
||||
let report = "Other wallet reports unrecognized API format.".to_string();
|
||||
error!("{}", report);
|
||||
return Err(ErrorKind::ClientCallback(report).into());
|
||||
}
|
||||
|
@ -119,7 +118,7 @@ impl HttpSlateSender {
|
|||
return Ok(SlateVersion::V2);
|
||||
}
|
||||
|
||||
let report = format!("Unable to negotiate slate format with other wallet.");
|
||||
let report = "Unable to negotiate slate format with other wallet.".to_string();
|
||||
error!("{}", report);
|
||||
Err(ErrorKind::ClientCallback(report).into())
|
||||
}
|
||||
|
@ -136,7 +135,7 @@ impl HttpSlateSender {
|
|||
let mut client = Client::new();
|
||||
if self.use_socks {
|
||||
client.use_socks = true;
|
||||
client.socks_proxy_addr = self.socks_proxy_addr.clone();
|
||||
client.socks_proxy_addr = self.socks_proxy_addr;
|
||||
}
|
||||
let req = client.create_post_request(url, api_secret, &input)?;
|
||||
let res = client.send_request(req)?;
|
||||
|
@ -167,24 +166,24 @@ impl SlateSender for HttpSlateSender {
|
|||
&tor_dir,
|
||||
&self.socks_proxy_addr.unwrap().to_string(),
|
||||
)
|
||||
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e).into()))?;
|
||||
.map_err(|e| ErrorKind::TorConfig(format!("{:?}", e)))?;
|
||||
// Start TOR process
|
||||
tor.torrc_path(&format!("{}/torrc", &tor_dir))
|
||||
.working_dir(&tor_dir)
|
||||
.timeout(20)
|
||||
.completion_percent(100)
|
||||
.launch()
|
||||
.map_err(|e| ErrorKind::TorProcess(format!("{:?}", e).into()))?;
|
||||
.map_err(|e| ErrorKind::TorProcess(format!("{:?}", e)))?;
|
||||
}
|
||||
|
||||
let slate_send = match self.check_other_version(&url_str)? {
|
||||
SlateVersion::V3 => VersionedSlate::into_version(slate.clone(), SlateVersion::V3),
|
||||
SlateVersion::V2 => {
|
||||
let mut slate = slate.clone();
|
||||
if let Some(_) = slate.payment_proof {
|
||||
if slate.payment_proof.is_some() {
|
||||
return Err(ErrorKind::ClientCallback("Payment proof requested, but other wallet does not support payment proofs. Please urge other user to upgrade, or re-send tx without a payment proof".into()).into());
|
||||
}
|
||||
if let Some(_) = slate.ttl_cutoff_height {
|
||||
if slate.ttl_cutoff_height.is_some() {
|
||||
warn!("Slate TTL value will be ignored and removed by other wallet, as other wallet does not support this feature. Please urge other user to upgrade");
|
||||
}
|
||||
slate.version_info.version = 2;
|
||||
|
@ -236,7 +235,7 @@ pub struct SchemeNotHttp;
|
|||
|
||||
impl Into<Error> for SchemeNotHttp {
|
||||
fn into(self) -> Error {
|
||||
let err_str = format!("url scheme must be http",);
|
||||
let err_str = "url scheme must be http".to_string();
|
||||
ErrorKind::GenericError(err_str).into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ impl KeybaseChannel {
|
|||
/// Check if keybase is installed and return an adapter object.
|
||||
pub fn new(channel: String) -> Result<KeybaseChannel, Error> {
|
||||
// Limit only one recipient
|
||||
if channel.matches(",").count() > 0 {
|
||||
if channel.matches(',').count() > 0 {
|
||||
return Err(
|
||||
ErrorKind::GenericError("Only one recipient is supported!".to_owned()).into(),
|
||||
);
|
||||
|
@ -83,12 +83,12 @@ fn api_send(payload: &str) -> Result<Value, Error> {
|
|||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
Err(ErrorKind::GenericError("keybase api fail".to_owned()))?
|
||||
Err(ErrorKind::GenericError("keybase api fail".to_owned()).into())
|
||||
} else {
|
||||
let response: Value =
|
||||
from_str(from_utf8(&output.stdout).expect("Bad output")).expect("Bad output");
|
||||
let err_msg = format!("{}", response["error"]["message"]);
|
||||
if err_msg.len() > 0 && err_msg != "null" {
|
||||
if !err_msg.is_empty() && err_msg != "null" {
|
||||
error!("api_send got error: {}", err_msg);
|
||||
}
|
||||
|
||||
|
@ -107,12 +107,12 @@ fn whoami() -> Result<String, Error> {
|
|||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
Err(ErrorKind::GenericError("keybase api fail".to_owned()))?
|
||||
Err(ErrorKind::GenericError("keybase api fail".to_owned()).into())
|
||||
} else {
|
||||
let response: Value =
|
||||
from_str(from_utf8(&output.stdout).expect("Bad output")).expect("Bad output");
|
||||
let err_msg = format!("{}", response["error"]["message"]);
|
||||
if err_msg.len() > 0 && err_msg != "null" {
|
||||
if !err_msg.is_empty() && err_msg != "null" {
|
||||
error!("status query got error: {}", err_msg);
|
||||
}
|
||||
|
||||
|
@ -121,9 +121,7 @@ fn whoami() -> Result<String, Error> {
|
|||
Ok(s.to_string())
|
||||
} else {
|
||||
error!("keybase username query fail");
|
||||
Err(ErrorKind::GenericError(
|
||||
"keybase username query fail".to_owned(),
|
||||
))?
|
||||
Err(ErrorKind::GenericError("keybase username query fail".to_owned()).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +157,7 @@ fn read_from_channel(channel: &str, topic: &str) -> Result<Vec<String>, Error> {
|
|||
}
|
||||
Ok(unread)
|
||||
} else {
|
||||
Err(ErrorKind::GenericError("keybase api fail".to_owned()))?
|
||||
Err(ErrorKind::GenericError("keybase api fail".to_owned()).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,7 +200,7 @@ fn get_unread(topic: &str) -> Result<HashMap<String, String>, Error> {
|
|||
}
|
||||
Ok(unread)
|
||||
} else {
|
||||
Err(ErrorKind::GenericError("keybase api fail".to_owned()))?
|
||||
Err(ErrorKind::GenericError("keybase api fail".to_owned()).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,16 +274,11 @@ fn poll(nseconds: u64, channel: &str) -> Option<Slate> {
|
|||
let unread = read_from_channel(channel, SLATE_SIGNED);
|
||||
for msg in unread.unwrap().iter() {
|
||||
let blob = Slate::deserialize_upgrade(&msg);
|
||||
match blob {
|
||||
Ok(slate) => {
|
||||
let slate: Slate = slate.into();
|
||||
if let Ok(slate) = blob {
|
||||
info!(
|
||||
"keybase response message received from @{}, tx uuid: {}",
|
||||
channel, slate.id,
|
||||
);
|
||||
return Some(slate);
|
||||
}
|
||||
Err(_) => (),
|
||||
}
|
||||
}
|
||||
sleep(POLL_SLEEP_DURATION);
|
||||
|
@ -306,19 +299,17 @@ impl SlateSender for KeybaseChannel {
|
|||
match send(&slate, &self.0, SLATE_NEW, TTL) {
|
||||
true => (),
|
||||
false => {
|
||||
return Err(ErrorKind::ClientCallback(
|
||||
"Posting transaction slate".to_owned(),
|
||||
))?;
|
||||
return Err(
|
||||
ErrorKind::ClientCallback("Posting transaction slate".to_owned()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
info!("tx request has been sent to @{}, tx uuid: {}", &self.0, id);
|
||||
// Wait for response from recipient with SLATE_SIGNED topic
|
||||
match poll(TTL as u64, &self.0) {
|
||||
Some(slate) => return Ok(slate),
|
||||
Some(slate) => Ok(slate),
|
||||
None => {
|
||||
return Err(ErrorKind::ClientCallback(
|
||||
"Receiving reply from recipient".to_owned(),
|
||||
))?;
|
||||
Err(ErrorKind::ClientCallback("Receiving reply from recipient".to_owned()).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -355,9 +346,8 @@ impl SlateReceiver for KeybaseAllChannels {
|
|||
node_api_secret: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
let node_client = HTTPNodeClient::new(&config.check_node_api_http_addr, node_api_secret);
|
||||
let mut wallet = Box::new(
|
||||
DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client.clone()).unwrap(),
|
||||
)
|
||||
let mut wallet =
|
||||
Box::new(DefaultWalletImpl::<'static, HTTPNodeClient>::new(node_client).unwrap())
|
||||
as Box<
|
||||
dyn WalletInst<
|
||||
'static,
|
||||
|
@ -383,17 +373,16 @@ impl SlateReceiver for KeybaseAllChannels {
|
|||
for (msg, channel) in &unread.unwrap() {
|
||||
let blob = Slate::deserialize_upgrade(&msg);
|
||||
match blob {
|
||||
Ok(message) => {
|
||||
let slate: Slate = message.clone().into();
|
||||
Ok(slate) => {
|
||||
let tx_uuid = slate.id;
|
||||
|
||||
// Reject multiple recipients channel for safety
|
||||
{
|
||||
if channel.matches(",").count() > 1 {
|
||||
if channel.matches(',').count() > 1 {
|
||||
error!(
|
||||
"Incoming tx initiated on channel \"{}\" is rejected, multiple recipients channel! amount: {}(g), tx uuid: {}",
|
||||
channel,
|
||||
slate.amount as f64 / 1000000000.0,
|
||||
slate.amount as f64 / 1_000_000_000.0,
|
||||
tx_uuid,
|
||||
);
|
||||
continue;
|
||||
|
@ -403,7 +392,7 @@ impl SlateReceiver for KeybaseAllChannels {
|
|||
info!(
|
||||
"tx initiated on channel \"{}\", to send you {}(g). tx uuid: {}",
|
||||
channel,
|
||||
slate.amount as f64 / 1000000000.0,
|
||||
slate.amount as f64 / 1_000_000_000.0,
|
||||
tx_uuid,
|
||||
);
|
||||
if let Err(e) = slate.verify_messages() {
|
||||
|
@ -411,15 +400,14 @@ impl SlateReceiver for KeybaseAllChannels {
|
|||
return Err(e);
|
||||
}
|
||||
let res = {
|
||||
let r = foreign::receive_tx(
|
||||
foreign::receive_tx(
|
||||
&mut **wallet_inst,
|
||||
Some(mask.as_ref().unwrap()),
|
||||
&slate,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
r
|
||||
)
|
||||
};
|
||||
match res {
|
||||
// Reply to the same channel with topic SLATE_SIGNED
|
||||
|
@ -460,7 +448,7 @@ fn notify_on_receive(keybase_notify_ttl: u16, channel: String, tx_uuid: String)
|
|||
if keybase_notify_ttl > 0 {
|
||||
let my_username = whoami();
|
||||
if let Ok(username) = my_username {
|
||||
let split = channel.split(",");
|
||||
let split = channel.split(',');
|
||||
let vec: Vec<&str> = split.collect();
|
||||
if vec.len() > 1 {
|
||||
let receiver = username;
|
||||
|
|
|
@ -70,7 +70,7 @@ pub fn create_sender(
|
|||
))
|
||||
};
|
||||
|
||||
let mut method = method.into();
|
||||
let mut method = method;
|
||||
|
||||
// will test if this is a tor address and fill out
|
||||
// the http://[].onion if missing
|
||||
|
@ -95,7 +95,7 @@ pub fn create_sender(
|
|||
.map_err(|_| invalid())?,
|
||||
),
|
||||
},
|
||||
"keybase" => Box::new(KeybaseChannel::new(dest.to_owned())?),
|
||||
"keybase" => Box::new(KeybaseChannel::new(dest)?),
|
||||
"self" => {
|
||||
return Err(ErrorKind::WalletComms(
|
||||
"No sender implementation for \"self\".".to_string(),
|
||||
|
|
|
@ -41,19 +41,19 @@ use crate::util::{self, secp};
|
|||
use rand::rngs::mock::StepRng;
|
||||
use rand::thread_rng;
|
||||
|
||||
pub const DB_DIR: &'static str = "db";
|
||||
pub const TX_SAVE_DIR: &'static str = "saved_txs";
|
||||
pub const DB_DIR: &str = "db";
|
||||
pub const TX_SAVE_DIR: &str = "saved_txs";
|
||||
|
||||
const OUTPUT_PREFIX: u8 = 'o' as u8;
|
||||
const DERIV_PREFIX: u8 = 'd' as u8;
|
||||
const CONFIRMED_HEIGHT_PREFIX: u8 = 'c' as u8;
|
||||
const PRIVATE_TX_CONTEXT_PREFIX: u8 = 'p' as u8;
|
||||
const TX_LOG_ENTRY_PREFIX: u8 = 't' as u8;
|
||||
const TX_LOG_ID_PREFIX: u8 = 'i' as u8;
|
||||
const ACCOUNT_PATH_MAPPING_PREFIX: u8 = 'a' as u8;
|
||||
const LAST_SCANNED_BLOCK: u8 = 'l' as u8;
|
||||
const OUTPUT_PREFIX: u8 = b'o';
|
||||
const DERIV_PREFIX: u8 = b'd';
|
||||
const CONFIRMED_HEIGHT_PREFIX: u8 = b'c';
|
||||
const PRIVATE_TX_CONTEXT_PREFIX: u8 = b'p';
|
||||
const TX_LOG_ENTRY_PREFIX: u8 = b't';
|
||||
const TX_LOG_ID_PREFIX: u8 = b'i';
|
||||
const ACCOUNT_PATH_MAPPING_PREFIX: u8 = b'a';
|
||||
const LAST_SCANNED_BLOCK: u8 = b'l';
|
||||
const LAST_SCANNED_KEY: &str = "LAST_SCANNED_KEY";
|
||||
const WALLET_INIT_STATUS: u8 = 'w' as u8;
|
||||
const WALLET_INIT_STATUS: u8 = b'w';
|
||||
const WALLET_INIT_STATUS_KEY: &str = "WALLET_INIT_STATUS";
|
||||
|
||||
/// test to see if database files exist in the current directory. If so,
|
||||
|
@ -79,7 +79,7 @@ where
|
|||
let mut hasher = Blake2b::new(SECRET_KEY_SIZE);
|
||||
hasher.update(&root_key.0[..]);
|
||||
hasher.update(&slate_id[..]);
|
||||
hasher.update(&"blind".as_bytes()[..]);
|
||||
hasher.update(&b"blind"[..]);
|
||||
let blind_xor_key = hasher.finalize();
|
||||
let mut ret_blind = [0; SECRET_KEY_SIZE];
|
||||
ret_blind.copy_from_slice(&blind_xor_key.as_bytes()[0..SECRET_KEY_SIZE]);
|
||||
|
@ -88,7 +88,7 @@ where
|
|||
let mut hasher = Blake2b::new(SECRET_KEY_SIZE);
|
||||
hasher.update(&root_key.0[..]);
|
||||
hasher.update(&slate_id[..]);
|
||||
hasher.update(&"nonce".as_bytes()[..]);
|
||||
hasher.update(&b"nonce"[..]);
|
||||
let nonce_xor_key = hasher.finalize();
|
||||
let mut ret_nonce = [0; SECRET_KEY_SIZE];
|
||||
ret_nonce.copy_from_slice(&nonce_xor_key.as_bytes()[0..SECRET_KEY_SIZE]);
|
||||
|
@ -200,7 +200,7 @@ where
|
|||
// before it is used
|
||||
let mask_value = match use_test_rng {
|
||||
true => {
|
||||
let mut test_rng = StepRng::new(1234567890u64, 1);
|
||||
let mut test_rng = StepRng::new(1_234_567_890_u64, 1);
|
||||
secp::key::SecretKey::new(&k.secp(), &mut test_rng)
|
||||
}
|
||||
false => secp::key::SecretKey::new(&k.secp(), &mut thread_rng()),
|
||||
|
@ -280,7 +280,7 @@ where
|
|||
self.set_parent_key_id(a.path);
|
||||
Ok(())
|
||||
} else {
|
||||
return Err(ErrorKind::UnknownAccountLabel(label.clone()).into());
|
||||
Err(ErrorKind::UnknownAccountLabel(label).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,8 +334,8 @@ where
|
|||
})?;
|
||||
|
||||
for i in 0..SECRET_KEY_SIZE {
|
||||
ctx.sec_key.0[i] = ctx.sec_key.0[i] ^ blind_xor_key[i];
|
||||
ctx.sec_nonce.0[i] = ctx.sec_nonce.0[i] ^ nonce_xor_key[i];
|
||||
ctx.sec_key.0[i] ^= blind_xor_key[i];
|
||||
ctx.sec_nonce.0[i] ^= nonce_xor_key[i];
|
||||
}
|
||||
|
||||
Ok(ctx)
|
||||
|
@ -428,9 +428,9 @@ where
|
|||
}
|
||||
};
|
||||
let mut return_path = self.parent_key_id.to_path();
|
||||
return_path.depth = return_path.depth + 1;
|
||||
return_path.depth += 1;
|
||||
return_path.path[return_path.depth as usize - 1] = ChildNumber::from(deriv_idx);
|
||||
deriv_idx = deriv_idx + 1;
|
||||
deriv_idx += 1;
|
||||
let mut batch = self.batch(keychain_mask)?;
|
||||
batch.save_child_index(&parent_key_id, deriv_idx)?;
|
||||
batch.commit()?;
|
||||
|
@ -696,8 +696,8 @@ where
|
|||
|
||||
let mut s_ctx = ctx.clone();
|
||||
for i in 0..SECRET_KEY_SIZE {
|
||||
s_ctx.sec_key.0[i] = s_ctx.sec_key.0[i] ^ blind_xor_key[i];
|
||||
s_ctx.sec_nonce.0[i] = s_ctx.sec_nonce.0[i] ^ nonce_xor_key[i];
|
||||
s_ctx.sec_key.0[i] ^= blind_xor_key[i];
|
||||
s_ctx.sec_nonce.0[i] ^= nonce_xor_key[i];
|
||||
}
|
||||
|
||||
self.db
|
||||
|
|
|
@ -339,9 +339,9 @@ impl Client {
|
|||
let addr = match self.socks_proxy_addr {
|
||||
Some(a) => a,
|
||||
None => {
|
||||
return Box::new(result(Err(ErrorKind::RequestError(format!(
|
||||
"Can't parse Socks proxy address"
|
||||
))
|
||||
return Box::new(result(Err(ErrorKind::RequestError(
|
||||
"Can't parse Socks proxy address".to_string(),
|
||||
)
|
||||
.into())))
|
||||
}
|
||||
};
|
||||
|
|
|
@ -125,7 +125,7 @@ fn answer_hello(
|
|||
if response[0] == 5 && response[1] == 0 {
|
||||
Box::new(ok(socket))
|
||||
} else if response[0] == 5 && response[1] == 2 && creds.is_some() {
|
||||
Box::new(auth_negotiation(socket, creds).and_then(|socket| ok(socket)))
|
||||
Box::new(auth_negotiation(socket, creds).and_then(ok))
|
||||
} else {
|
||||
Box::new(
|
||||
Err(Error::new(
|
||||
|
@ -159,7 +159,7 @@ fn write_addr(socket: TcpStream, req: Destination) -> HandshakeFuture<TcpStream>
|
|||
};
|
||||
|
||||
let mut packet = Vec::new();
|
||||
packet.write_all(&vec![5, 1, 0]).unwrap();
|
||||
packet.write_all(&[5, 1, 0]).unwrap();
|
||||
|
||||
packet.write_u8(3).unwrap();
|
||||
packet.write_u8(host.as_bytes().len() as u8).unwrap();
|
||||
|
|
|
@ -109,13 +109,7 @@ impl Fail for Error {
|
|||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let show_bt = match env::var("RUST_BACKTRACE") {
|
||||
Ok(r) => {
|
||||
if r == "1" {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
Ok(r) => r == "1",
|
||||
Err(_) => false,
|
||||
};
|
||||
let backtrace = match self.backtrace() {
|
||||
|
@ -124,7 +118,7 @@ impl Display for Error {
|
|||
};
|
||||
let inner_output = format!("{}", self.inner,);
|
||||
let backtrace_output = format!("\nBacktrace: {}", backtrace);
|
||||
let mut output = inner_output.clone();
|
||||
let mut output = inner_output;
|
||||
if show_bt {
|
||||
output.push_str(&backtrace_output);
|
||||
}
|
||||
|
|
|
@ -82,21 +82,21 @@ where
|
|||
let logging = match logging_config {
|
||||
Some(l) => Some(l),
|
||||
None => match default_config.members.as_ref() {
|
||||
Some(m) => m.clone().logging.clone(),
|
||||
Some(m) => m.clone().logging,
|
||||
None => None,
|
||||
},
|
||||
};
|
||||
let wallet = match wallet_config {
|
||||
Some(w) => w,
|
||||
None => match default_config.members.as_ref() {
|
||||
Some(m) => m.clone().wallet.clone(),
|
||||
Some(m) => m.clone().wallet,
|
||||
None => WalletConfig::default(),
|
||||
},
|
||||
};
|
||||
let tor = match tor_config {
|
||||
Some(t) => Some(t),
|
||||
None => match default_config.members.as_ref() {
|
||||
Some(m) => m.clone().tor.clone(),
|
||||
Some(m) => m.clone().tor,
|
||||
None => Some(TorConfig::default()),
|
||||
},
|
||||
};
|
||||
|
@ -138,7 +138,7 @@ where
|
|||
let mut abs_path = std::env::current_dir()?;
|
||||
abs_path.push(self.data_dir.clone());
|
||||
|
||||
default_config.update_paths(&PathBuf::from(abs_path));
|
||||
default_config.update_paths(&abs_path);
|
||||
let res = default_config.write_to_file(config_file_name.to_str().unwrap());
|
||||
if let Err(e) = res {
|
||||
let msg = format!(
|
||||
|
@ -180,7 +180,7 @@ where
|
|||
if !test_mode {
|
||||
if let Ok(true) = exists {
|
||||
let msg = format!("Wallet seed already exists at: {}", data_dir_name);
|
||||
return Err(ErrorKind::WalletSeedExists(msg))?;
|
||||
return Err(ErrorKind::WalletSeedExists(msg).into());
|
||||
}
|
||||
}
|
||||
WalletSeed::init_file(
|
||||
|
@ -245,10 +245,9 @@ where
|
|||
}
|
||||
|
||||
fn close_wallet(&mut self, _name: Option<&str>) -> Result<(), Error> {
|
||||
match self.backend.as_mut() {
|
||||
Some(b) => b.close()?,
|
||||
None => {}
|
||||
};
|
||||
if let Some(b) = self.backend.as_mut() {
|
||||
b.close()?
|
||||
}
|
||||
self.backend = None;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -283,7 +282,7 @@ where
|
|||
fn validate_mnemonic(&self, mnemonic: ZeroingString) -> Result<(), Error> {
|
||||
match WalletSeed::from_mnemonic(mnemonic) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => Err(ErrorKind::GenericError("Validating mnemonic".into()))?,
|
||||
Err(_) => Err(ErrorKind::GenericError("Validating mnemonic".into()).into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,9 +344,9 @@ where
|
|||
)?;
|
||||
|
||||
if orig_wallet_seed != new_wallet_seed {
|
||||
let msg = format!(
|
||||
let msg =
|
||||
"New and Old wallet seeds are not equal on password change, not removing backups."
|
||||
);
|
||||
.to_string();
|
||||
return Err(ErrorKind::Lifecycle(msg).into());
|
||||
}
|
||||
// Removin
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::util;
|
|||
use crate::{Error, ErrorKind};
|
||||
use failure::ResultExt;
|
||||
|
||||
pub const SEED_FILE: &'static str = "wallet.seed";
|
||||
pub const SEED_FILE: &str = "wallet.seed";
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct WalletSeed(Vec<u8>);
|
||||
|
@ -108,10 +108,8 @@ impl WalletSeed {
|
|||
i += 1;
|
||||
}
|
||||
path.push(backup_seed_file_name.clone());
|
||||
if let Err(_) = fs::rename(seed_file_name, backup_seed_file_name.as_str()) {
|
||||
return Err(ErrorKind::GenericError(
|
||||
"Can't rename wallet seed file".to_owned(),
|
||||
))?;
|
||||
if fs::rename(seed_file_name, backup_seed_file_name.as_str()).is_err() {
|
||||
return Err(ErrorKind::GenericError("Can't rename wallet seed file".to_owned()).into());
|
||||
}
|
||||
warn!("{} backed up as {}", seed_file_name, backup_seed_file_name);
|
||||
Ok(backup_seed_file_name)
|
||||
|
@ -133,7 +131,8 @@ impl WalletSeed {
|
|||
data_file_dir.to_owned(),
|
||||
"To create a new wallet from a recovery phrase, use 'grin-wallet init -r'"
|
||||
.to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
let seed = WalletSeed::from_mnemonic(word_list)?;
|
||||
let enc_seed = EncryptedWalletSeed::from_seed(&seed, password)?;
|
||||
|
@ -162,7 +161,7 @@ impl WalletSeed {
|
|||
if exists && !test_mode {
|
||||
let msg = format!("Wallet seed already exists at: {}", data_file_dir);
|
||||
error!("{}", msg);
|
||||
return Err(ErrorKind::WalletSeedExists(msg))?;
|
||||
return Err(ErrorKind::WalletSeedExists(msg).into());
|
||||
}
|
||||
|
||||
let seed = match recovery_phrase {
|
||||
|
@ -203,7 +202,7 @@ impl WalletSeed {
|
|||
Run \"grin-wallet init\" to initialize a new wallet.",
|
||||
seed_file_path
|
||||
);
|
||||
Err(ErrorKind::WalletSeedDoesntExist)?
|
||||
Err(ErrorKind::WalletSeedDoesntExist.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +241,7 @@ impl EncryptedWalletSeed {
|
|||
let mut key = [0; 32];
|
||||
pbkdf2::derive(&digest::SHA512, 100, &salt, password, &mut key);
|
||||
let content = seed.0.to_vec();
|
||||
let mut enc_bytes = content.clone();
|
||||
let mut enc_bytes = content;
|
||||
let suffix_len = aead::CHACHA20_POLY1305.tag_len();
|
||||
for _ in 0..suffix_len {
|
||||
enc_bytes.push(0);
|
||||
|
@ -262,15 +261,15 @@ impl EncryptedWalletSeed {
|
|||
pub fn decrypt(&self, password: &str) -> Result<WalletSeed, Error> {
|
||||
let mut encrypted_seed = match util::from_hex(self.encrypted_seed.clone()) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return Err(ErrorKind::Encryption)?,
|
||||
Err(_) => return Err(ErrorKind::Encryption.into()),
|
||||
};
|
||||
let salt = match util::from_hex(self.salt.clone()) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return Err(ErrorKind::Encryption)?,
|
||||
Err(_) => return Err(ErrorKind::Encryption.into()),
|
||||
};
|
||||
let nonce = match util::from_hex(self.nonce.clone()) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return Err(ErrorKind::Encryption)?,
|
||||
Err(_) => return Err(ErrorKind::Encryption.into()),
|
||||
};
|
||||
let password = password.as_bytes();
|
||||
let mut key = [0; 32];
|
||||
|
|
|
@ -142,9 +142,7 @@ impl NodeClient for HTTPNodeClient {
|
|||
) -> Result<Option<(TxKernel, u64, u64)>, libwallet::Error> {
|
||||
let version = self
|
||||
.get_version_info()
|
||||
.ok_or(libwallet::ErrorKind::ClientCallback(
|
||||
"Unable to get version".into(),
|
||||
))?;
|
||||
.ok_or_else(|| libwallet::ErrorKind::ClientCallback("Unable to get version".into()))?;
|
||||
let version = Version::parse(&version.node_version)
|
||||
.map_err(|_| libwallet::ErrorKind::ClientCallback("Unable to parse version".into()))?;
|
||||
if version <= Version::new(2, 0, 0) {
|
||||
|
@ -159,12 +157,12 @@ impl NodeClient for HTTPNodeClient {
|
|||
query += &format!("min_height={}", h);
|
||||
}
|
||||
if let Some(h) = max_height {
|
||||
if query.len() > 0 {
|
||||
if !query.is_empty() {
|
||||
query += "&";
|
||||
}
|
||||
query += &format!("max_height={}", h);
|
||||
}
|
||||
if query.len() > 0 {
|
||||
if !query.is_empty() {
|
||||
query.insert_str(0, "?");
|
||||
}
|
||||
|
||||
|
@ -292,7 +290,7 @@ impl NodeClient for HTTPNodeClient {
|
|||
out,
|
||||
e);
|
||||
error!("{}", msg);
|
||||
Err(libwallet::ErrorKind::ClientCallback(msg))?
|
||||
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
|
||||
}
|
||||
};
|
||||
let block_height = match out.block_height {
|
||||
|
@ -302,7 +300,7 @@ impl NodeClient for HTTPNodeClient {
|
|||
out.commit,
|
||||
out);
|
||||
error!("{}", msg);
|
||||
Err(libwallet::ErrorKind::ClientCallback(msg))?
|
||||
return Err(libwallet::ErrorKind::ClientCallback(msg).into());
|
||||
}
|
||||
};
|
||||
api_outputs.push((
|
||||
|
@ -322,7 +320,7 @@ impl NodeClient for HTTPNodeClient {
|
|||
addr, e
|
||||
);
|
||||
let report = format!("outputs by pmmr index: {}", e);
|
||||
Err(libwallet::ErrorKind::ClientCallback(report))?
|
||||
Err(libwallet::ErrorKind::ClientCallback(report).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -349,7 +347,7 @@ impl NodeClient for HTTPNodeClient {
|
|||
// if we got anything other than 200 back from server, bye
|
||||
error!("heightstopmmr: error contacting {}. Error: {}", addr, e);
|
||||
let report = format!(": {}", e);
|
||||
Err(libwallet::ErrorKind::ClientCallback(report))?
|
||||
Err(libwallet::ErrorKind::ClientCallback(report).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ fn get_output_local(chain: &chain::Chain, commit: &pedersen::Commitment) -> Opti
|
|||
];
|
||||
|
||||
for x in outputs.iter() {
|
||||
if let Ok(_) = chain.is_unspent(&x) {
|
||||
if chain.is_unspent(&x).is_ok() {
|
||||
let block_height = chain.get_header_for_output(&x).unwrap().height;
|
||||
let output_pos = chain.get_output_pos(&x.commit).unwrap_or(0);
|
||||
return Some(api::Output::new(&commit, block_height, output_pos));
|
||||
|
@ -221,8 +221,7 @@ where
|
|||
let slate_i = owner::init_send_tx(&mut **w, keychain_mask, args, test_mode)?;
|
||||
let slate = client.send_tx_slate_direct(dest, &slate_i)?;
|
||||
owner::tx_lock_outputs(&mut **w, keychain_mask, &slate, 0)?;
|
||||
let slate = owner::finalize_tx(&mut **w, keychain_mask, &slate)?;
|
||||
slate
|
||||
owner::finalize_tx(&mut **w, keychain_mask, &slate)?
|
||||
};
|
||||
let client = {
|
||||
let mut w_lock = wallet.lock();
|
||||
|
|
|
@ -100,7 +100,7 @@ where
|
|||
let verifier_cache = Arc::new(RwLock::new(LruVerifierCache::new()));
|
||||
let dir_name = format!("{}/.grin", chain_dir);
|
||||
let c = Chain::init(
|
||||
dir_name.to_string(),
|
||||
dir_name,
|
||||
Arc::new(NoopAdapter {}),
|
||||
genesis_block,
|
||||
pow::verify_size,
|
||||
|
@ -109,15 +109,14 @@ where
|
|||
)
|
||||
.unwrap();
|
||||
let (tx, rx) = channel();
|
||||
let retval = WalletProxy {
|
||||
WalletProxy {
|
||||
chain_dir: chain_dir.to_owned(),
|
||||
chain: Arc::new(c),
|
||||
tx: tx,
|
||||
rx: rx,
|
||||
wallets: HashMap::new(),
|
||||
running: Arc::new(AtomicBool::new(false)),
|
||||
};
|
||||
retval
|
||||
}
|
||||
}
|
||||
|
||||
/// Add wallet with a given "address"
|
||||
|
@ -274,12 +273,12 @@ where
|
|||
&mut self,
|
||||
m: WalletProxyMessage,
|
||||
) -> Result<WalletProxyMessage, libwallet::Error> {
|
||||
let split = m.body.split(",");
|
||||
let split = m.body.split(',');
|
||||
//let mut api_outputs: HashMap<pedersen::Commitment, String> = HashMap::new();
|
||||
let mut outputs: Vec<api::Output> = vec![];
|
||||
for o in split {
|
||||
let o_str = String::from(o);
|
||||
if o_str.len() == 0 {
|
||||
if o_str.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let c = util::from_hex(o_str).unwrap();
|
||||
|
@ -302,7 +301,7 @@ where
|
|||
&mut self,
|
||||
m: WalletProxyMessage,
|
||||
) -> Result<WalletProxyMessage, libwallet::Error> {
|
||||
let split = m.body.split(",").collect::<Vec<&str>>();
|
||||
let split = m.body.split(',').collect::<Vec<&str>>();
|
||||
let start_index = split[0].parse::<u64>().unwrap();
|
||||
let max = split[1].parse::<u64>().unwrap();
|
||||
let end_index = split[2].parse::<u64>().unwrap();
|
||||
|
@ -325,7 +324,7 @@ where
|
|||
&mut self,
|
||||
m: WalletProxyMessage,
|
||||
) -> Result<WalletProxyMessage, libwallet::Error> {
|
||||
let split = m.body.split(",").collect::<Vec<&str>>();
|
||||
let split = m.body.split(',').collect::<Vec<&str>>();
|
||||
let start_index = split[0].parse::<u64>().unwrap();
|
||||
let end_index = split[1].parse::<u64>().unwrap();
|
||||
let end_index = match end_index {
|
||||
|
@ -347,7 +346,7 @@ where
|
|||
&mut self,
|
||||
m: WalletProxyMessage,
|
||||
) -> Result<WalletProxyMessage, libwallet::Error> {
|
||||
let split = m.body.split(",").collect::<Vec<&str>>();
|
||||
let split = m.body.split(',').collect::<Vec<&str>>();
|
||||
let excess = split[0].parse::<String>().unwrap();
|
||||
let min = split[1].parse::<u64>().unwrap();
|
||||
let max = split[2].parse::<u64>().unwrap();
|
||||
|
@ -457,7 +456,7 @@ impl NodeClient for LocalWalletClient {
|
|||
}
|
||||
let r = self.rx.lock();
|
||||
let m = r.recv().unwrap();
|
||||
trace!("Received post_tx response: {:?}", m.clone());
|
||||
trace!("Received post_tx response: {:?}", m);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -484,7 +483,7 @@ impl NodeClient for LocalWalletClient {
|
|||
.context(libwallet::ErrorKind::ClientCallback(
|
||||
"Parsing get_height response".to_owned(),
|
||||
))?;
|
||||
let split: Vec<&str> = res.split(",").collect();
|
||||
let split: Vec<&str> = res.split(',').collect();
|
||||
Ok((split[0].parse::<u64>().unwrap(), split[1].to_owned()))
|
||||
}
|
||||
|
||||
|
@ -495,7 +494,7 @@ impl NodeClient for LocalWalletClient {
|
|||
) -> Result<HashMap<pedersen::Commitment, (String, u64, u64)>, libwallet::Error> {
|
||||
let query_params: Vec<String> = wallet_outputs
|
||||
.iter()
|
||||
.map(|commit| format!("{}", util::to_hex(commit.as_ref().to_vec())))
|
||||
.map(|commit| util::to_hex(commit.as_ref().to_vec()))
|
||||
.collect();
|
||||
let query_str = query_params.join(",");
|
||||
let m = WalletProxyMessage {
|
||||
|
|
|
@ -28,13 +28,13 @@ use std::path::{Path, MAIN_SEPARATOR};
|
|||
|
||||
use failure::ResultExt;
|
||||
|
||||
const SEC_KEY_FILE: &'static str = "hs_ed25519_secret_key";
|
||||
const PUB_KEY_FILE: &'static str = "hs_ed25519_public_key";
|
||||
const HOSTNAME_FILE: &'static str = "hostname";
|
||||
const TORRC_FILE: &'static str = "torrc";
|
||||
const TOR_DATA_DIR: &'static str = "data";
|
||||
const AUTH_CLIENTS_DIR: &'static str = "authorized_clients";
|
||||
const HIDDEN_SERVICES_DIR: &'static str = "onion_service_addresses";
|
||||
const SEC_KEY_FILE: &str = "hs_ed25519_secret_key";
|
||||
const PUB_KEY_FILE: &str = "hs_ed25519_public_key";
|
||||
const HOSTNAME_FILE: &str = "hostname";
|
||||
const TORRC_FILE: &str = "torrc";
|
||||
const TOR_DATA_DIR: &str = "data";
|
||||
const AUTH_CLIENTS_DIR: &str = "authorized_clients";
|
||||
const HIDDEN_SERVICES_DIR: &str = "onion_service_addresses";
|
||||
|
||||
#[cfg(unix)]
|
||||
fn set_permissions(file_path: &str) -> Result<(), Error> {
|
||||
|
@ -100,7 +100,7 @@ pub fn create_onion_service_sec_key_file(
|
|||
let key_file_path = &format!("{}{}{}", os_directory, MAIN_SEPARATOR, SEC_KEY_FILE);
|
||||
let mut file = File::create(key_file_path).context(ErrorKind::IO)?;
|
||||
// Tag is always 32 bytes, so pad with null zeroes
|
||||
file.write("== ed25519v1-secret: type0 ==\0\0\0".as_bytes())
|
||||
file.write(b"== ed25519v1-secret: type0 ==\0\0\0")
|
||||
.context(ErrorKind::IO)?;
|
||||
let expanded_skey: ExpandedSecretKey = ExpandedSecretKey::from(sec_key);
|
||||
file.write_all(&expanded_skey.to_bytes())
|
||||
|
@ -115,7 +115,7 @@ pub fn create_onion_service_pub_key_file(
|
|||
let key_file_path = &format!("{}{}{}", os_directory, MAIN_SEPARATOR, PUB_KEY_FILE);
|
||||
let mut file = File::create(key_file_path).context(ErrorKind::IO)?;
|
||||
// Tag is always 32 bytes, so pad with null zeroes
|
||||
file.write("== ed25519v1-public: type0 ==\0\0\0".as_bytes())
|
||||
file.write(b"== ed25519v1-public: type0 ==\0\0\0")
|
||||
.context(ErrorKind::IO)?;
|
||||
file.write_all(pub_key.as_bytes()).context(ErrorKind::IO)?;
|
||||
Ok(())
|
||||
|
@ -170,7 +170,7 @@ pub fn output_torrc(
|
|||
tor_config_directory: &str,
|
||||
wallet_listener_addr: &str,
|
||||
socks_port: &str,
|
||||
service_dirs: &Vec<String>,
|
||||
service_dirs: &[String],
|
||||
) -> Result<(), Error> {
|
||||
let torrc_file_path = format!("{}{}{}", tor_config_directory, MAIN_SEPARATOR, TORRC_FILE);
|
||||
|
||||
|
@ -195,7 +195,7 @@ pub fn output_torrc(
|
|||
pub fn output_tor_listener_config(
|
||||
tor_config_directory: &str,
|
||||
wallet_listener_addr: &str,
|
||||
listener_keys: &Vec<SecretKey>,
|
||||
listener_keys: &[SecretKey],
|
||||
) -> Result<(), Error> {
|
||||
let tor_data_dir = format!("{}{}{}", tor_config_directory, MAIN_SEPARATOR, TOR_DATA_DIR);
|
||||
|
||||
|
@ -228,7 +228,7 @@ pub fn output_tor_sender_config(
|
|||
// create data directory if it doesn't exist
|
||||
fs::create_dir_all(&tor_config_dir).context(ErrorKind::IO)?;
|
||||
|
||||
output_torrc(tor_config_dir, "", socks_listener_addr, &vec![])?;
|
||||
output_torrc(tor_config_dir, "", socks_listener_addr, &[])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -238,13 +238,13 @@ pub fn is_tor_address(input: &str) -> Result<(), Error> {
|
|||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
let msg = format!("{:?}", e);
|
||||
Err(ErrorKind::NotOnion(msg).to_owned())?
|
||||
Err(ErrorKind::NotOnion(msg).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn complete_tor_address(input: &str) -> Result<String, Error> {
|
||||
let _ = is_tor_address(input)?;
|
||||
is_tor_address(input)?;
|
||||
let mut input = input.to_uppercase();
|
||||
if !input.starts_with("HTTP://") && !input.starts_with("HTTPS://") {
|
||||
input = format!("HTTP://{}", input);
|
||||
|
@ -278,7 +278,7 @@ mod tests {
|
|||
setup(test_dir);
|
||||
let secp_inst = static_secp_instance();
|
||||
let secp = secp_inst.lock();
|
||||
let mut test_rng = StepRng::new(1234567890u64, 1);
|
||||
let mut test_rng = StepRng::new(1_234_567_890_u64, 1);
|
||||
let sec_key = secp::key::SecretKey::new(&secp, &mut test_rng);
|
||||
output_onion_service_config(test_dir, &sec_key)?;
|
||||
clean_output_dir(test_dir);
|
||||
|
@ -291,9 +291,9 @@ mod tests {
|
|||
setup(test_dir);
|
||||
let secp_inst = static_secp_instance();
|
||||
let secp = secp_inst.lock();
|
||||
let mut test_rng = StepRng::new(1234567890u64, 1);
|
||||
let mut test_rng = StepRng::new(1_234_567_890_u64, 1);
|
||||
let sec_key = secp::key::SecretKey::new(&secp, &mut test_rng);
|
||||
output_tor_listener_config(test_dir, "127.0.0.1:3415", &vec![sec_key])?;
|
||||
output_tor_listener_config(test_dir, "127.0.0.1:3415", &[sec_key])?;
|
||||
clean_output_dir(test_dir);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -61,9 +61,9 @@ use std::thread;
|
|||
use sysinfo::{Process, ProcessExt, Signal};
|
||||
|
||||
#[cfg(windows)]
|
||||
const TOR_EXE_NAME: &'static str = "tor.exe";
|
||||
const TOR_EXE_NAME: &str = "tor.exe";
|
||||
#[cfg(not(windows))]
|
||||
const TOR_EXE_NAME: &'static str = "tor";
|
||||
const TOR_EXE_NAME: &str = "tor";
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
@ -160,7 +160,7 @@ impl TorProcess {
|
|||
let pid_file_name = format!("{}{}pid", d, MAIN_SEPARATOR);
|
||||
// kill off PID if its already running
|
||||
if Path::new(&pid_file_name).exists() {
|
||||
let pid = fs::read_to_string(&pid_file_name).map_err(|err| Error::IO(err))?;
|
||||
let pid = fs::read_to_string(&pid_file_name).map_err(Error::IO)?;
|
||||
let pid = pid
|
||||
.parse::<i32>()
|
||||
.map_err(|err| Error::PID(format!("{:?}", err)))?;
|
||||
|
@ -186,9 +186,9 @@ impl TorProcess {
|
|||
// split out the process id, so if we don't exit cleanly
|
||||
// we can take it down on the next run
|
||||
let pid_file_name = format!("{}{}pid", d, MAIN_SEPARATOR);
|
||||
let mut file = File::create(pid_file_name).map_err(|err| Error::IO(err))?;
|
||||
let mut file = File::create(pid_file_name).map_err(Error::IO)?;
|
||||
file.write_all(format!("{}", tor_process.id()).as_bytes())
|
||||
.map_err(|err| Error::IO(err))?;
|
||||
.map_err(Error::IO)?;
|
||||
}
|
||||
|
||||
let stdout = BufReader::new(tor_process.stdout.take().unwrap());
|
||||
|
@ -228,7 +228,7 @@ impl TorProcess {
|
|||
completion_perc: u8,
|
||||
) -> Result<BufReader<ChildStdout>, Error> {
|
||||
let re_bootstrap = Regex::new(r"^\[notice\] Bootstrapped (?P<perc>[0-9]+)%(.*): ")
|
||||
.map_err(|err| Error::Regex(err))?;
|
||||
.map_err(Error::Regex)?;
|
||||
|
||||
let timestamp_len = "May 16 02:50:08.792".len();
|
||||
let mut warnings = Vec::new();
|
||||
|
@ -253,7 +253,7 @@ impl TorProcess {
|
|||
.captures(line)
|
||||
.and_then(|c| c.name("perc"))
|
||||
.and_then(|pc| pc.as_str().parse::<u8>().ok())
|
||||
.ok_or(Error::InvalidBootstrapLine(line.to_string()))?;
|
||||
.ok_or_else(|| Error::InvalidBootstrapLine(line.to_string()))?;
|
||||
|
||||
if perc >= completion_perc {
|
||||
break;
|
||||
|
|
|
@ -37,7 +37,7 @@ where
|
|||
// for m/0: m/0/1/0, m/0/1/1
|
||||
// for m/1: m/1/1/0, m/1/1/1
|
||||
key_path.path[1] = ChildNumber::from(1);
|
||||
key_path.depth = key_path.depth + 1;
|
||||
key_path.depth += 1;
|
||||
key_path.path[key_path.depth as usize - 1] = ChildNumber::from(index);
|
||||
let key_id = Identifier::from_path(&key_path);
|
||||
let sec_key = keychain.derive_key(0, &key_id, &SwitchCommitmentType::None)?;
|
||||
|
|
|
@ -114,7 +114,7 @@ where
|
|||
false,
|
||||
use_test_rng,
|
||||
)?;
|
||||
tx::update_message(&mut *w, keychain_mask, &mut ret_slate)?;
|
||||
tx::update_message(&mut *w, keychain_mask, &ret_slate)?;
|
||||
|
||||
let keychain = w.keychain(keychain_mask)?;
|
||||
let excess = ret_slate.calc_excess(&keychain)?;
|
||||
|
@ -148,8 +148,8 @@ where
|
|||
check_ttl(w, &sl)?;
|
||||
let context = w.get_private_context(keychain_mask, sl.id.as_bytes(), 1)?;
|
||||
tx::complete_tx(&mut *w, keychain_mask, &mut sl, 1, &context)?;
|
||||
tx::update_stored_tx(&mut *w, keychain_mask, &context, &mut sl, true)?;
|
||||
tx::update_message(&mut *w, keychain_mask, &mut sl)?;
|
||||
tx::update_stored_tx(&mut *w, keychain_mask, &context, &sl, true)?;
|
||||
tx::update_message(&mut *w, keychain_mask, &sl)?;
|
||||
{
|
||||
let mut batch = w.batch(keychain_mask)?;
|
||||
batch.delete_private_context(sl.id.as_bytes(), 1)?;
|
||||
|
|
|
@ -111,15 +111,16 @@ where
|
|||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
let mut validated = false;
|
||||
if refresh_from_node {
|
||||
validated = update_wallet_state(
|
||||
let validated = if refresh_from_node {
|
||||
update_wallet_state(
|
||||
wallet_inst.clone(),
|
||||
keychain_mask,
|
||||
status_send_channel,
|
||||
false,
|
||||
)?;
|
||||
}
|
||||
)?
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
wallet_lock!(wallet_inst, w);
|
||||
let parent_key_id = w.parent_key_id();
|
||||
|
@ -150,15 +151,16 @@ where
|
|||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
let mut validated = false;
|
||||
if refresh_from_node {
|
||||
validated = update_wallet_state(
|
||||
let validated = if refresh_from_node {
|
||||
update_wallet_state(
|
||||
wallet_inst.clone(),
|
||||
keychain_mask,
|
||||
status_send_channel,
|
||||
false,
|
||||
)?;
|
||||
}
|
||||
)?
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
wallet_lock!(wallet_inst, w);
|
||||
let parent_key_id = w.parent_key_id();
|
||||
|
@ -180,15 +182,16 @@ where
|
|||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
let mut validated = false;
|
||||
if refresh_from_node {
|
||||
validated = update_wallet_state(
|
||||
let validated = if refresh_from_node {
|
||||
update_wallet_state(
|
||||
wallet_inst.clone(),
|
||||
keychain_mask,
|
||||
status_send_channel,
|
||||
false,
|
||||
)?;
|
||||
}
|
||||
)?
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
wallet_lock!(wallet_inst, w);
|
||||
let parent_key_id = w.parent_key_id();
|
||||
|
@ -216,15 +219,16 @@ where
|
|||
)
|
||||
.into());
|
||||
}
|
||||
let mut _validated = false;
|
||||
if refresh_from_node {
|
||||
_validated = update_wallet_state(
|
||||
update_wallet_state(
|
||||
wallet_inst.clone(),
|
||||
keychain_mask,
|
||||
status_send_channel,
|
||||
false,
|
||||
)?;
|
||||
}
|
||||
)?
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let txs = retrieve_txs(
|
||||
wallet_inst.clone(),
|
||||
keychain_mask,
|
||||
|
@ -469,7 +473,7 @@ where
|
|||
check_ttl(w, &ret_slate)?;
|
||||
let parent_key_id = match args.src_acct_name {
|
||||
Some(d) => {
|
||||
let pm = w.get_acct_path(d.to_owned())?;
|
||||
let pm = w.get_acct_path(d)?;
|
||||
match pm {
|
||||
Some(p) => p.path,
|
||||
None => w.parent_key_id(),
|
||||
|
@ -570,8 +574,8 @@ where
|
|||
let parent_key_id = w.parent_key_id();
|
||||
tx::complete_tx(&mut *w, keychain_mask, &mut sl, 0, &context)?;
|
||||
tx::verify_slate_payment_proof(&mut *w, keychain_mask, &parent_key_id, &context, &sl)?;
|
||||
tx::update_stored_tx(&mut *w, keychain_mask, &context, &mut sl, false)?;
|
||||
tx::update_message(&mut *w, keychain_mask, &mut sl)?;
|
||||
tx::update_stored_tx(&mut *w, keychain_mask, &context, &sl, false)?;
|
||||
tx::update_message(&mut *w, keychain_mask, &sl)?;
|
||||
{
|
||||
let mut batch = w.batch(keychain_mask)?;
|
||||
batch.delete_private_context(sl.id.as_bytes(), 0)?;
|
||||
|
@ -601,7 +605,8 @@ where
|
|||
)? {
|
||||
return Err(ErrorKind::TransactionCancellationError(
|
||||
"Can't contact running Grin node. Not Cancelling.",
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
wallet_lock!(wallet_inst, w);
|
||||
let parent_key_id = w.parent_key_id();
|
||||
|
@ -739,7 +744,7 @@ where
|
|||
{
|
||||
let parent_key_id = {
|
||||
wallet_lock!(wallet_inst, w);
|
||||
w.parent_key_id().clone()
|
||||
w.parent_key_id()
|
||||
};
|
||||
let client = {
|
||||
wallet_lock!(wallet_inst, w);
|
||||
|
@ -822,7 +827,7 @@ where
|
|||
let start_index = last_scanned_block.height.saturating_sub(100);
|
||||
|
||||
if last_scanned_block.height == 0 {
|
||||
let msg = format!("This wallet has not been scanned against the current chain. Beginning full scan... (this first scan may take a while, but subsequent scans will be much quicker)");
|
||||
let msg = "This wallet has not been scanned against the current chain. Beginning full scan... (this first scan may take a while, but subsequent scans will be much quicker)".to_string();
|
||||
if let Some(ref s) = status_send_channel {
|
||||
let _ = s.send(StatusMessage::FullScanWarn(msg));
|
||||
}
|
||||
|
@ -873,7 +878,7 @@ where
|
|||
let last_confirmed_height = w.last_confirmed_height()?;
|
||||
if let Some(e) = slate.ttl_cutoff_height {
|
||||
if last_confirmed_height >= e {
|
||||
return Err(ErrorKind::TransactionExpired)?;
|
||||
return Err(ErrorKind::TransactionExpired.into());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -906,35 +911,31 @@ where
|
|||
// Check kernel exists
|
||||
match client.get_kernel(&proof.excess, None, None) {
|
||||
Err(e) => {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
format!("Error retrieving kernel from chain: {}", e).to_owned(),
|
||||
))?;
|
||||
return Err(ErrorKind::PaymentProof(format!(
|
||||
"Error retrieving kernel from chain: {}",
|
||||
e
|
||||
))
|
||||
.into());
|
||||
}
|
||||
Ok(None) => {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
format!(
|
||||
return Err(ErrorKind::PaymentProof(format!(
|
||||
"Transaction kernel with excess {:?} not found on chain",
|
||||
proof.excess
|
||||
)
|
||||
.to_owned(),
|
||||
))?;
|
||||
))
|
||||
.into());
|
||||
}
|
||||
Ok(Some(_)) => {}
|
||||
};
|
||||
|
||||
// Check Sigs
|
||||
let recipient_pubkey = proof.recipient_address.to_ed25519()?;
|
||||
if let Err(_) = recipient_pubkey.verify(&msg, &proof.recipient_sig) {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Invalid recipient signature".to_owned(),
|
||||
))?;
|
||||
if recipient_pubkey.verify(&msg, &proof.recipient_sig).is_err() {
|
||||
return Err(ErrorKind::PaymentProof("Invalid recipient signature".to_owned()).into());
|
||||
};
|
||||
|
||||
let sender_pubkey = proof.sender_address.to_ed25519()?;
|
||||
if let Err(_) = sender_pubkey.verify(&msg, &proof.sender_sig) {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Invalid sender signature".to_owned(),
|
||||
))?;
|
||||
if sender_pubkey.verify(&msg, &proof.sender_sig).is_err() {
|
||||
return Err(ErrorKind::PaymentProof("Invalid sender signature".to_owned()).into());
|
||||
};
|
||||
|
||||
// for now, simple test as to whether one of the addresses belongs to this wallet
|
||||
|
@ -942,7 +943,7 @@ where
|
|||
let d_skey = match DalekSecretKey::from_bytes(&sec_key.0) {
|
||||
Ok(k) => k,
|
||||
Err(e) => {
|
||||
return Err(ErrorKind::ED25519Key(format!("{}", e)).to_owned())?;
|
||||
return Err(ErrorKind::ED25519Key(format!("{}", e)).into());
|
||||
}
|
||||
};
|
||||
let my_address_pubkey: DalekPublicKey = (&d_skey).into();
|
||||
|
@ -990,7 +991,7 @@ where
|
|||
{
|
||||
let parent_key_id = {
|
||||
wallet_lock!(wallet_inst, w);
|
||||
w.parent_key_id().clone()
|
||||
w.parent_key_id()
|
||||
};
|
||||
|
||||
let mut client = {
|
||||
|
|
|
@ -125,10 +125,7 @@ where
|
|||
let wallet_opened = {
|
||||
let mut w_lock = self.wallet_inst.lock();
|
||||
let w_provider = w_lock.lc_provider()?;
|
||||
match w_provider.wallet_inst() {
|
||||
Ok(_) => true,
|
||||
Err(_) => false,
|
||||
}
|
||||
w_provider.wallet_inst().is_ok()
|
||||
};
|
||||
// Business goes here
|
||||
if wallet_opened {
|
||||
|
|
|
@ -258,13 +258,7 @@ pub enum ErrorKind {
|
|||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let show_bt = match env::var("RUST_BACKTRACE") {
|
||||
Ok(r) => {
|
||||
if r == "1" {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
Ok(r) => r == "1",
|
||||
Err(_) => false,
|
||||
};
|
||||
let backtrace = match self.backtrace() {
|
||||
|
@ -273,7 +267,7 @@ impl Display for Error {
|
|||
};
|
||||
let inner_output = format!("{}", self.inner,);
|
||||
let backtrace_output = format!("\n Backtrace: {}", backtrace);
|
||||
let mut output = inner_output.clone();
|
||||
let mut output = inner_output;
|
||||
if show_bt {
|
||||
output.push_str(&backtrace_output);
|
||||
}
|
||||
|
@ -290,7 +284,7 @@ impl Error {
|
|||
pub fn cause_string(&self) -> String {
|
||||
match self.cause() {
|
||||
Some(k) => format!("{}", k),
|
||||
None => format!("Unknown"),
|
||||
None => "Unknown".to_string(),
|
||||
}
|
||||
}
|
||||
/// get cause
|
||||
|
|
|
@ -71,8 +71,8 @@ where
|
|||
K: Keychain + 'a,
|
||||
{
|
||||
let label = label.to_owned();
|
||||
if let Some(_) = wallet.acct_path_iter().find(|l| l.label == label) {
|
||||
return Err(ErrorKind::AccountLabelAlreadyExists(label.clone()).into());
|
||||
if wallet.acct_path_iter().any(|l| l.label == label) {
|
||||
return Err(ErrorKind::AccountLabelAlreadyExists(label).into());
|
||||
}
|
||||
|
||||
// We're always using paths at m/k/0 for parent keys for output derivations
|
||||
|
@ -94,7 +94,7 @@ where
|
|||
};
|
||||
|
||||
let save_path = AcctPathMapping {
|
||||
label: label.to_owned(),
|
||||
label: label,
|
||||
path: return_id.clone(),
|
||||
};
|
||||
|
||||
|
@ -118,7 +118,7 @@ where
|
|||
{
|
||||
let label = label.to_owned();
|
||||
let save_path = AcctPathMapping {
|
||||
label: label.to_owned(),
|
||||
label: label,
|
||||
path: path.clone(),
|
||||
};
|
||||
|
||||
|
|
|
@ -238,8 +238,7 @@ where
|
|||
t.update_confirmation_ts();
|
||||
batch.save_tx_log_entry(t, &parent_key_id)?;
|
||||
log_id
|
||||
} else {
|
||||
if let Some(ref mut s) = tx_stats {
|
||||
} else if let Some(ref mut s) = tx_stats {
|
||||
let ts = s.get(&parent_key_id).unwrap().clone();
|
||||
s.insert(
|
||||
parent_key_id.clone(),
|
||||
|
@ -252,7 +251,6 @@ where
|
|||
ts.log_id
|
||||
} else {
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
let _ = batch.save(OutputData {
|
||||
|
@ -269,9 +267,9 @@ where
|
|||
tx_log_entry: Some(log_id),
|
||||
});
|
||||
|
||||
let max_child_index = found_parents.get(&parent_key_id).unwrap().clone();
|
||||
let max_child_index = *found_parents.get(&parent_key_id).unwrap();
|
||||
if output.n_child >= max_child_index {
|
||||
found_parents.insert(parent_key_id.clone(), output.n_child);
|
||||
found_parents.insert(parent_key_id, output.n_child);
|
||||
}
|
||||
|
||||
batch.commit()?;
|
||||
|
@ -294,12 +292,12 @@ where
|
|||
let updated_tx_entry = if output.tx_log_entry.is_some() {
|
||||
let entries = updater::retrieve_txs(
|
||||
&mut **w,
|
||||
output.tx_log_entry.clone(),
|
||||
output.tx_log_entry,
|
||||
None,
|
||||
Some(&parent_key_id),
|
||||
false,
|
||||
)?;
|
||||
if entries.len() > 0 {
|
||||
if !entries.is_empty() {
|
||||
let mut entry = entries[0].clone();
|
||||
match entry.tx_type {
|
||||
TxLogEntryType::TxSent => entry.tx_type = TxLogEntryType::TxSentCancelled,
|
||||
|
@ -343,7 +341,7 @@ where
|
|||
}
|
||||
let (client, keychain) = {
|
||||
wallet_lock!(wallet_inst, w);
|
||||
(w.w2n_client().clone(), w.keychain(keychain_mask)?.clone())
|
||||
(w.w2n_client().clone(), w.keychain(keychain_mask)?)
|
||||
};
|
||||
|
||||
// Retrieve the actual PMMR index range we're looking for
|
||||
|
|
|
@ -131,7 +131,7 @@ where
|
|||
let keychain = wallet.keychain(keychain_mask)?;
|
||||
|
||||
let tx_entry = {
|
||||
let lock_inputs = context.get_inputs().clone();
|
||||
let lock_inputs = context.get_inputs();
|
||||
let messages = Some(slate.participant_messages());
|
||||
let slate_id = slate.id;
|
||||
let height = slate.height;
|
||||
|
@ -139,15 +139,14 @@ where
|
|||
let mut batch = wallet.batch(keychain_mask)?;
|
||||
let log_id = batch.next_tx_log_id(&parent_key_id)?;
|
||||
let mut t = TxLogEntry::new(parent_key_id.clone(), TxLogEntryType::TxSent, log_id);
|
||||
t.tx_slate_id = Some(slate_id.clone());
|
||||
t.tx_slate_id = Some(slate_id);
|
||||
let filename = format!("{}.grintx", slate_id);
|
||||
t.stored_tx = Some(filename);
|
||||
t.fee = Some(slate.fee);
|
||||
t.ttl_cutoff_height = slate.ttl_cutoff_height;
|
||||
|
||||
match slate.calc_excess(&keychain) {
|
||||
Ok(e) => t.kernel_excess = Some(e),
|
||||
Err(_) => {}
|
||||
if let Ok(e) = slate.calc_excess(&keychain) {
|
||||
t.kernel_excess = Some(e)
|
||||
}
|
||||
t.kernel_lookup_min_height = Some(slate.height);
|
||||
|
||||
|
@ -156,7 +155,7 @@ where
|
|||
for id in lock_inputs {
|
||||
let mut coin = batch.get(&id.0, &id.1).unwrap();
|
||||
coin.tx_log_entry = Some(log_id);
|
||||
amount_debited = amount_debited + coin.value;
|
||||
amount_debited += coin.value;
|
||||
batch.lock_output(&mut coin)?;
|
||||
}
|
||||
|
||||
|
@ -170,7 +169,8 @@ where
|
|||
None => {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Payment proof derivation index required".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
let sender_key = address::address_from_derivation_path(
|
||||
|
@ -180,8 +180,8 @@ where
|
|||
)?;
|
||||
let sender_address = OnionV3Address::from_private(&sender_key.0)?;
|
||||
t.payment_proof = Some(StoredProofInfo {
|
||||
receiver_address: p.receiver_address.clone(),
|
||||
receiver_signature: p.receiver_signature.clone(),
|
||||
receiver_address: p.receiver_address,
|
||||
receiver_signature: p.receiver_signature,
|
||||
sender_address: sender_address.to_ed25519()?,
|
||||
sender_address_path,
|
||||
sender_signature: None,
|
||||
|
@ -199,7 +199,7 @@ where
|
|||
n_child: id.to_path().last_path_index(),
|
||||
commit: commit,
|
||||
mmr_index: None,
|
||||
value: change_amount.clone(),
|
||||
value: change_amount,
|
||||
status: OutputStatus::Unconfirmed,
|
||||
height: height,
|
||||
lock_height: 0,
|
||||
|
@ -237,7 +237,7 @@ where
|
|||
let amount = slate.amount;
|
||||
let height = slate.height;
|
||||
|
||||
let slate_id = slate.id.clone();
|
||||
let slate_id = slate.id;
|
||||
let blinding = slate.add_transaction_elements(
|
||||
&keychain,
|
||||
&ProofBuilder::new(&keychain),
|
||||
|
@ -267,9 +267,8 @@ where
|
|||
t.messages = messages;
|
||||
t.ttl_cutoff_height = slate.ttl_cutoff_height;
|
||||
// when invoicing, this will be invalid
|
||||
match slate.calc_excess(&keychain) {
|
||||
Ok(e) => t.kernel_excess = Some(e),
|
||||
Err(_) => {}
|
||||
if let Ok(e) = slate.calc_excess(&keychain) {
|
||||
t.kernel_excess = Some(e)
|
||||
}
|
||||
t.kernel_lookup_min_height = Some(slate.height);
|
||||
batch.save(OutputData {
|
||||
|
@ -390,7 +389,8 @@ where
|
|||
available_disp: amount_to_hr_string(0, false),
|
||||
needed: amount_with_fee as u64,
|
||||
needed_disp: amount_to_hr_string(amount_with_fee as u64, false),
|
||||
})?;
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
// The amount with fee is more than the total values of our max outputs
|
||||
|
@ -400,7 +400,8 @@ where
|
|||
available_disp: amount_to_hr_string(total, false),
|
||||
needed: amount_with_fee as u64,
|
||||
needed_disp: amount_to_hr_string(amount_with_fee as u64, false),
|
||||
})?;
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
let num_outputs = change_outputs + 1;
|
||||
|
@ -420,7 +421,8 @@ where
|
|||
available_disp: amount_to_hr_string(total, false),
|
||||
needed: amount_with_fee as u64,
|
||||
needed_disp: amount_to_hr_string(amount_with_fee as u64, false),
|
||||
})?;
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
// select some spendable coins from the wallet
|
||||
|
@ -444,7 +446,7 @@ where
|
|||
|
||||
/// Selects inputs and change for a transaction
|
||||
pub fn inputs_and_change<'a, T: ?Sized, C, K, B>(
|
||||
coins: &Vec<OutputData>,
|
||||
coins: &[OutputData],
|
||||
wallet: &mut T,
|
||||
keychain_mask: Option<&SecretKey>,
|
||||
amount: u64,
|
||||
|
@ -559,7 +561,7 @@ where
|
|||
// wants to send. So the wallet considers max_outputs more of a soft limit.
|
||||
if eligible.len() > max_outputs {
|
||||
for window in eligible.windows(max_outputs) {
|
||||
let windowed_eligibles = window.iter().cloned().collect::<Vec<_>>();
|
||||
let windowed_eligibles = window.to_vec();
|
||||
if let Some(outputs) = select_from(amount, select_all, windowed_eligibles) {
|
||||
return (max_available, outputs);
|
||||
}
|
||||
|
@ -574,11 +576,9 @@ where
|
|||
);
|
||||
return (max_available, outputs);
|
||||
}
|
||||
} else {
|
||||
if let Some(outputs) = select_from(amount, select_all, eligible.clone()) {
|
||||
} else if let Some(outputs) = select_from(amount, select_all, eligible.clone()) {
|
||||
return (max_available, outputs);
|
||||
}
|
||||
}
|
||||
|
||||
// we failed to find a suitable set of outputs to spend,
|
||||
// so return the largest amount we can so we can provide guidance on what is
|
||||
|
@ -594,10 +594,10 @@ fn select_from(amount: u64, select_all: bool, outputs: Vec<OutputData>) -> Optio
|
|||
let total = outputs.iter().fold(0, |acc, x| acc + x.value);
|
||||
if total >= amount {
|
||||
if select_all {
|
||||
return Some(outputs.iter().cloned().collect());
|
||||
Some(outputs.to_vec())
|
||||
} else {
|
||||
let mut selected_amount = 0;
|
||||
return Some(
|
||||
Some(
|
||||
outputs
|
||||
.iter()
|
||||
.take_while(|out| {
|
||||
|
@ -607,7 +607,7 @@ fn select_from(amount: u64, select_all: bool, outputs: Vec<OutputData>) -> Optio
|
|||
})
|
||||
.cloned()
|
||||
.collect(),
|
||||
);
|
||||
)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -181,7 +181,7 @@ where
|
|||
// Generate a kernel offset and subtract from our context's secret key. Store
|
||||
// the offset in the slate's transaction kernel, and adds our public key
|
||||
// information to the slate
|
||||
let _ = slate.fill_round_1(
|
||||
slate.fill_round_1(
|
||||
&wallet.keychain(keychain_mask)?,
|
||||
&mut context.sec_key,
|
||||
&context.sec_nonce,
|
||||
|
@ -192,7 +192,7 @@ where
|
|||
|
||||
if !is_initator {
|
||||
// perform partial sig
|
||||
let _ = slate.fill_round_2(
|
||||
slate.fill_round_2(
|
||||
&wallet.keychain(keychain_mask)?,
|
||||
&context.sec_key,
|
||||
&context.sec_nonce,
|
||||
|
@ -229,7 +229,7 @@ where
|
|||
)?;
|
||||
|
||||
// fill public keys
|
||||
let _ = slate.fill_round_1(
|
||||
slate.fill_round_1(
|
||||
&wallet.keychain(keychain_mask)?,
|
||||
&mut context.sec_key,
|
||||
&context.sec_nonce,
|
||||
|
@ -240,7 +240,7 @@ where
|
|||
|
||||
if !is_initiator {
|
||||
// perform partial sig
|
||||
let _ = slate.fill_round_2(
|
||||
slate.fill_round_2(
|
||||
&wallet.keychain(keychain_mask)?,
|
||||
&context.sec_key,
|
||||
&context.sec_nonce,
|
||||
|
@ -264,7 +264,7 @@ where
|
|||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
let _ = slate.fill_round_2(
|
||||
slate.fill_round_2(
|
||||
&wallet.keychain(keychain_mask)?,
|
||||
&context.sec_key,
|
||||
&context.sec_nonce,
|
||||
|
@ -297,14 +297,14 @@ where
|
|||
}
|
||||
let tx_vec = updater::retrieve_txs(wallet, tx_id, tx_slate_id, Some(&parent_key_id), false)?;
|
||||
if tx_vec.len() != 1 {
|
||||
return Err(ErrorKind::TransactionDoesntExist(tx_id_string))?;
|
||||
return Err(ErrorKind::TransactionDoesntExist(tx_id_string).into());
|
||||
}
|
||||
let tx = tx_vec[0].clone();
|
||||
if tx.tx_type != TxLogEntryType::TxSent && tx.tx_type != TxLogEntryType::TxReceived {
|
||||
return Err(ErrorKind::TransactionNotCancellable(tx_id_string))?;
|
||||
return Err(ErrorKind::TransactionNotCancellable(tx_id_string).into());
|
||||
}
|
||||
if tx.confirmed == true {
|
||||
return Err(ErrorKind::TransactionNotCancellable(tx_id_string))?;
|
||||
if tx.confirmed {
|
||||
return Err(ErrorKind::TransactionNotCancellable(tx_id_string).into());
|
||||
}
|
||||
// get outputs associated with tx
|
||||
let res = updater::retrieve_outputs(
|
||||
|
@ -338,17 +338,17 @@ where
|
|||
// don't want to assume this is the right tx, in case of self-sending
|
||||
for t in tx_vec {
|
||||
if t.tx_type == TxLogEntryType::TxSent && !is_invoiced {
|
||||
tx = Some(t.clone());
|
||||
tx = Some(t);
|
||||
break;
|
||||
}
|
||||
if t.tx_type == TxLogEntryType::TxReceived && is_invoiced {
|
||||
tx = Some(t.clone());
|
||||
tx = Some(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let mut tx = match tx {
|
||||
Some(t) => t,
|
||||
None => return Err(ErrorKind::TransactionDoesntExist(slate.id.to_string()))?,
|
||||
None => return Err(ErrorKind::TransactionDoesntExist(slate.id.to_string()).into()),
|
||||
};
|
||||
wallet.store_tx(&format!("{}", tx.tx_slate_id.unwrap()), &slate.tx)?;
|
||||
let parent_key = tx.parent_key_id.clone();
|
||||
|
@ -395,7 +395,7 @@ where
|
|||
{
|
||||
let tx_vec = updater::retrieve_txs(wallet, None, Some(slate.id), None, false)?;
|
||||
if tx_vec.is_empty() {
|
||||
return Err(ErrorKind::TransactionDoesntExist(slate.id.to_string()))?;
|
||||
return Err(ErrorKind::TransactionDoesntExist(slate.id.to_string()).into());
|
||||
}
|
||||
let mut batch = wallet.batch(keychain_mask)?;
|
||||
for mut tx in tx_vec.into_iter() {
|
||||
|
@ -420,7 +420,7 @@ pub fn payment_proof_message(
|
|||
}
|
||||
|
||||
pub fn _decode_payment_proof_message(
|
||||
msg: &Vec<u8>,
|
||||
msg: &[u8],
|
||||
) -> Result<(u64, pedersen::Commitment, DalekPublicKey), Error> {
|
||||
let mut rdr = Cursor::new(msg);
|
||||
let amount = rdr.read_u64::<BigEndian>()?;
|
||||
|
@ -451,7 +451,7 @@ pub fn create_payment_proof_signature(
|
|||
let d_skey = match DalekSecretKey::from_bytes(&sec_key.0) {
|
||||
Ok(k) => k,
|
||||
Err(e) => {
|
||||
return Err(ErrorKind::ED25519Key(format!("{}", e)).to_owned())?;
|
||||
return Err(ErrorKind::ED25519Key(format!("{}", e)).into());
|
||||
}
|
||||
};
|
||||
let pub_key: DalekPublicKey = (&d_skey).into();
|
||||
|
@ -476,10 +476,11 @@ where
|
|||
K: Keychain + 'a,
|
||||
{
|
||||
let tx_vec = updater::retrieve_txs(wallet, None, Some(slate.id), Some(parent_key_id), false)?;
|
||||
if tx_vec.len() == 0 {
|
||||
if tx_vec.is_empty() {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"TxLogEntry with original proof info not found (is account correct?)".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let orig_proof_info = tx_vec[0].clone().payment_proof;
|
||||
|
@ -487,7 +488,8 @@ where
|
|||
if orig_proof_info.is_some() && slate.payment_proof.is_none() {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Expected Payment Proof for this Transaction is not present".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
if let Some(ref p) = slate.payment_proof {
|
||||
|
@ -496,7 +498,8 @@ where
|
|||
None => {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Original proof info not stored in tx".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
let keychain = wallet.keychain(keychain_mask)?;
|
||||
|
@ -505,7 +508,8 @@ where
|
|||
None => {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Payment proof derivation index required".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
let orig_sender_sk =
|
||||
|
@ -514,13 +518,15 @@ where
|
|||
if p.sender_address != orig_sender_address.to_ed25519()? {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Sender address on slate does not match original sender address".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
if orig_proof_info.receiver_address != p.receiver_address {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Recipient address on slate does not match original recipient address".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
let msg = payment_proof_message(
|
||||
slate.amount,
|
||||
|
@ -532,14 +538,13 @@ where
|
|||
None => {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Recipient did not provide requested proof signature".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(_) = p.receiver_address.verify(&msg, &sig) {
|
||||
return Err(ErrorKind::PaymentProof(
|
||||
"Invalid proof signature".to_owned(),
|
||||
))?;
|
||||
if p.receiver_address.verify(&msg, &sig).is_err() {
|
||||
return Err(ErrorKind::PaymentProof("Invalid proof signature".to_owned()).into());
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
|
@ -588,7 +593,7 @@ mod test {
|
|||
fn payment_proof_construction() {
|
||||
let secp_inst = static_secp_instance();
|
||||
let secp = secp_inst.lock();
|
||||
let mut test_rng = StepRng::new(1234567890u64, 1);
|
||||
let mut test_rng = StepRng::new(1_234_567_890_u64, 1);
|
||||
let sec_key = secp::key::SecretKey::new(&secp, &mut test_rng);
|
||||
let d_skey = DalekSecretKey::from_bytes(&sec_key.0).unwrap();
|
||||
|
||||
|
@ -615,7 +620,7 @@ mod test {
|
|||
.unwrap()
|
||||
};
|
||||
|
||||
let amount = 12345678u64;
|
||||
let amount = 1_234_567_890_u64;
|
||||
let msg = payment_proof_message(amount, &kernel_excess, address).unwrap();
|
||||
println!("payment proof message is (len {}): {:?}", msg.len(), msg);
|
||||
|
||||
|
|
|
@ -66,8 +66,8 @@ where
|
|||
outputs = outputs
|
||||
.iter()
|
||||
.filter(|o| o.root_key_id == *k)
|
||||
.map(|o| o.clone())
|
||||
.collect();
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
outputs.sort_by_key(|out| out.n_child);
|
||||
|
@ -178,13 +178,7 @@ where
|
|||
false => unspents
|
||||
.into_iter()
|
||||
.filter(|x| match x.tx_log_entry.as_ref() {
|
||||
Some(t) => {
|
||||
if let Some(_) = tx_entries.iter().find(|&te| te.id == *t) {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
Some(t) => tx_entries.iter().any(|te| te.id == *t),
|
||||
None => true,
|
||||
})
|
||||
.collect(),
|
||||
|
@ -228,7 +222,7 @@ where
|
|||
batch.save(o)?;
|
||||
}
|
||||
}
|
||||
let mut tx = tx.clone();
|
||||
let mut tx = tx;
|
||||
if tx.tx_type == TxLogEntryType::TxSent {
|
||||
tx.tx_type = TxLogEntryType::TxSentCancelled;
|
||||
}
|
||||
|
@ -291,8 +285,7 @@ where
|
|||
let secp = static_secp_instance();
|
||||
let secp = secp.lock();
|
||||
let over_commit = secp.commit_value(output.value)?;
|
||||
let excess =
|
||||
secp.commit_sum(vec![commit.clone()], vec![over_commit])?;
|
||||
let excess = secp.commit_sum(vec![*commit], vec![over_commit])?;
|
||||
t.kernel_excess = Some(excess);
|
||||
t.kernel_lookup_min_height = Some(height);
|
||||
}
|
||||
|
@ -350,7 +343,7 @@ where
|
|||
// and a list of outputs we want to query the node for
|
||||
let wallet_outputs = map_wallet_outputs(wallet, keychain_mask, parent_key_id, update_all)?;
|
||||
|
||||
let wallet_output_keys = wallet_outputs.keys().map(|commit| commit.clone()).collect();
|
||||
let wallet_output_keys = wallet_outputs.keys().copied().collect();
|
||||
|
||||
let api_outputs = wallet
|
||||
.w2n_client()
|
||||
|
|
|
@ -122,7 +122,7 @@ impl ParticipantMessageData {
|
|||
id: p.id,
|
||||
public_key: p.public_blind_excess,
|
||||
message: p.message.clone(),
|
||||
message_sig: p.message_sig.clone(),
|
||||
message_sig: p.message_sig,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ impl fmt::Display for ParticipantMessageData {
|
|||
Some(m) => m,
|
||||
};
|
||||
writeln!(f, "Message: {}", message)?;
|
||||
let message_sig = match self.message_sig.clone() {
|
||||
let message_sig = match self.message_sig {
|
||||
None => "None".to_owned(),
|
||||
Some(m) => grin_util::to_hex(m.to_raw_data().to_vec()),
|
||||
};
|
||||
|
@ -401,7 +401,7 @@ impl Slate {
|
|||
.collect();
|
||||
match PublicKey::from_combination(secp, pub_nonces) {
|
||||
Ok(k) => Ok(k),
|
||||
Err(e) => Err(ErrorKind::Secp(e))?,
|
||||
Err(e) => Err(ErrorKind::Secp(e).into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,7 +414,7 @@ impl Slate {
|
|||
.collect();
|
||||
match PublicKey::from_combination(secp, pub_blinds) {
|
||||
Ok(k) => Ok(k),
|
||||
Err(e) => Err(ErrorKind::Secp(e))?,
|
||||
Err(e) => Err(ErrorKind::Secp(e).into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,7 +513,7 @@ impl Slate {
|
|||
}
|
||||
true => {
|
||||
// allow for consistent test results
|
||||
let mut test_rng = StepRng::new(1234567890u64, 1);
|
||||
let mut test_rng = StepRng::new(1_234_567_890_u64, 1);
|
||||
BlindingFactor::from_secret_key(SecretKey::new(&keychain.secp(), &mut test_rng))
|
||||
}
|
||||
};
|
||||
|
@ -540,9 +540,9 @@ impl Slate {
|
|||
);
|
||||
|
||||
if fee > self.tx.fee() {
|
||||
return Err(ErrorKind::Fee(
|
||||
format!("Fee Dispute Error: {}, {}", self.tx.fee(), fee,).to_string(),
|
||||
))?;
|
||||
return Err(
|
||||
ErrorKind::Fee(format!("Fee Dispute Error: {}, {}", self.tx.fee(), fee,)).into(),
|
||||
);
|
||||
}
|
||||
|
||||
if fee > self.amount + self.fee {
|
||||
|
@ -552,7 +552,7 @@ impl Slate {
|
|||
amount_to_hr_string(self.amount + self.fee, false)
|
||||
);
|
||||
info!("{}", reason);
|
||||
return Err(ErrorKind::Fee(reason.to_string()))?;
|
||||
return Err(ErrorKind::Fee(reason).into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -589,7 +589,8 @@ impl Slate {
|
|||
String::from_utf8_lossy(&msg.as_bytes()[..]));
|
||||
return Err(ErrorKind::Signature(
|
||||
"Optional participant messages doesn't have signature".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
}
|
||||
Some(s) => s,
|
||||
};
|
||||
|
@ -606,7 +607,8 @@ impl Slate {
|
|||
String::from_utf8_lossy(&msg.as_bytes()[..]));
|
||||
return Err(ErrorKind::Signature(
|
||||
"Optional participant messages do not match signatures".to_owned(),
|
||||
))?;
|
||||
)
|
||||
.into());
|
||||
} else {
|
||||
info!(
|
||||
"verify_messages - signature verified ok. Participant message: \"{}\"",
|
||||
|
@ -709,7 +711,7 @@ impl Slate {
|
|||
// confirm the overall transaction is valid (including the updated kernel)
|
||||
// accounting for tx weight limits
|
||||
let verifier_cache = Arc::new(RwLock::new(LruVerifierCache::new()));
|
||||
let _ = final_tx.validate(Weighting::AsTransaction, verifier_cache)?;
|
||||
final_tx.validate(Weighting::AsTransaction, verifier_cache)?;
|
||||
|
||||
self.tx = final_tx;
|
||||
Ok(())
|
||||
|
|
|
@ -82,10 +82,7 @@ impl VersionedSlate {
|
|||
impl From<VersionedSlate> for Slate {
|
||||
fn from(slate: VersionedSlate) -> Slate {
|
||||
match slate {
|
||||
VersionedSlate::V3(s) => {
|
||||
let s = SlateV3::from(s);
|
||||
Slate::from(s)
|
||||
}
|
||||
VersionedSlate::V3(s) => Slate::from(s),
|
||||
VersionedSlate::V2(s) => {
|
||||
let s = SlateV3::from(s);
|
||||
Slate::from(s)
|
||||
|
|
|
@ -70,7 +70,7 @@ pub mod ov3_serde {
|
|||
String::deserialize(deserializer).and_then(|s| {
|
||||
OnionV3Address::try_from(s.as_str())
|
||||
.map_err(|err: OnionV3AddressError| Error::custom(format!("{:?}", err)))
|
||||
.and_then(|a| Ok(a))
|
||||
.and_then(Ok)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -128,13 +128,13 @@ pub mod option_dalek_pubkey_serde {
|
|||
D: Deserializer<'de>,
|
||||
{
|
||||
Option::<String>::deserialize(deserializer).and_then(|res| match res {
|
||||
Some(string) => from_hex(string.to_string())
|
||||
Some(string) => from_hex(string)
|
||||
.map_err(|err| Error::custom(err.to_string()))
|
||||
.and_then(|bytes: Vec<u8>| {
|
||||
let mut b = [0u8; 32];
|
||||
b.copy_from_slice(&bytes[0..32]);
|
||||
DalekPublicKey::from_bytes(&b)
|
||||
.map(|val| Some(val))
|
||||
.map(Some)
|
||||
.map_err(|err| Error::custom(err.to_string()))
|
||||
}),
|
||||
None => Ok(None),
|
||||
|
@ -198,13 +198,13 @@ pub mod option_dalek_sig_serde {
|
|||
D: Deserializer<'de>,
|
||||
{
|
||||
Option::<String>::deserialize(deserializer).and_then(|res| match res {
|
||||
Some(string) => from_hex(string.to_string())
|
||||
Some(string) => from_hex(string)
|
||||
.map_err(|err| Error::custom(err.to_string()))
|
||||
.and_then(|bytes: Vec<u8>| {
|
||||
let mut b = [0u8; 64];
|
||||
b.copy_from_slice(&bytes[0..64]);
|
||||
DalekSignature::from_bytes(&b)
|
||||
.map(|val| Some(val))
|
||||
.map(Some)
|
||||
.map_err(|err| Error::custom(err.to_string()))
|
||||
}),
|
||||
None => Ok(None),
|
||||
|
|
|
@ -221,19 +221,19 @@ where
|
|||
fn batch_no_mask<'a>(&'a mut self) -> Result<Box<dyn WalletOutputBatch<K> + 'a>, Error>;
|
||||
|
||||
/// Return the current child Index
|
||||
fn current_child_index<'a>(&mut self, parent_key_id: &Identifier) -> Result<u32, Error>;
|
||||
fn current_child_index(&mut self, parent_key_id: &Identifier) -> Result<u32, Error>;
|
||||
|
||||
/// Next child ID when we want to create a new output, based on current parent
|
||||
fn next_child<'a>(&mut self, keychain_mask: Option<&SecretKey>) -> Result<Identifier, Error>;
|
||||
fn next_child(&mut self, keychain_mask: Option<&SecretKey>) -> Result<Identifier, Error>;
|
||||
|
||||
/// last verified height of outputs directly descending from the given parent key
|
||||
fn last_confirmed_height<'a>(&mut self) -> Result<u64, Error>;
|
||||
fn last_confirmed_height(&mut self) -> Result<u64, Error>;
|
||||
|
||||
/// last block scanned during scan or restore
|
||||
fn last_scanned_block<'a>(&mut self) -> Result<ScannedBlockInfo, Error>;
|
||||
fn last_scanned_block(&mut self) -> Result<ScannedBlockInfo, Error>;
|
||||
|
||||
/// Flag whether the wallet needs a full UTXO scan on next update attempt
|
||||
fn init_status<'a>(&mut self) -> Result<WalletInitStatus, Error>;
|
||||
fn init_status(&mut self) -> Result<WalletInitStatus, Error>;
|
||||
}
|
||||
|
||||
/// Batch trait to update the output data backend atomically. Trying to use a
|
||||
|
@ -274,7 +274,7 @@ where
|
|||
fn save_last_scanned_block(&mut self, block: ScannedBlockInfo) -> Result<(), Error>;
|
||||
|
||||
/// Save flag indicating whether wallet needs a full UTXO scan
|
||||
fn save_init_status<'a>(&mut self, value: WalletInitStatus) -> Result<(), Error>;
|
||||
fn save_init_status(&mut self, value: WalletInitStatus) -> Result<(), Error>;
|
||||
|
||||
/// get next tx log entry for the parent
|
||||
fn next_tx_log_id(&mut self, parent_key_id: &Identifier) -> Result<u32, Error>;
|
||||
|
@ -469,29 +469,23 @@ impl OutputData {
|
|||
/// Check if output is eligible to spend based on state and height and
|
||||
/// confirmations
|
||||
pub fn eligible_to_spend(&self, current_height: u64, minimum_confirmations: u64) -> bool {
|
||||
if [OutputStatus::Spent, OutputStatus::Locked].contains(&self.status) {
|
||||
return false;
|
||||
} else if self.status == OutputStatus::Unconfirmed && self.is_coinbase {
|
||||
return false;
|
||||
} else if self.lock_height > current_height {
|
||||
return false;
|
||||
} else if self.status == OutputStatus::Unspent
|
||||
&& self.num_confirmations(current_height) >= minimum_confirmations
|
||||
if [OutputStatus::Spent, OutputStatus::Locked].contains(&self.status)
|
||||
|| self.status == OutputStatus::Unconfirmed && self.is_coinbase
|
||||
|| self.lock_height > current_height
|
||||
{
|
||||
return true;
|
||||
} else if self.status == OutputStatus::Unconfirmed && minimum_confirmations == 0 {
|
||||
return true;
|
||||
false
|
||||
} else {
|
||||
return false;
|
||||
(self.status == OutputStatus::Unspent
|
||||
&& self.num_confirmations(current_height) >= minimum_confirmations)
|
||||
|| self.status == OutputStatus::Unconfirmed && minimum_confirmations == 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Marks this output as unspent if it was previously unconfirmed
|
||||
pub fn mark_unspent(&mut self) {
|
||||
match self.status {
|
||||
OutputStatus::Unconfirmed => self.status = OutputStatus::Unspent,
|
||||
_ => (),
|
||||
}
|
||||
if let OutputStatus::Unconfirmed = self.status {
|
||||
self.status = OutputStatus::Unspent
|
||||
};
|
||||
}
|
||||
|
||||
/// Mark an output as spent
|
||||
|
@ -585,7 +579,7 @@ impl Context {
|
|||
/// be kept between invocations
|
||||
pub fn add_output(&mut self, output_id: &Identifier, mmr_index: &Option<u64>, amount: u64) {
|
||||
self.output_ids
|
||||
.push((output_id.clone(), mmr_index.clone(), amount));
|
||||
.push((output_id.clone(), *mmr_index, amount));
|
||||
}
|
||||
|
||||
/// Returns all stored outputs
|
||||
|
@ -596,8 +590,7 @@ impl Context {
|
|||
/// Tracks IDs of my inputs into the transaction
|
||||
/// be kept between invocations
|
||||
pub fn add_input(&mut self, input_id: &Identifier, mmr_index: &Option<u64>, amount: u64) {
|
||||
self.input_ids
|
||||
.push((input_id.clone(), mmr_index.clone(), amount));
|
||||
self.input_ids.push((input_id.clone(), *mmr_index, amount));
|
||||
}
|
||||
|
||||
/// Returns all stored input identifiers
|
||||
|
@ -839,7 +832,7 @@ impl TxLogEntry {
|
|||
}
|
||||
|
||||
/// Given a vec of TX log entries, return credited + debited sums
|
||||
pub fn sum_confirmed(txs: &Vec<TxLogEntry>) -> (u64, u64) {
|
||||
pub fn sum_confirmed(txs: &[TxLogEntry]) -> (u64, u64) {
|
||||
txs.iter().fold((0, 0), |acc, tx| match tx.confirmed {
|
||||
true => (acc.0 + tx.amount_credited, acc.1 + tx.amount_debited),
|
||||
false => acc,
|
||||
|
|
Loading…
Reference in a new issue