mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 11:31:08 +03:00
Wallet implementation dynamic dispatch (#1235)
* add ability to instantiate wallets with different backend implementations * test fix
This commit is contained in:
parent
6450b603ea
commit
d5a6992be9
28 changed files with 258 additions and 165 deletions
|
@ -186,6 +186,9 @@ pub struct ServerConfig {
|
||||||
/// Whether to run the web wallet owner listener
|
/// Whether to run the web wallet owner listener
|
||||||
pub run_wallet_owner_api: Option<bool>,
|
pub run_wallet_owner_api: Option<bool>,
|
||||||
|
|
||||||
|
/// Whether to use the DB wallet backend implementation
|
||||||
|
pub use_db_wallet: Option<bool>,
|
||||||
|
|
||||||
/// Whether to run the test miner (internal, cuckoo 16)
|
/// Whether to run the test miner (internal, cuckoo 16)
|
||||||
pub run_test_miner: Option<bool>,
|
pub run_test_miner: Option<bool>,
|
||||||
|
|
||||||
|
@ -212,6 +215,7 @@ impl Default for ServerConfig {
|
||||||
run_tui: None,
|
run_tui: None,
|
||||||
run_wallet_listener: Some(false),
|
run_wallet_listener: Some(false),
|
||||||
run_wallet_owner_api: Some(false),
|
run_wallet_owner_api: Some(false),
|
||||||
|
use_db_wallet: Some(false),
|
||||||
run_test_miner: Some(false),
|
run_test_miner: Some(false),
|
||||||
test_miner_wallet_url: None,
|
test_miner_wallet_url: None,
|
||||||
}
|
}
|
||||||
|
@ -323,9 +327,7 @@ impl SyncState {
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
LOGGER,
|
LOGGER,
|
||||||
"sync_state: sync_status: {:?} -> {:?}",
|
"sync_state: sync_status: {:?} -> {:?}", *status, new_status,
|
||||||
*status,
|
|
||||||
new_status,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
*status = new_status;
|
*status = new_status;
|
||||||
|
|
|
@ -274,7 +274,7 @@ impl LocalServerContainer {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
wallet::controller::foreign_listener(wallet, &self.wallet_config.api_listen_addr())
|
wallet::controller::foreign_listener(Box::new(wallet), &self.wallet_config.api_listen_addr())
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
panic!(
|
panic!(
|
||||||
"Error creating wallet listener: {:?} Config: {:?}",
|
"Error creating wallet listener: {:?} Config: {:?}",
|
||||||
|
@ -330,7 +330,7 @@ impl LocalServerContainer {
|
||||||
.unwrap_or_else(|e| panic!("Error creating wallet: {:?} Config: {:?}", e, config));
|
.unwrap_or_else(|e| panic!("Error creating wallet: {:?} Config: {:?}", e, config));
|
||||||
wallet.keychain = Some(keychain);
|
wallet.keychain = Some(keychain);
|
||||||
let _ =
|
let _ =
|
||||||
wallet::controller::owner_single_use(&mut wallet, |api| {
|
wallet::controller::owner_single_use(Box::new(wallet), |api| {
|
||||||
let result = api.issue_send_tx(
|
let result = api.issue_send_tx(
|
||||||
amount,
|
amount,
|
||||||
minimum_confirmations,
|
minimum_confirmations,
|
||||||
|
|
|
@ -40,8 +40,8 @@ pub mod tui;
|
||||||
|
|
||||||
use std::env::current_dir;
|
use std::env::current_dir;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
@ -51,10 +51,9 @@ use daemonize::Daemonize;
|
||||||
use config::GlobalConfig;
|
use config::GlobalConfig;
|
||||||
use core::core::amount_to_hr_string;
|
use core::core::amount_to_hr_string;
|
||||||
use core::global;
|
use core::global;
|
||||||
use keychain::ExtKeychain;
|
|
||||||
use tui::ui;
|
use tui::ui;
|
||||||
use util::{init_logger, LoggingConfig, LOGGER};
|
use util::{init_logger, LoggingConfig, LOGGER};
|
||||||
use wallet::{libwallet, FileWallet};
|
use wallet::{libwallet, wallet_db_exists, FileWallet, LMDBBackend, WalletConfig, WalletInst};
|
||||||
|
|
||||||
// include build information
|
// include build information
|
||||||
pub mod built_info {
|
pub mod built_info {
|
||||||
|
@ -296,8 +295,11 @@ fn main() {
|
||||||
.about("basic wallet contents summary"))
|
.about("basic wallet contents summary"))
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("init")
|
.subcommand(SubCommand::with_name("init")
|
||||||
.about("Initialize a new wallet seed file."))
|
.about("Initialize a new wallet seed file.")
|
||||||
|
.arg(Arg::with_name("db")
|
||||||
|
.help("Use database backend. (Default: false)")
|
||||||
|
.short("d")
|
||||||
|
.long("db")))
|
||||||
.subcommand(SubCommand::with_name("restore")
|
.subcommand(SubCommand::with_name("restore")
|
||||||
.about("Attempt to restore wallet contents from the chain using seed and password. \
|
.about("Attempt to restore wallet contents from the chain using seed and password. \
|
||||||
NOTE: Backup wallet.* and run `wallet listen` before running restore.")))
|
NOTE: Backup wallet.* and run `wallet listen` before running restore.")))
|
||||||
|
@ -437,19 +439,14 @@ fn server_command(server_args: Option<&ArgMatches>, mut global_config: GlobalCon
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(true) = server_config.run_wallet_listener {
|
if let Some(true) = server_config.run_wallet_listener {
|
||||||
|
let use_db = server_config.use_db_wallet == Some(true);
|
||||||
let mut wallet_config = global_config.members.as_ref().unwrap().wallet.clone();
|
let mut wallet_config = global_config.members.as_ref().unwrap().wallet.clone();
|
||||||
if let Err(_) = wallet::WalletSeed::from_file(&wallet_config) {
|
init_wallet_seed(wallet_config.clone());
|
||||||
wallet::WalletSeed::init_file(&wallet_config)
|
|
||||||
.expect("Failed to create wallet seed file.");
|
|
||||||
};
|
|
||||||
|
|
||||||
let _ = thread::Builder::new()
|
let _ = thread::Builder::new()
|
||||||
.name("wallet_listener".to_string())
|
.name("wallet_listener".to_string())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
let wallet: FileWallet<keychain::ExtKeychain> =
|
let wallet = instantiate_wallet(wallet_config.clone(), "", use_db);
|
||||||
FileWallet::new(wallet_config.clone(), "").unwrap_or_else(|e| {
|
|
||||||
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
|
||||||
});
|
|
||||||
wallet::controller::foreign_listener(wallet, &wallet_config.api_listen_addr())
|
wallet::controller::foreign_listener(wallet, &wallet_config.api_listen_addr())
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -460,19 +457,14 @@ fn server_command(server_args: Option<&ArgMatches>, mut global_config: GlobalCon
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(true) = server_config.run_wallet_owner_api {
|
if let Some(true) = server_config.run_wallet_owner_api {
|
||||||
|
let use_db = server_config.use_db_wallet == Some(true);
|
||||||
let mut wallet_config = global_config.members.unwrap().wallet;
|
let mut wallet_config = global_config.members.unwrap().wallet;
|
||||||
if let Err(_) = wallet::WalletSeed::from_file(&wallet_config) {
|
init_wallet_seed(wallet_config.clone());
|
||||||
wallet::WalletSeed::init_file(&wallet_config)
|
|
||||||
.expect("Failed to create wallet seed file.");
|
|
||||||
};
|
|
||||||
|
|
||||||
let _ = thread::Builder::new()
|
let _ = thread::Builder::new()
|
||||||
.name("wallet_owner_listener".to_string())
|
.name("wallet_owner_listener".to_string())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
let wallet: FileWallet<ExtKeychain> = FileWallet::new(wallet_config.clone(), "")
|
let wallet = instantiate_wallet(wallet_config.clone(), "", use_db);
|
||||||
.unwrap_or_else(|e| {
|
|
||||||
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
|
||||||
});
|
|
||||||
wallet::controller::owner_listener(wallet, "127.0.0.1:13420").unwrap_or_else(|e| {
|
wallet::controller::owner_listener(wallet, "127.0.0.1:13420").unwrap_or_else(|e| {
|
||||||
panic!(
|
panic!(
|
||||||
"Error creating wallet api listener: {:?} Config: {:?}",
|
"Error creating wallet api listener: {:?} Config: {:?}",
|
||||||
|
@ -551,6 +543,34 @@ fn client_command(client_args: &ArgMatches, global_config: GlobalConfig) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_wallet_seed(wallet_config: WalletConfig) {
|
||||||
|
if let Err(_) = wallet::WalletSeed::from_file(&wallet_config) {
|
||||||
|
wallet::WalletSeed::init_file(&wallet_config).expect("Failed to create wallet seed file.");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instantiate_wallet(
|
||||||
|
wallet_config: WalletConfig,
|
||||||
|
passphrase: &str,
|
||||||
|
use_db: bool,
|
||||||
|
) -> Box<WalletInst<keychain::ExtKeychain>> {
|
||||||
|
if use_db {
|
||||||
|
let db_wallet = LMDBBackend::new(wallet_config.clone(), "").unwrap_or_else(|e| {
|
||||||
|
panic!(
|
||||||
|
"Error creating DB wallet: {} Config: {:?}",
|
||||||
|
e, wallet_config
|
||||||
|
);
|
||||||
|
});
|
||||||
|
info!(LOGGER, "Using LMDB Backend for wallet");
|
||||||
|
Box::new(db_wallet)
|
||||||
|
} else {
|
||||||
|
let file_wallet = FileWallet::new(wallet_config.clone(), passphrase)
|
||||||
|
.unwrap_or_else(|e| panic!("Error creating wallet: {} Config: {:?}", e, wallet_config));
|
||||||
|
info!(LOGGER, "Using File Backend for wallet");
|
||||||
|
Box::new(file_wallet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) {
|
fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) {
|
||||||
// just get defaults from the global config
|
// just get defaults from the global config
|
||||||
let mut wallet_config = global_config.members.unwrap().wallet;
|
let mut wallet_config = global_config.members.unwrap().wallet;
|
||||||
|
@ -574,8 +594,26 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) {
|
||||||
|
|
||||||
// Derive the keychain based on seed from seed file and specified passphrase.
|
// Derive the keychain based on seed from seed file and specified passphrase.
|
||||||
// Generate the initial wallet seed if we are running "wallet init".
|
// Generate the initial wallet seed if we are running "wallet init".
|
||||||
if let ("init", Some(_)) = wallet_args.subcommand() {
|
if let ("init", Some(init_args)) = wallet_args.subcommand() {
|
||||||
|
let mut use_db = false;
|
||||||
|
if init_args.is_present("db") {
|
||||||
|
info!(LOGGER, "Use db");
|
||||||
|
use_db = true;
|
||||||
|
}
|
||||||
wallet::WalletSeed::init_file(&wallet_config).expect("Failed to init wallet seed file.");
|
wallet::WalletSeed::init_file(&wallet_config).expect("Failed to init wallet seed file.");
|
||||||
|
info!(LOGGER, "Wallet seed file created");
|
||||||
|
if use_db {
|
||||||
|
let _: LMDBBackend<keychain::ExtKeychain> = LMDBBackend::new(wallet_config.clone(), "")
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
panic!(
|
||||||
|
"Error creating DB wallet: {} Config: {:?}",
|
||||||
|
e, wallet_config
|
||||||
|
);
|
||||||
|
});
|
||||||
|
info!(LOGGER, "Wallet database backend created");
|
||||||
|
}
|
||||||
|
// give logging thread a moment to catch up
|
||||||
|
thread::sleep(Duration::from_millis(200));
|
||||||
// we are done here with creating the wallet, so just return
|
// we are done here with creating the wallet, so just return
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -584,12 +622,12 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) {
|
||||||
.value_of("pass")
|
.value_of("pass")
|
||||||
.expect("Failed to read passphrase.");
|
.expect("Failed to read passphrase.");
|
||||||
|
|
||||||
|
// use database if one exists, otherwise use file
|
||||||
|
let use_db = wallet_db_exists(wallet_config.clone());
|
||||||
|
|
||||||
// Handle listener startup commands
|
// Handle listener startup commands
|
||||||
{
|
{
|
||||||
let wallet: FileWallet<keychain::ExtKeychain> =
|
let wallet = instantiate_wallet(wallet_config.clone(), passphrase, use_db);
|
||||||
FileWallet::new(wallet_config.clone(), passphrase).unwrap_or_else(|e| {
|
|
||||||
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
|
||||||
});
|
|
||||||
match wallet_args.subcommand() {
|
match wallet_args.subcommand() {
|
||||||
("listen", Some(listen_args)) => {
|
("listen", Some(listen_args)) => {
|
||||||
if let Some(port) = listen_args.value_of("port") {
|
if let Some(port) = listen_args.value_of("port") {
|
||||||
|
@ -617,11 +655,8 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) {
|
||||||
|
|
||||||
// Handle single-use (command line) owner commands
|
// Handle single-use (command line) owner commands
|
||||||
{
|
{
|
||||||
let mut wallet: FileWallet<keychain::ExtKeychain> =
|
let wallet = instantiate_wallet(wallet_config.clone(), passphrase, use_db);
|
||||||
FileWallet::new(wallet_config.clone(), passphrase).unwrap_or_else(|e| {
|
let _res = wallet::controller::owner_single_use(wallet, |api| {
|
||||||
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
|
||||||
});
|
|
||||||
let _res = wallet::controller::owner_single_use(&mut wallet, |api| {
|
|
||||||
match wallet_args.subcommand() {
|
match wallet_args.subcommand() {
|
||||||
("send", Some(send_args)) => {
|
("send", Some(send_args)) => {
|
||||||
let amount = send_args
|
let amount = send_args
|
||||||
|
|
|
@ -14,16 +14,20 @@
|
||||||
|
|
||||||
//! Main Menu definition
|
//! Main Menu definition
|
||||||
|
|
||||||
use cursive::Cursive;
|
|
||||||
use cursive::align::HAlign;
|
use cursive::align::HAlign;
|
||||||
use cursive::direction::Orientation;
|
use cursive::direction::Orientation;
|
||||||
use cursive::event::{EventResult, Key};
|
use cursive::event::{EventResult, Key};
|
||||||
use cursive::view::Identifiable;
|
use cursive::view::Identifiable;
|
||||||
use cursive::view::View;
|
use cursive::view::View;
|
||||||
use cursive::views::{BoxView, LinearLayout, OnEventView, SelectView, StackView, TextView, ViewRef};
|
use cursive::views::{
|
||||||
|
BoxView, LinearLayout, OnEventView, SelectView, StackView, TextView, ViewRef,
|
||||||
|
};
|
||||||
|
use cursive::Cursive;
|
||||||
|
|
||||||
use tui::constants::{MAIN_MENU, ROOT_STACK, SUBMENU_MINING_BUTTON, VIEW_BASIC_STATUS, VIEW_MINING,
|
use tui::constants::{
|
||||||
VIEW_PEER_SYNC, VIEW_VERSION};
|
MAIN_MENU, ROOT_STACK, SUBMENU_MINING_BUTTON, VIEW_BASIC_STATUS, VIEW_MINING, VIEW_PEER_SYNC,
|
||||||
|
VIEW_VERSION,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn create() -> Box<View> {
|
pub fn create() -> Box<View> {
|
||||||
let mut main_menu = SelectView::new().h_align(HAlign::Left).with_id(MAIN_MENU);
|
let mut main_menu = SelectView::new().h_align(HAlign::Left).with_id(MAIN_MENU);
|
||||||
|
|
|
@ -16,18 +16,20 @@
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use cursive::Cursive;
|
|
||||||
use cursive::direction::Orientation;
|
use cursive::direction::Orientation;
|
||||||
use cursive::event::Key;
|
use cursive::event::Key;
|
||||||
use cursive::traits::{Boxable, Identifiable};
|
use cursive::traits::{Boxable, Identifiable};
|
||||||
use cursive::view::View;
|
use cursive::view::View;
|
||||||
use cursive::views::{BoxView, Button, Dialog, LinearLayout, OnEventView, Panel, StackView,
|
use cursive::views::{
|
||||||
TextView};
|
BoxView, Button, Dialog, LinearLayout, OnEventView, Panel, StackView, TextView,
|
||||||
|
};
|
||||||
|
use cursive::Cursive;
|
||||||
use std::time;
|
use std::time;
|
||||||
use tui::chrono::prelude::{DateTime, NaiveDateTime, Utc};
|
use tui::chrono::prelude::{DateTime, NaiveDateTime, Utc};
|
||||||
|
|
||||||
use tui::constants::{MAIN_MENU, SUBMENU_MINING_BUTTON, TABLE_MINING_DIFF_STATUS,
|
use tui::constants::{
|
||||||
TABLE_MINING_STATUS, VIEW_MINING};
|
MAIN_MENU, SUBMENU_MINING_BUTTON, TABLE_MINING_DIFF_STATUS, TABLE_MINING_STATUS, VIEW_MINING,
|
||||||
|
};
|
||||||
use tui::types::TUIStatusListener;
|
use tui::types::TUIStatusListener;
|
||||||
|
|
||||||
use servers::{DiffBlock, ServerStats, WorkerStats};
|
use servers::{DiffBlock, ServerStats, WorkerStats};
|
||||||
|
|
|
@ -18,11 +18,11 @@ use std::cmp::Ordering;
|
||||||
|
|
||||||
use servers::{PeerStats, ServerStats};
|
use servers::{PeerStats, ServerStats};
|
||||||
|
|
||||||
use cursive::Cursive;
|
|
||||||
use cursive::direction::Orientation;
|
use cursive::direction::Orientation;
|
||||||
use cursive::traits::{Boxable, Identifiable};
|
use cursive::traits::{Boxable, Identifiable};
|
||||||
use cursive::view::View;
|
use cursive::view::View;
|
||||||
use cursive::views::{BoxView, Dialog, LinearLayout, TextView};
|
use cursive::views::{BoxView, Dialog, LinearLayout, TextView};
|
||||||
|
use cursive::Cursive;
|
||||||
|
|
||||||
use tui::constants::{TABLE_PEER_STATUS, VIEW_PEER_SYNC};
|
use tui::constants::{TABLE_PEER_STATUS, VIEW_PEER_SYNC};
|
||||||
use tui::table::{TableView, TableViewItem};
|
use tui::table::{TableView, TableViewItem};
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
|
|
||||||
//! Basic status view definition
|
//! Basic status view definition
|
||||||
|
|
||||||
use cursive::Cursive;
|
|
||||||
use cursive::direction::Orientation;
|
use cursive::direction::Orientation;
|
||||||
use cursive::traits::Identifiable;
|
use cursive::traits::Identifiable;
|
||||||
use cursive::view::View;
|
use cursive::view::View;
|
||||||
use cursive::views::{BoxView, LinearLayout, TextView};
|
use cursive::views::{BoxView, LinearLayout, TextView};
|
||||||
|
use cursive::Cursive;
|
||||||
|
|
||||||
use tui::constants::VIEW_BASIC_STATUS;
|
use tui::constants::VIEW_BASIC_STATUS;
|
||||||
use tui::types::TUIStatusListener;
|
use tui::types::TUIStatusListener;
|
||||||
|
|
|
@ -54,7 +54,6 @@ use std::hash::Hash;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
// External Dependencies ------------------------------------------------------
|
// External Dependencies ------------------------------------------------------
|
||||||
use cursive::With;
|
|
||||||
use cursive::align::HAlign;
|
use cursive::align::HAlign;
|
||||||
use cursive::direction::Direction;
|
use cursive::direction::Direction;
|
||||||
use cursive::event::{Callback, Event, EventResult, Key};
|
use cursive::event::{Callback, Event, EventResult, Key};
|
||||||
|
@ -62,6 +61,7 @@ use cursive::theme::ColorStyle;
|
||||||
use cursive::theme::PaletteColor::{Highlight, HighlightInactive, Primary};
|
use cursive::theme::PaletteColor::{Highlight, HighlightInactive, Primary};
|
||||||
use cursive::vec::Vec2;
|
use cursive::vec::Vec2;
|
||||||
use cursive::view::{ScrollBase, View};
|
use cursive::view::{ScrollBase, View};
|
||||||
|
use cursive::With;
|
||||||
use cursive::{Cursive, Printer};
|
use cursive::{Cursive, Printer};
|
||||||
|
|
||||||
/// A trait for displaying and sorting items inside a
|
/// A trait for displaying and sorting items inside a
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
//! Types specific to the UI module
|
//! Types specific to the UI module
|
||||||
|
|
||||||
use cursive::Cursive;
|
|
||||||
use cursive::view::View;
|
use cursive::view::View;
|
||||||
|
use cursive::Cursive;
|
||||||
use servers::ServerStats;
|
use servers::ServerStats;
|
||||||
|
|
||||||
/// Main message struct to communicate between the UI and
|
/// Main message struct to communicate between the UI and
|
||||||
|
|
|
@ -19,15 +19,17 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{mpsc, Arc};
|
use std::sync::{mpsc, Arc};
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
use cursive::Cursive;
|
|
||||||
use cursive::direction::Orientation;
|
use cursive::direction::Orientation;
|
||||||
use cursive::theme::BaseColor::{Black, Blue, Cyan, White};
|
use cursive::theme::BaseColor::{Black, Blue, Cyan, White};
|
||||||
use cursive::theme::Color::Dark;
|
use cursive::theme::Color::Dark;
|
||||||
use cursive::theme::PaletteColor::{Background, Highlight, HighlightInactive, Primary, Shadow, View};
|
use cursive::theme::PaletteColor::{
|
||||||
|
Background, Highlight, HighlightInactive, Primary, Shadow, View,
|
||||||
|
};
|
||||||
use cursive::theme::{BaseColor, BorderStyle, Color, Theme};
|
use cursive::theme::{BaseColor, BorderStyle, Color, Theme};
|
||||||
use cursive::traits::Identifiable;
|
use cursive::traits::Identifiable;
|
||||||
use cursive::utils::markup::StyledString;
|
use cursive::utils::markup::StyledString;
|
||||||
use cursive::views::{LinearLayout, Panel, StackView, TextView, ViewBox};
|
use cursive::views::{LinearLayout, Panel, StackView, TextView, ViewBox};
|
||||||
|
use cursive::Cursive;
|
||||||
|
|
||||||
use servers::Server;
|
use servers::Server;
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
|
|
||||||
//! Version and build info
|
//! Version and build info
|
||||||
|
|
||||||
use cursive::Cursive;
|
|
||||||
use cursive::direction::Orientation;
|
use cursive::direction::Orientation;
|
||||||
use cursive::traits::Identifiable;
|
use cursive::traits::Identifiable;
|
||||||
use cursive::view::View;
|
use cursive::view::View;
|
||||||
use cursive::views::{BoxView, LinearLayout, TextView};
|
use cursive::views::{BoxView, LinearLayout, TextView};
|
||||||
|
use cursive::Cursive;
|
||||||
|
|
||||||
use tui::constants::VIEW_VERSION;
|
use tui::constants::VIEW_VERSION;
|
||||||
use tui::types::TUIStatusListener;
|
use tui::types::TUIStatusListener;
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use core::core::{self, amount_to_hr_string};
|
use core::core::{self, amount_to_hr_string};
|
||||||
use libwallet::Error;
|
|
||||||
use libwallet::types::{OutputData, WalletInfo};
|
use libwallet::types::{OutputData, WalletInfo};
|
||||||
|
use libwallet::Error;
|
||||||
use prettytable;
|
use prettytable;
|
||||||
use std::io::prelude::Write;
|
use std::io::prelude::Write;
|
||||||
use term;
|
use term;
|
||||||
|
|
|
@ -104,7 +104,19 @@ impl Fail for Error {
|
||||||
|
|
||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
Display::fmt(&self.inner, f)
|
let cause = match self.cause() {
|
||||||
|
Some(c) => format!("{}", c),
|
||||||
|
None => String::from("Unknown"),
|
||||||
|
};
|
||||||
|
let backtrace = match self.backtrace() {
|
||||||
|
Some(b) => format!("{}", b),
|
||||||
|
None => String::from("Unknown"),
|
||||||
|
};
|
||||||
|
let output = format!(
|
||||||
|
"{} \n Cause: {} \n Backtrace: {}",
|
||||||
|
self.inner, cause, backtrace
|
||||||
|
);
|
||||||
|
Display::fmt(&output, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,14 +19,14 @@ use std::path::{Path, MAIN_SEPARATOR};
|
||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use tokio_core::reactor;
|
use tokio_core::reactor;
|
||||||
use tokio_retry::Retry;
|
|
||||||
use tokio_retry::strategy::FibonacciBackoff;
|
use tokio_retry::strategy::FibonacciBackoff;
|
||||||
|
use tokio_retry::Retry;
|
||||||
|
|
||||||
use failure::ResultExt;
|
use failure::ResultExt;
|
||||||
|
|
||||||
use keychain::{self, Identifier, Keychain};
|
use keychain::{self, Identifier, Keychain};
|
||||||
use util::LOGGER;
|
|
||||||
use util::secp::pedersen;
|
use util::secp::pedersen;
|
||||||
|
use util::LOGGER;
|
||||||
|
|
||||||
use error::{Error, ErrorKind};
|
use error::{Error, ErrorKind};
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ use libtx::slate::Slate;
|
||||||
use libwallet;
|
use libwallet;
|
||||||
|
|
||||||
use libwallet::types::{
|
use libwallet::types::{
|
||||||
BlockFees, CbData, OutputData, TxWrapper, WalletBackend,
|
BlockFees, CbData, OutputData, TxWrapper, WalletBackend, WalletClient, WalletDetails,
|
||||||
WalletClient, WalletDetails, WalletOutputBatch,
|
WalletOutputBatch,
|
||||||
};
|
};
|
||||||
|
|
||||||
use types::{WalletConfig, WalletSeed};
|
use types::{WalletConfig, WalletSeed};
|
||||||
|
|
|
@ -60,5 +60,6 @@ pub use client::create_coinbase;
|
||||||
pub use error::{Error, ErrorKind};
|
pub use error::{Error, ErrorKind};
|
||||||
pub use file_wallet::FileWallet;
|
pub use file_wallet::FileWallet;
|
||||||
pub use libwallet::controller;
|
pub use libwallet::controller;
|
||||||
pub use libwallet::types::{BlockFees, CbData, WalletInfo};
|
pub use libwallet::types::{BlockFees, CbData, WalletInfo, WalletInst};
|
||||||
|
pub use lmdb_wallet::{wallet_db_exists, LMDBBackend};
|
||||||
pub use types::{WalletConfig, WalletSeed};
|
pub use types::{WalletConfig, WalletSeed};
|
||||||
|
|
|
@ -47,11 +47,7 @@ pub type Append<K> = for<'a> Fn(&'a mut Context<K>, (Transaction, TxKernel, Blin
|
||||||
|
|
||||||
/// Adds an input with the provided value and blinding key to the transaction
|
/// Adds an input with the provided value and blinding key to the transaction
|
||||||
/// being built.
|
/// being built.
|
||||||
fn build_input<K>(
|
fn build_input<K>(value: u64, features: OutputFeatures, key_id: Identifier) -> Box<Append<K>>
|
||||||
value: u64,
|
|
||||||
features: OutputFeatures,
|
|
||||||
key_id: Identifier,
|
|
||||||
) -> Box<Append<K>>
|
|
||||||
where
|
where
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
|
@ -78,10 +74,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a coinbase input spending a coinbase output.
|
/// Adds a coinbase input spending a coinbase output.
|
||||||
pub fn coinbase_input<K>(
|
pub fn coinbase_input<K>(value: u64, key_id: Identifier) -> Box<Append<K>>
|
||||||
value: u64,
|
|
||||||
key_id: Identifier,
|
|
||||||
) -> Box<Append<K>>
|
|
||||||
where
|
where
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,8 +23,8 @@ use keychain::{BlindSum, BlindingFactor, Keychain};
|
||||||
use libtx::error::{Error, ErrorKind};
|
use libtx::error::{Error, ErrorKind};
|
||||||
use libtx::{aggsig, build, tx_fee};
|
use libtx::{aggsig, build, tx_fee};
|
||||||
|
|
||||||
use util::secp::Signature;
|
|
||||||
use util::secp::key::{PublicKey, SecretKey};
|
use util::secp::key::{PublicKey, SecretKey};
|
||||||
|
use util::secp::Signature;
|
||||||
use util::{secp, LOGGER};
|
use util::{secp, LOGGER};
|
||||||
|
|
||||||
/// Public data for each participant in the slate
|
/// Public data for each participant in the slate
|
||||||
|
@ -261,11 +261,7 @@ impl Slate {
|
||||||
// double check the fee amount included in the partial tx
|
// double check the fee amount included in the partial tx
|
||||||
// we don't necessarily want to just trust the sender
|
// we don't necessarily want to just trust the sender
|
||||||
// we could just overwrite the fee here (but we won't) due to the sig
|
// we could just overwrite the fee here (but we won't) due to the sig
|
||||||
let fee = tx_fee(
|
let fee = tx_fee(self.tx.inputs.len(), self.tx.outputs.len(), None);
|
||||||
self.tx.inputs.len(),
|
|
||||||
self.tx.outputs.len(),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
if fee > self.tx.fee() {
|
if fee > self.tx.fee() {
|
||||||
return Err(ErrorKind::Fee(
|
return Err(ErrorKind::Fee(
|
||||||
format!("Fee Dispute Error: {}, {}", self.tx.fee(), fee,).to_string(),
|
format!("Fee Dispute Error: {}, {}", self.tx.fee(), fee,).to_string(),
|
||||||
|
|
|
@ -22,32 +22,33 @@ use std::marker::PhantomData;
|
||||||
use core::ser;
|
use core::ser;
|
||||||
use keychain::Keychain;
|
use keychain::Keychain;
|
||||||
use libtx::slate::Slate;
|
use libtx::slate::Slate;
|
||||||
use libwallet::Error;
|
|
||||||
use libwallet::internal::{tx, updater};
|
use libwallet::internal::{tx, updater};
|
||||||
use libwallet::types::{BlockFees, CbData, OutputData, TxWrapper, WalletBackend, WalletClient,
|
use libwallet::types::{
|
||||||
WalletInfo};
|
BlockFees, CbData, OutputData, TxWrapper, WalletBackend, WalletClient, WalletInfo,
|
||||||
|
};
|
||||||
|
use libwallet::Error;
|
||||||
use util::{self, LOGGER};
|
use util::{self, LOGGER};
|
||||||
|
|
||||||
/// Wrapper around internal API functions, containing a reference to
|
/// Wrapper around internal API functions, containing a reference to
|
||||||
/// the wallet/keychain that they're acting upon
|
/// the wallet/keychain that they're acting upon
|
||||||
pub struct APIOwner<'a, W, K>
|
pub struct APIOwner<'a, W: ?Sized, K>
|
||||||
where
|
where
|
||||||
W: 'a + WalletBackend<K> + WalletClient,
|
W: 'a + WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// Wallet, contains its keychain (TODO: Split these up into 2 traits
|
/// Wallet, contains its keychain (TODO: Split these up into 2 traits
|
||||||
/// perhaps)
|
/// perhaps)
|
||||||
pub wallet: &'a mut W,
|
pub wallet: &'a mut Box<W>,
|
||||||
phantom: PhantomData<K>,
|
phantom: PhantomData<K>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W, K> APIOwner<'a, W, K>
|
impl<'a, W: ?Sized, K> APIOwner<'a, W, K>
|
||||||
where
|
where
|
||||||
W: 'a + WalletBackend<K> + WalletClient,
|
W: 'a + WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// Create new API instance
|
/// Create new API instance
|
||||||
pub fn new(wallet_in: &'a mut W) -> APIOwner<'a, W, K> {
|
pub fn new(wallet_in: &'a mut Box<W>) -> APIOwner<'a, W, K> {
|
||||||
APIOwner {
|
APIOwner {
|
||||||
wallet: wallet_in,
|
wallet: wallet_in,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
@ -67,7 +68,7 @@ where
|
||||||
}
|
}
|
||||||
Ok((
|
Ok((
|
||||||
validated,
|
validated,
|
||||||
updater::retrieve_outputs(self.wallet, include_spent)?,
|
updater::retrieve_outputs(&mut **self.wallet, include_spent)?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ where
|
||||||
if refresh_from_node {
|
if refresh_from_node {
|
||||||
validated = self.update_outputs();
|
validated = self.update_outputs();
|
||||||
}
|
}
|
||||||
let wallet_info = updater::retrieve_info(self.wallet)?;
|
let wallet_info = updater::retrieve_info(&mut **self.wallet)?;
|
||||||
Ok((validated, wallet_info))
|
Ok((validated, wallet_info))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ where
|
||||||
fluff: bool,
|
fluff: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let (slate, context, lock_fn) = tx::create_send_tx(
|
let (slate, context, lock_fn) = tx::create_send_tx(
|
||||||
self.wallet,
|
&mut **self.wallet,
|
||||||
amount,
|
amount,
|
||||||
minimum_confirmations,
|
minimum_confirmations,
|
||||||
max_outputs,
|
max_outputs,
|
||||||
|
@ -114,7 +115,7 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
tx::complete_tx(self.wallet, &mut slate, &context)?;
|
tx::complete_tx(&mut **self.wallet, &mut slate, &context)?;
|
||||||
|
|
||||||
// All good here, so let's post it
|
// All good here, so let's post it
|
||||||
let tx_hex = util::to_hex(ser::ser_vec(&slate.tx).unwrap());
|
let tx_hex = util::to_hex(ser::ser_vec(&slate.tx).unwrap());
|
||||||
|
@ -132,7 +133,12 @@ where
|
||||||
minimum_confirmations: u64,
|
minimum_confirmations: u64,
|
||||||
max_outputs: usize,
|
max_outputs: usize,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let tx_burn = tx::issue_burn_tx(self.wallet, amount, minimum_confirmations, max_outputs)?;
|
let tx_burn = tx::issue_burn_tx(
|
||||||
|
&mut **self.wallet,
|
||||||
|
amount,
|
||||||
|
minimum_confirmations,
|
||||||
|
max_outputs,
|
||||||
|
)?;
|
||||||
let tx_hex = util::to_hex(ser::ser_vec(&tx_burn).unwrap());
|
let tx_hex = util::to_hex(ser::ser_vec(&tx_burn).unwrap());
|
||||||
self.wallet.post_tx(&TxWrapper { tx_hex: tx_hex }, false)?;
|
self.wallet.post_tx(&TxWrapper { tx_hex: tx_hex }, false)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -160,7 +166,7 @@ where
|
||||||
|
|
||||||
/// Attempt to update outputs in wallet, return whether it was successful
|
/// Attempt to update outputs in wallet, return whether it was successful
|
||||||
fn update_outputs(&mut self) -> bool {
|
fn update_outputs(&mut self) -> bool {
|
||||||
match updater::refresh_outputs(self.wallet) {
|
match updater::refresh_outputs(&mut **self.wallet) {
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
}
|
}
|
||||||
|
@ -169,24 +175,24 @@ where
|
||||||
|
|
||||||
/// Wrapper around external API functions, intended to communicate
|
/// Wrapper around external API functions, intended to communicate
|
||||||
/// with other parties
|
/// with other parties
|
||||||
pub struct APIForeign<'a, W, K>
|
pub struct APIForeign<'a, W: ?Sized, K>
|
||||||
where
|
where
|
||||||
W: 'a + WalletBackend<K> + WalletClient,
|
W: WalletBackend<K> + WalletClient + 'a,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// Wallet, contains its keychain (TODO: Split these up into 2 traits
|
/// Wallet, contains its keychain (TODO: Split these up into 2 traits
|
||||||
/// perhaps)
|
/// perhaps)
|
||||||
pub wallet: &'a mut W,
|
pub wallet: &'a mut Box<W>,
|
||||||
phantom: PhantomData<K>,
|
phantom: PhantomData<K>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W, K> APIForeign<'a, W, K>
|
impl<'a, W: ?Sized, K> APIForeign<'a, W, K>
|
||||||
where
|
where
|
||||||
W: 'a + WalletBackend<K> + WalletClient,
|
W: WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// Create new API instance
|
/// Create new API instance
|
||||||
pub fn new(wallet_in: &'a mut W) -> APIForeign<'a, W, K> {
|
pub fn new(wallet_in: &'a mut Box<W>) -> APIForeign<W, K> {
|
||||||
APIForeign {
|
APIForeign {
|
||||||
wallet: wallet_in,
|
wallet: wallet_in,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
@ -195,11 +201,11 @@ where
|
||||||
|
|
||||||
/// Build a new (potential) coinbase transaction in the wallet
|
/// Build a new (potential) coinbase transaction in the wallet
|
||||||
pub fn build_coinbase(&mut self, block_fees: &BlockFees) -> Result<CbData, Error> {
|
pub fn build_coinbase(&mut self, block_fees: &BlockFees) -> Result<CbData, Error> {
|
||||||
updater::build_coinbase(self.wallet, block_fees)
|
updater::build_coinbase(&mut **self.wallet, block_fees)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive a transaction from a sender
|
/// Receive a transaction from a sender
|
||||||
pub fn receive_tx(&mut self, slate: &mut Slate) -> Result<(), Error> {
|
pub fn receive_tx(&mut self, slate: &mut Slate) -> Result<(), Error> {
|
||||||
tx::receive_tx(self.wallet, slate)
|
tx::receive_tx(&mut **self.wallet, slate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,29 +31,31 @@ use failure::Fail;
|
||||||
use keychain::Keychain;
|
use keychain::Keychain;
|
||||||
use libtx::slate::Slate;
|
use libtx::slate::Slate;
|
||||||
use libwallet::api::{APIForeign, APIOwner};
|
use libwallet::api::{APIForeign, APIOwner};
|
||||||
use libwallet::types::{BlockFees, CbData, OutputData, SendTXArgs, WalletBackend, WalletClient,
|
use libwallet::types::{
|
||||||
WalletInfo};
|
BlockFees, CbData, OutputData, SendTXArgs, WalletBackend, WalletClient, WalletInfo, WalletInst,
|
||||||
|
};
|
||||||
use libwallet::{Error, ErrorKind};
|
use libwallet::{Error, ErrorKind};
|
||||||
|
|
||||||
use util::LOGGER;
|
use util::LOGGER;
|
||||||
|
|
||||||
/// Instantiate wallet Owner API for a single-use (command line) call
|
/// Instantiate wallet Owner API for a single-use (command line) call
|
||||||
/// Return a function containing a loaded API context to call
|
/// Return a function containing a loaded API context to call
|
||||||
pub fn owner_single_use<F, T, K>(wallet: &mut T, f: F) -> Result<(), Error>
|
pub fn owner_single_use<F, T: ?Sized, K>(wallet: Box<T>, f: F) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletBackend<K> + WalletClient,
|
||||||
F: FnOnce(&mut APIOwner<T, K>) -> Result<(), Error>,
|
F: FnOnce(&mut APIOwner<T, K>) -> Result<(), Error>,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
wallet.open_with_credentials()?;
|
let mut w = wallet;
|
||||||
f(&mut APIOwner::new(wallet))?;
|
w.open_with_credentials()?;
|
||||||
wallet.close()?;
|
f(&mut APIOwner::new(&mut w))?;
|
||||||
|
w.close()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instantiate wallet Foreign API for a single-use (command line) call
|
/// Instantiate wallet Foreign API for a single-use (command line) call
|
||||||
/// Return a function containing a loaded API context to call
|
/// Return a function containing a loaded API context to call
|
||||||
pub fn foreign_single_use<F, T, K>(wallet: &mut T, f: F) -> Result<(), Error>
|
pub fn foreign_single_use<F, T: ?Sized, K>(wallet: &mut Box<T>, f: F) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletBackend<K> + WalletClient,
|
||||||
F: FnOnce(&mut APIForeign<T, K>) -> Result<(), Error>,
|
F: FnOnce(&mut APIForeign<T, K>) -> Result<(), Error>,
|
||||||
|
@ -67,9 +69,9 @@ where
|
||||||
|
|
||||||
/// Listener version, providing same API but listening for requests on a
|
/// Listener version, providing same API but listening for requests on a
|
||||||
/// port and wrapping the calls
|
/// port and wrapping the calls
|
||||||
pub fn owner_listener<T, K>(wallet: T, addr: &str) -> Result<(), Error>
|
pub fn owner_listener<T: ?Sized, K>(wallet: Box<T>, addr: &str) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletInst<K>,
|
||||||
OwnerAPIGetHandler<T, K>: Handler,
|
OwnerAPIGetHandler<T, K>: Handler,
|
||||||
OwnerAPIPostHandler<T, K>: Handler,
|
OwnerAPIPostHandler<T, K>: Handler,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
|
@ -99,9 +101,9 @@ where
|
||||||
|
|
||||||
/// Listener version, providing same API but listening for requests on a
|
/// Listener version, providing same API but listening for requests on a
|
||||||
/// port and wrapping the calls
|
/// port and wrapping the calls
|
||||||
pub fn foreign_listener<T, K>(wallet: T, addr: &str) -> Result<(), Error>
|
pub fn foreign_listener<T: ?Sized, K>(wallet: Box<T>, addr: &str) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletInst<K>,
|
||||||
ForeignAPIHandler<T, K>: Handler,
|
ForeignAPIHandler<T, K>: Handler,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
|
@ -124,23 +126,23 @@ where
|
||||||
}
|
}
|
||||||
/// API Handler/Wrapper for owner functions
|
/// API Handler/Wrapper for owner functions
|
||||||
|
|
||||||
pub struct OwnerAPIGetHandler<T, K>
|
pub struct OwnerAPIGetHandler<T: ?Sized, K>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K>,
|
T: WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// Wallet instance
|
/// Wallet instance
|
||||||
pub wallet: Arc<Mutex<T>>,
|
pub wallet: Arc<Mutex<Box<T>>>,
|
||||||
phantom: PhantomData<K>,
|
phantom: PhantomData<K>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, K> OwnerAPIGetHandler<T, K>
|
impl<T: ?Sized, K> OwnerAPIGetHandler<T, K>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// Create a new owner API handler for GET methods
|
/// Create a new owner API handler for GET methods
|
||||||
pub fn new(wallet: Arc<Mutex<T>>) -> OwnerAPIGetHandler<T, K> {
|
pub fn new(wallet: Arc<Mutex<Box<T>>>) -> OwnerAPIGetHandler<T, K> {
|
||||||
OwnerAPIGetHandler {
|
OwnerAPIGetHandler {
|
||||||
wallet,
|
wallet,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
@ -201,7 +203,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, K> Handler for OwnerAPIGetHandler<T, K>
|
impl<T: ?Sized, K> Handler for OwnerAPIGetHandler<T, K>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
||||||
K: Keychain + 'static,
|
K: Keychain + 'static,
|
||||||
|
@ -215,7 +217,8 @@ where
|
||||||
error!(LOGGER, "Error opening wallet: {:?}", e);
|
error!(LOGGER, "Error opening wallet: {:?}", e);
|
||||||
IronError::new(Fail::compat(e), status::BadRequest)
|
IronError::new(Fail::compat(e), status::BadRequest)
|
||||||
})?;
|
})?;
|
||||||
let mut api = APIOwner::new(&mut *wallet);
|
let mut w = wallet;
|
||||||
|
let mut api = APIOwner::new(&mut w);
|
||||||
let mut resp_json = self.handle_request(req, &mut api);
|
let mut resp_json = self.handle_request(req, &mut api);
|
||||||
if !resp_json.is_err() {
|
if !resp_json.is_err() {
|
||||||
resp_json
|
resp_json
|
||||||
|
@ -232,23 +235,23 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles all owner API POST requests
|
/// Handles all owner API POST requests
|
||||||
pub struct OwnerAPIPostHandler<T, K>
|
pub struct OwnerAPIPostHandler<T: ?Sized, K>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K>,
|
T: WalletBackend<K>,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// Wallet instance
|
/// Wallet instance
|
||||||
pub wallet: Arc<Mutex<T>>,
|
pub wallet: Arc<Mutex<Box<T>>>,
|
||||||
phantom: PhantomData<K>,
|
phantom: PhantomData<K>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, K> OwnerAPIPostHandler<T, K>
|
impl<T: ?Sized, K> OwnerAPIPostHandler<T, K>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// New POST handler
|
/// New POST handler
|
||||||
pub fn new(wallet: Arc<Mutex<T>>) -> OwnerAPIPostHandler<T, K> {
|
pub fn new(wallet: Arc<Mutex<Box<T>>>) -> OwnerAPIPostHandler<T, K> {
|
||||||
OwnerAPIPostHandler {
|
OwnerAPIPostHandler {
|
||||||
wallet,
|
wallet,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
@ -320,7 +323,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, K> Handler for OwnerAPIPostHandler<T, K>
|
impl<T: ?Sized, K> Handler for OwnerAPIPostHandler<T, K>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
||||||
K: Keychain + 'static,
|
K: Keychain + 'static,
|
||||||
|
@ -329,12 +332,15 @@ where
|
||||||
// every request should open with stored credentials,
|
// every request should open with stored credentials,
|
||||||
// do its thing and then de-init whatever secrets have been
|
// do its thing and then de-init whatever secrets have been
|
||||||
// stored
|
// stored
|
||||||
|
{
|
||||||
let mut wallet = self.wallet.lock().unwrap();
|
let mut wallet = self.wallet.lock().unwrap();
|
||||||
wallet.open_with_credentials().map_err(|e| {
|
wallet.open_with_credentials().map_err(|e| {
|
||||||
error!(LOGGER, "Error opening wallet: {:?}", e);
|
error!(LOGGER, "Error opening wallet: {:?}", e);
|
||||||
IronError::new(Fail::compat(e), status::BadRequest)
|
IronError::new(Fail::compat(e), status::BadRequest)
|
||||||
})?;
|
})?;
|
||||||
let mut api = APIOwner::new(&mut *wallet);
|
}
|
||||||
|
let mut wallet = self.wallet.lock().unwrap();
|
||||||
|
let mut api = APIOwner::new(&mut wallet);
|
||||||
let resp = match self.handle_request(req, &mut api) {
|
let resp = match self.handle_request(req, &mut api) {
|
||||||
Ok(r) => self.create_ok_response(&r),
|
Ok(r) => self.create_ok_response(&r),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -367,23 +373,23 @@ impl Handler for OwnerAPIOptionsHandler where {
|
||||||
}
|
}
|
||||||
/// API Handler/Wrapper for foreign functions
|
/// API Handler/Wrapper for foreign functions
|
||||||
|
|
||||||
pub struct ForeignAPIHandler<T, K>
|
pub struct ForeignAPIHandler<T: ?Sized, K>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// Wallet instance
|
/// Wallet instance
|
||||||
pub wallet: Arc<Mutex<T>>,
|
pub wallet: Arc<Mutex<Box<T>>>,
|
||||||
phantom: PhantomData<K>,
|
phantom: PhantomData<K>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, K> ForeignAPIHandler<T, K>
|
impl<T: ?Sized, K> ForeignAPIHandler<T, K>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
/// create a new api handler
|
/// create a new api handler
|
||||||
pub fn new(wallet: Arc<Mutex<T>>) -> ForeignAPIHandler<T, K> {
|
pub fn new(wallet: Arc<Mutex<Box<T>>>) -> ForeignAPIHandler<T, K> {
|
||||||
ForeignAPIHandler {
|
ForeignAPIHandler {
|
||||||
wallet,
|
wallet,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
@ -442,7 +448,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T, K> Handler for ForeignAPIHandler<T, K>
|
impl<T: ?Sized, K> Handler for ForeignAPIHandler<T, K>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
||||||
K: Keychain + 'static,
|
K: Keychain + 'static,
|
||||||
|
@ -451,12 +457,15 @@ where
|
||||||
// every request should open with stored credentials,
|
// every request should open with stored credentials,
|
||||||
// do its thing and then de-init whatever secrets have been
|
// do its thing and then de-init whatever secrets have been
|
||||||
// stored
|
// stored
|
||||||
|
{
|
||||||
let mut wallet = self.wallet.lock().unwrap();
|
let mut wallet = self.wallet.lock().unwrap();
|
||||||
wallet.open_with_credentials().map_err(|e| {
|
wallet.open_with_credentials().map_err(|e| {
|
||||||
error!(LOGGER, "Error opening wallet: {:?}", e);
|
error!(LOGGER, "Error opening wallet: {:?}", e);
|
||||||
IronError::new(Fail::compat(e), status::BadRequest)
|
IronError::new(Fail::compat(e), status::BadRequest)
|
||||||
})?;
|
})?;
|
||||||
let mut api = APIForeign::new(&mut *wallet);
|
}
|
||||||
|
let mut wallet = self.wallet.lock().unwrap();
|
||||||
|
let mut api = APIForeign::new(&mut wallet);
|
||||||
let resp_json = self.handle_request(req, &mut api);
|
let resp_json = self.handle_request(req, &mut api);
|
||||||
api.wallet
|
api.wallet
|
||||||
.close()
|
.close()
|
||||||
|
|
|
@ -48,8 +48,11 @@ pub enum ErrorKind {
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Fee Exceeds amount
|
/// Fee Exceeds amount
|
||||||
#[fail(display = "Fee exceeds amount: sender amount {}, recipient fee {}", sender_amount,
|
#[fail(
|
||||||
recipient_fee)]
|
display = "Fee exceeds amount: sender amount {}, recipient fee {}",
|
||||||
|
sender_amount,
|
||||||
|
recipient_fee
|
||||||
|
)]
|
||||||
FeeExceedsAmount {
|
FeeExceedsAmount {
|
||||||
/// sender amount
|
/// sender amount
|
||||||
sender_amount: u64,
|
sender_amount: u64,
|
||||||
|
|
|
@ -18,7 +18,7 @@ use libwallet::error::Error;
|
||||||
use libwallet::types::WalletBackend;
|
use libwallet::types::WalletBackend;
|
||||||
|
|
||||||
/// Get next available key in the wallet
|
/// Get next available key in the wallet
|
||||||
pub fn next_available_key<T, K>(wallet: &mut T) -> Result<(Identifier, u32), Error>
|
pub fn next_available_key<T: ?Sized, K>(wallet: &mut T) -> Result<(Identifier, u32), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K>,
|
T: WalletBackend<K>,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
|
@ -30,7 +30,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve an existing key from a wallet
|
/// Retrieve an existing key from a wallet
|
||||||
pub fn retrieve_existing_key<T, K>(
|
pub fn retrieve_existing_key<T: ?Sized, K>(
|
||||||
wallet: &T,
|
wallet: &T,
|
||||||
key_id: Identifier,
|
key_id: Identifier,
|
||||||
) -> Result<(Identifier, u32), Error>
|
) -> Result<(Identifier, u32), Error>
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
use core::global;
|
use core::global;
|
||||||
use keychain::{Identifier, Keychain};
|
use keychain::{Identifier, Keychain};
|
||||||
use libtx::proof;
|
use libtx::proof;
|
||||||
use libwallet::Error;
|
|
||||||
use libwallet::types::*;
|
use libwallet::types::*;
|
||||||
use util::secp::{pedersen, key::SecretKey};
|
use libwallet::Error;
|
||||||
|
use util::secp::{key::SecretKey, pedersen};
|
||||||
use util::LOGGER;
|
use util::LOGGER;
|
||||||
|
|
||||||
/// Utility struct for return values from below
|
/// Utility struct for return values from below
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
//! Selection of inputs for building transactions
|
//! Selection of inputs for building transactions
|
||||||
|
|
||||||
use keychain::{Identifier, Keychain};
|
use keychain::{Identifier, Keychain};
|
||||||
use libtx::{build, tx_fee, slate::Slate};
|
use libtx::{build, slate::Slate, tx_fee};
|
||||||
use libwallet::error::{Error, ErrorKind};
|
use libwallet::error::{Error, ErrorKind};
|
||||||
use libwallet::internal::{keys, sigcontext};
|
use libwallet::internal::{keys, sigcontext};
|
||||||
use libwallet::types::*;
|
use libwallet::types::*;
|
||||||
|
@ -25,7 +25,7 @@ use libwallet::types::*;
|
||||||
/// and saves the private wallet identifiers of our selected outputs
|
/// and saves the private wallet identifiers of our selected outputs
|
||||||
/// into our transaction context
|
/// into our transaction context
|
||||||
|
|
||||||
pub fn build_send_tx_slate<T, K>(
|
pub fn build_send_tx_slate<T: ?Sized, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
num_participants: usize,
|
num_participants: usize,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
|
@ -122,7 +122,7 @@ where
|
||||||
/// returning the key of the fresh output and a closure
|
/// returning the key of the fresh output and a closure
|
||||||
/// that actually performs the addition of the output to the
|
/// that actually performs the addition of the output to the
|
||||||
/// wallet
|
/// wallet
|
||||||
pub fn build_recipient_output_with_slate<T, K>(
|
pub fn build_recipient_output_with_slate<T: ?Sized, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
slate: &mut Slate,
|
slate: &mut Slate,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
|
@ -182,7 +182,7 @@ where
|
||||||
/// Builds a transaction to send to someone from the HD seed associated with the
|
/// Builds a transaction to send to someone from the HD seed associated with the
|
||||||
/// wallet and the amount to send. Handles reading through the wallet data file,
|
/// wallet and the amount to send. Handles reading through the wallet data file,
|
||||||
/// selecting outputs to spend and building the change.
|
/// selecting outputs to spend and building the change.
|
||||||
pub fn select_send_tx<T, K>(
|
pub fn select_send_tx<T: ?Sized, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
current_height: u64,
|
current_height: u64,
|
||||||
|
@ -287,7 +287,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Selects inputs and change for a transaction
|
/// Selects inputs and change for a transaction
|
||||||
pub fn inputs_and_change<T, K>(
|
pub fn inputs_and_change<T: ?Sized, K>(
|
||||||
coins: &Vec<OutputData>,
|
coins: &Vec<OutputData>,
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
|
@ -313,10 +313,7 @@ where
|
||||||
for coin in coins {
|
for coin in coins {
|
||||||
let key_id = wallet.keychain().derive_key_id(coin.n_child)?;
|
let key_id = wallet.keychain().derive_key_id(coin.n_child)?;
|
||||||
if coin.is_coinbase {
|
if coin.is_coinbase {
|
||||||
parts.push(build::coinbase_input(
|
parts.push(build::coinbase_input(coin.value, key_id));
|
||||||
coin.value,
|
|
||||||
key_id,
|
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
parts.push(build::input(coin.value, key_id));
|
parts.push(build::input(coin.value, key_id));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ use util::LOGGER;
|
||||||
|
|
||||||
/// Receive a transaction, modifying the slate accordingly (which can then be
|
/// Receive a transaction, modifying the slate accordingly (which can then be
|
||||||
/// sent back to sender for posting)
|
/// sent back to sender for posting)
|
||||||
pub fn receive_tx<T, K>(wallet: &mut T, slate: &mut Slate) -> Result<(), Error>
|
pub fn receive_tx<T: ?Sized, K>(wallet: &mut T, slate: &mut Slate) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K>,
|
T: WalletBackend<K>,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
|
@ -53,7 +53,7 @@ where
|
||||||
|
|
||||||
/// Issue a new transaction to the provided sender by spending some of our
|
/// Issue a new transaction to the provided sender by spending some of our
|
||||||
/// wallet
|
/// wallet
|
||||||
pub fn create_send_tx<T, K>(
|
pub fn create_send_tx<T: ?Sized, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
minimum_confirmations: u64,
|
minimum_confirmations: u64,
|
||||||
|
@ -110,7 +110,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Complete a transaction as the sender
|
/// Complete a transaction as the sender
|
||||||
pub fn complete_tx<T, K>(
|
pub fn complete_tx<T: ?Sized, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
slate: &mut Slate,
|
slate: &mut Slate,
|
||||||
context: &sigcontext::Context,
|
context: &sigcontext::Context,
|
||||||
|
@ -129,7 +129,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Issue a burn tx
|
/// Issue a burn tx
|
||||||
pub fn issue_burn_tx<T, K>(
|
pub fn issue_burn_tx<T: ?Sized, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
minimum_confirmations: u64,
|
minimum_confirmations: u64,
|
||||||
|
|
|
@ -26,13 +26,17 @@ use libtx::reward;
|
||||||
use libwallet;
|
use libwallet;
|
||||||
use libwallet::error::{Error, ErrorKind};
|
use libwallet::error::{Error, ErrorKind};
|
||||||
use libwallet::internal::keys;
|
use libwallet::internal::keys;
|
||||||
use libwallet::types::{BlockFees, CbData, OutputData, OutputStatus, WalletBackend, WalletClient,
|
use libwallet::types::{
|
||||||
WalletInfo};
|
BlockFees, CbData, OutputData, OutputStatus, WalletBackend, WalletClient, WalletInfo,
|
||||||
|
};
|
||||||
use util::secp::pedersen;
|
use util::secp::pedersen;
|
||||||
use util::{self, LOGGER};
|
use util::{self, LOGGER};
|
||||||
|
|
||||||
/// Retrieve all of the outputs (doesn't attempt to update from node)
|
/// Retrieve all of the outputs (doesn't attempt to update from node)
|
||||||
pub fn retrieve_outputs<T, K>(wallet: &mut T, show_spent: bool) -> Result<Vec<OutputData>, Error>
|
pub fn retrieve_outputs<T: ?Sized, K>(
|
||||||
|
wallet: &mut T,
|
||||||
|
show_spent: bool,
|
||||||
|
) -> Result<Vec<OutputData>, Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K>,
|
T: WalletBackend<K>,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
|
@ -57,7 +61,7 @@ where
|
||||||
|
|
||||||
/// Refreshes the outputs in a wallet with the latest information
|
/// Refreshes the outputs in a wallet with the latest information
|
||||||
/// from a node
|
/// from a node
|
||||||
pub fn refresh_outputs<T, K>(wallet: &mut T) -> Result<(), Error>
|
pub fn refresh_outputs<T: ?Sized, K>(wallet: &mut T) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
|
@ -69,7 +73,7 @@ where
|
||||||
|
|
||||||
/// build a local map of wallet outputs keyed by commit
|
/// build a local map of wallet outputs keyed by commit
|
||||||
/// and a list of outputs we want to query the node for
|
/// and a list of outputs we want to query the node for
|
||||||
pub fn map_wallet_outputs<T, K>(
|
pub fn map_wallet_outputs<T: ?Sized, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
) -> Result<HashMap<pedersen::Commitment, Identifier>, Error>
|
) -> Result<HashMap<pedersen::Commitment, Identifier>, Error>
|
||||||
where
|
where
|
||||||
|
@ -90,7 +94,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply refreshed API output data to the wallet
|
/// Apply refreshed API output data to the wallet
|
||||||
pub fn apply_api_outputs<T, K>(
|
pub fn apply_api_outputs<T: ?Sized, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
wallet_outputs: &HashMap<pedersen::Commitment, Identifier>,
|
wallet_outputs: &HashMap<pedersen::Commitment, Identifier>,
|
||||||
api_outputs: &HashMap<pedersen::Commitment, String>,
|
api_outputs: &HashMap<pedersen::Commitment, String>,
|
||||||
|
@ -125,7 +129,7 @@ where
|
||||||
|
|
||||||
/// Builds a single api query to retrieve the latest output data from the node.
|
/// Builds a single api query to retrieve the latest output data from the node.
|
||||||
/// So we can refresh the local wallet outputs.
|
/// So we can refresh the local wallet outputs.
|
||||||
fn refresh_output_state<T, K>(wallet: &mut T, height: u64) -> Result<(), Error>
|
fn refresh_output_state<T: ?Sized, K>(wallet: &mut T, height: u64) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
|
@ -144,7 +148,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_old_unconfirmed<T, K>(wallet: &mut T, height: u64) -> Result<(), Error>
|
fn clean_old_unconfirmed<T: ?Sized, K>(wallet: &mut T, height: u64) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K>,
|
T: WalletBackend<K>,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
|
@ -168,7 +172,7 @@ where
|
||||||
|
|
||||||
/// Retrieve summary info about the wallet
|
/// Retrieve summary info about the wallet
|
||||||
/// caller should refresh first if desired
|
/// caller should refresh first if desired
|
||||||
pub fn retrieve_info<T, K>(wallet: &mut T) -> Result<WalletInfo, Error>
|
pub fn retrieve_info<T: ?Sized, K>(wallet: &mut T) -> Result<WalletInfo, Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K> + WalletClient,
|
T: WalletBackend<K> + WalletClient,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
|
@ -209,7 +213,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a coinbase output and insert into wallet
|
/// Build a coinbase output and insert into wallet
|
||||||
pub fn build_coinbase<T, K>(wallet: &mut T, block_fees: &BlockFees) -> Result<CbData, Error>
|
pub fn build_coinbase<T: ?Sized, K>(wallet: &mut T, block_fees: &BlockFees) -> Result<CbData, Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<K>,
|
T: WalletBackend<K>,
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
|
@ -234,7 +238,7 @@ where
|
||||||
|
|
||||||
//TODO: Split up the output creation and the wallet insertion
|
//TODO: Split up the output creation and the wallet insertion
|
||||||
/// Build a coinbase output and the corresponding kernel
|
/// Build a coinbase output and the corresponding kernel
|
||||||
pub fn receive_coinbase<T, K>(
|
pub fn receive_coinbase<T: ?Sized, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
block_fees: &BlockFees,
|
block_fees: &BlockFees,
|
||||||
) -> Result<(Output, TxKernel, BlockFees), Error>
|
) -> Result<(Output, TxKernel, BlockFees), Error>
|
||||||
|
|
|
@ -33,6 +33,19 @@ use libwallet::error::{Error, ErrorKind};
|
||||||
|
|
||||||
use util::secp::pedersen;
|
use util::secp::pedersen;
|
||||||
|
|
||||||
|
/// Combined trait to allow dynamic wallet dispatch
|
||||||
|
pub trait WalletInst<K>: WalletBackend<K> + WalletClient + Send + Sync + 'static
|
||||||
|
where
|
||||||
|
K: Keychain,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
impl<T, K> WalletInst<K> for T
|
||||||
|
where
|
||||||
|
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
||||||
|
K: Keychain,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// TODO:
|
/// TODO:
|
||||||
/// Wallets should implement this backend for their storage. All functions
|
/// Wallets should implement this backend for their storage. All functions
|
||||||
/// here expect that the wallet instance has instantiated itself or stored
|
/// here expect that the wallet instance has instantiated itself or stored
|
||||||
|
|
|
@ -29,7 +29,7 @@ use libwallet::{internal, Error, ErrorKind};
|
||||||
use types::{WalletConfig, WalletSeed};
|
use types::{WalletConfig, WalletSeed};
|
||||||
use util::secp::pedersen;
|
use util::secp::pedersen;
|
||||||
|
|
||||||
pub const DB_DIR: &'static str = "wallet";
|
pub const DB_DIR: &'static str = "wallet_data";
|
||||||
|
|
||||||
const OUTPUT_PREFIX: u8 = 'o' as u8;
|
const OUTPUT_PREFIX: u8 = 'o' as u8;
|
||||||
const DERIV_PREFIX: u8 = 'd' as u8;
|
const DERIV_PREFIX: u8 = 'd' as u8;
|
||||||
|
@ -40,6 +40,13 @@ impl From<store::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// test to see if database files exist in the current directory. If so,
|
||||||
|
/// use a DB backend for all operations
|
||||||
|
pub fn wallet_db_exists(config: WalletConfig) -> bool {
|
||||||
|
let db_path = path::Path::new(&config.data_file_dir).join(DB_DIR);
|
||||||
|
db_path.exists()
|
||||||
|
}
|
||||||
|
|
||||||
pub struct LMDBBackend<K> {
|
pub struct LMDBBackend<K> {
|
||||||
db: store::Store,
|
db: store::Store,
|
||||||
config: WalletConfig,
|
config: WalletConfig,
|
||||||
|
@ -64,6 +71,13 @@ impl<K> LMDBBackend<K> {
|
||||||
keychain: None,
|
keychain: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Just test to see if database files exist in the current directory. If
|
||||||
|
/// so, use a DB backend for all operations
|
||||||
|
pub fn exists(config: WalletConfig) -> bool {
|
||||||
|
let db_path = path::Path::new(&config.data_file_dir).join(DB_DIR);
|
||||||
|
db_path.exists()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K> WalletBackend<K> for LMDBBackend<K>
|
impl<K> WalletBackend<K> for LMDBBackend<K>
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::MAIN_SEPARATOR;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::path::MAIN_SEPARATOR;
|
||||||
|
|
||||||
use blake2;
|
use blake2;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
|
Loading…
Reference in a new issue