mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21: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
|
||||
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)
|
||||
pub run_test_miner: Option<bool>,
|
||||
|
||||
|
@ -212,6 +215,7 @@ impl Default for ServerConfig {
|
|||
run_tui: None,
|
||||
run_wallet_listener: Some(false),
|
||||
run_wallet_owner_api: Some(false),
|
||||
use_db_wallet: Some(false),
|
||||
run_test_miner: Some(false),
|
||||
test_miner_wallet_url: None,
|
||||
}
|
||||
|
@ -323,9 +327,7 @@ impl SyncState {
|
|||
|
||||
debug!(
|
||||
LOGGER,
|
||||
"sync_state: sync_status: {:?} -> {:?}",
|
||||
*status,
|
||||
new_status,
|
||||
"sync_state: sync_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| {
|
||||
panic!(
|
||||
"Error creating wallet listener: {:?} Config: {:?}",
|
||||
|
@ -330,7 +330,7 @@ impl LocalServerContainer {
|
|||
.unwrap_or_else(|e| panic!("Error creating wallet: {:?} Config: {:?}", e, config));
|
||||
wallet.keychain = Some(keychain);
|
||||
let _ =
|
||||
wallet::controller::owner_single_use(&mut wallet, |api| {
|
||||
wallet::controller::owner_single_use(Box::new(wallet), |api| {
|
||||
let result = api.issue_send_tx(
|
||||
amount,
|
||||
minimum_confirmations,
|
||||
|
|
|
@ -40,8 +40,8 @@ pub mod tui;
|
|||
|
||||
use std::env::current_dir;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
|
@ -51,10 +51,9 @@ use daemonize::Daemonize;
|
|||
use config::GlobalConfig;
|
||||
use core::core::amount_to_hr_string;
|
||||
use core::global;
|
||||
use keychain::ExtKeychain;
|
||||
use tui::ui;
|
||||
use util::{init_logger, LoggingConfig, LOGGER};
|
||||
use wallet::{libwallet, FileWallet};
|
||||
use wallet::{libwallet, wallet_db_exists, FileWallet, LMDBBackend, WalletConfig, WalletInst};
|
||||
|
||||
// include build information
|
||||
pub mod built_info {
|
||||
|
@ -296,8 +295,11 @@ fn main() {
|
|||
.about("basic wallet contents summary"))
|
||||
|
||||
.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")
|
||||
.about("Attempt to restore wallet contents from the chain using seed and password. \
|
||||
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 {
|
||||
let use_db = server_config.use_db_wallet == Some(true);
|
||||
let mut wallet_config = global_config.members.as_ref().unwrap().wallet.clone();
|
||||
if let Err(_) = wallet::WalletSeed::from_file(&wallet_config) {
|
||||
wallet::WalletSeed::init_file(&wallet_config)
|
||||
.expect("Failed to create wallet seed file.");
|
||||
};
|
||||
init_wallet_seed(wallet_config.clone());
|
||||
|
||||
let _ = thread::Builder::new()
|
||||
.name("wallet_listener".to_string())
|
||||
.spawn(move || {
|
||||
let wallet: FileWallet<keychain::ExtKeychain> =
|
||||
FileWallet::new(wallet_config.clone(), "").unwrap_or_else(|e| {
|
||||
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
||||
});
|
||||
let wallet = instantiate_wallet(wallet_config.clone(), "", use_db);
|
||||
wallet::controller::foreign_listener(wallet, &wallet_config.api_listen_addr())
|
||||
.unwrap_or_else(|e| {
|
||||
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 {
|
||||
let use_db = server_config.use_db_wallet == Some(true);
|
||||
let mut wallet_config = global_config.members.unwrap().wallet;
|
||||
if let Err(_) = wallet::WalletSeed::from_file(&wallet_config) {
|
||||
wallet::WalletSeed::init_file(&wallet_config)
|
||||
.expect("Failed to create wallet seed file.");
|
||||
};
|
||||
init_wallet_seed(wallet_config.clone());
|
||||
|
||||
let _ = thread::Builder::new()
|
||||
.name("wallet_owner_listener".to_string())
|
||||
.spawn(move || {
|
||||
let wallet: FileWallet<ExtKeychain> = FileWallet::new(wallet_config.clone(), "")
|
||||
.unwrap_or_else(|e| {
|
||||
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
||||
});
|
||||
let wallet = instantiate_wallet(wallet_config.clone(), "", use_db);
|
||||
wallet::controller::owner_listener(wallet, "127.0.0.1:13420").unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"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) {
|
||||
// just get defaults from the global config
|
||||
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.
|
||||
// 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.");
|
||||
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
|
||||
return;
|
||||
}
|
||||
|
@ -584,12 +622,12 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) {
|
|||
.value_of("pass")
|
||||
.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
|
||||
{
|
||||
let wallet: FileWallet<keychain::ExtKeychain> =
|
||||
FileWallet::new(wallet_config.clone(), passphrase).unwrap_or_else(|e| {
|
||||
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
||||
});
|
||||
let wallet = instantiate_wallet(wallet_config.clone(), passphrase, use_db);
|
||||
match wallet_args.subcommand() {
|
||||
("listen", Some(listen_args)) => {
|
||||
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
|
||||
{
|
||||
let mut wallet: FileWallet<keychain::ExtKeychain> =
|
||||
FileWallet::new(wallet_config.clone(), passphrase).unwrap_or_else(|e| {
|
||||
panic!("Error creating wallet: {:?} Config: {:?}", e, wallet_config)
|
||||
});
|
||||
let _res = wallet::controller::owner_single_use(&mut wallet, |api| {
|
||||
let wallet = instantiate_wallet(wallet_config.clone(), passphrase, use_db);
|
||||
let _res = wallet::controller::owner_single_use(wallet, |api| {
|
||||
match wallet_args.subcommand() {
|
||||
("send", Some(send_args)) => {
|
||||
let amount = send_args
|
||||
|
|
|
@ -14,16 +14,20 @@
|
|||
|
||||
//! Main Menu definition
|
||||
|
||||
use cursive::Cursive;
|
||||
use cursive::align::HAlign;
|
||||
use cursive::direction::Orientation;
|
||||
use cursive::event::{EventResult, Key};
|
||||
use cursive::view::Identifiable;
|
||||
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,
|
||||
VIEW_PEER_SYNC, VIEW_VERSION};
|
||||
use tui::constants::{
|
||||
MAIN_MENU, ROOT_STACK, SUBMENU_MINING_BUTTON, VIEW_BASIC_STATUS, VIEW_MINING, VIEW_PEER_SYNC,
|
||||
VIEW_VERSION,
|
||||
};
|
||||
|
||||
pub fn create() -> Box<View> {
|
||||
let mut main_menu = SelectView::new().h_align(HAlign::Left).with_id(MAIN_MENU);
|
||||
|
|
|
@ -16,18 +16,20 @@
|
|||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use cursive::Cursive;
|
||||
use cursive::direction::Orientation;
|
||||
use cursive::event::Key;
|
||||
use cursive::traits::{Boxable, Identifiable};
|
||||
use cursive::view::View;
|
||||
use cursive::views::{BoxView, Button, Dialog, LinearLayout, OnEventView, Panel, StackView,
|
||||
TextView};
|
||||
use cursive::views::{
|
||||
BoxView, Button, Dialog, LinearLayout, OnEventView, Panel, StackView, TextView,
|
||||
};
|
||||
use cursive::Cursive;
|
||||
use std::time;
|
||||
use tui::chrono::prelude::{DateTime, NaiveDateTime, Utc};
|
||||
|
||||
use tui::constants::{MAIN_MENU, SUBMENU_MINING_BUTTON, TABLE_MINING_DIFF_STATUS,
|
||||
TABLE_MINING_STATUS, VIEW_MINING};
|
||||
use tui::constants::{
|
||||
MAIN_MENU, SUBMENU_MINING_BUTTON, TABLE_MINING_DIFF_STATUS, TABLE_MINING_STATUS, VIEW_MINING,
|
||||
};
|
||||
use tui::types::TUIStatusListener;
|
||||
|
||||
use servers::{DiffBlock, ServerStats, WorkerStats};
|
||||
|
|
|
@ -18,11 +18,11 @@ use std::cmp::Ordering;
|
|||
|
||||
use servers::{PeerStats, ServerStats};
|
||||
|
||||
use cursive::Cursive;
|
||||
use cursive::direction::Orientation;
|
||||
use cursive::traits::{Boxable, Identifiable};
|
||||
use cursive::view::View;
|
||||
use cursive::views::{BoxView, Dialog, LinearLayout, TextView};
|
||||
use cursive::Cursive;
|
||||
|
||||
use tui::constants::{TABLE_PEER_STATUS, VIEW_PEER_SYNC};
|
||||
use tui::table::{TableView, TableViewItem};
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
|
||||
//! Basic status view definition
|
||||
|
||||
use cursive::Cursive;
|
||||
use cursive::direction::Orientation;
|
||||
use cursive::traits::Identifiable;
|
||||
use cursive::view::View;
|
||||
use cursive::views::{BoxView, LinearLayout, TextView};
|
||||
use cursive::Cursive;
|
||||
|
||||
use tui::constants::VIEW_BASIC_STATUS;
|
||||
use tui::types::TUIStatusListener;
|
||||
|
|
|
@ -54,7 +54,6 @@ use std::hash::Hash;
|
|||
use std::rc::Rc;
|
||||
|
||||
// External Dependencies ------------------------------------------------------
|
||||
use cursive::With;
|
||||
use cursive::align::HAlign;
|
||||
use cursive::direction::Direction;
|
||||
use cursive::event::{Callback, Event, EventResult, Key};
|
||||
|
@ -62,6 +61,7 @@ use cursive::theme::ColorStyle;
|
|||
use cursive::theme::PaletteColor::{Highlight, HighlightInactive, Primary};
|
||||
use cursive::vec::Vec2;
|
||||
use cursive::view::{ScrollBase, View};
|
||||
use cursive::With;
|
||||
use cursive::{Cursive, Printer};
|
||||
|
||||
/// A trait for displaying and sorting items inside a
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
//! Types specific to the UI module
|
||||
|
||||
use cursive::Cursive;
|
||||
use cursive::view::View;
|
||||
use cursive::Cursive;
|
||||
use servers::ServerStats;
|
||||
|
||||
/// 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 time;
|
||||
|
||||
use cursive::Cursive;
|
||||
use cursive::direction::Orientation;
|
||||
use cursive::theme::BaseColor::{Black, Blue, Cyan, White};
|
||||
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::traits::Identifiable;
|
||||
use cursive::utils::markup::StyledString;
|
||||
use cursive::views::{LinearLayout, Panel, StackView, TextView, ViewBox};
|
||||
use cursive::Cursive;
|
||||
|
||||
use servers::Server;
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
|
||||
//! Version and build info
|
||||
|
||||
use cursive::Cursive;
|
||||
use cursive::direction::Orientation;
|
||||
use cursive::traits::Identifiable;
|
||||
use cursive::view::View;
|
||||
use cursive::views::{BoxView, LinearLayout, TextView};
|
||||
use cursive::Cursive;
|
||||
|
||||
use tui::constants::VIEW_VERSION;
|
||||
use tui::types::TUIStatusListener;
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
// limitations under the License.
|
||||
|
||||
use core::core::{self, amount_to_hr_string};
|
||||
use libwallet::Error;
|
||||
use libwallet::types::{OutputData, WalletInfo};
|
||||
use libwallet::Error;
|
||||
use prettytable;
|
||||
use std::io::prelude::Write;
|
||||
use term;
|
||||
|
|
|
@ -104,7 +104,19 @@ impl Fail for Error {
|
|||
|
||||
impl Display for Error {
|
||||
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 tokio_core::reactor;
|
||||
use tokio_retry::Retry;
|
||||
use tokio_retry::strategy::FibonacciBackoff;
|
||||
use tokio_retry::Retry;
|
||||
|
||||
use failure::ResultExt;
|
||||
|
||||
use keychain::{self, Identifier, Keychain};
|
||||
use util::LOGGER;
|
||||
use util::secp::pedersen;
|
||||
use util::LOGGER;
|
||||
|
||||
use error::{Error, ErrorKind};
|
||||
|
||||
|
@ -35,8 +35,8 @@ use libtx::slate::Slate;
|
|||
use libwallet;
|
||||
|
||||
use libwallet::types::{
|
||||
BlockFees, CbData, OutputData, TxWrapper, WalletBackend,
|
||||
WalletClient, WalletDetails, WalletOutputBatch,
|
||||
BlockFees, CbData, OutputData, TxWrapper, WalletBackend, WalletClient, WalletDetails,
|
||||
WalletOutputBatch,
|
||||
};
|
||||
|
||||
use types::{WalletConfig, WalletSeed};
|
||||
|
|
|
@ -60,5 +60,6 @@ pub use client::create_coinbase;
|
|||
pub use error::{Error, ErrorKind};
|
||||
pub use file_wallet::FileWallet;
|
||||
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};
|
||||
|
|
|
@ -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
|
||||
/// being built.
|
||||
fn build_input<K>(
|
||||
value: u64,
|
||||
features: OutputFeatures,
|
||||
key_id: Identifier,
|
||||
) -> Box<Append<K>>
|
||||
fn build_input<K>(value: u64, features: OutputFeatures, key_id: Identifier) -> Box<Append<K>>
|
||||
where
|
||||
K: Keychain,
|
||||
{
|
||||
|
@ -78,10 +74,7 @@ where
|
|||
}
|
||||
|
||||
/// Adds a coinbase input spending a coinbase output.
|
||||
pub fn coinbase_input<K>(
|
||||
value: u64,
|
||||
key_id: Identifier,
|
||||
) -> Box<Append<K>>
|
||||
pub fn coinbase_input<K>(value: u64, key_id: Identifier) -> Box<Append<K>>
|
||||
where
|
||||
K: Keychain,
|
||||
{
|
||||
|
|
|
@ -23,8 +23,8 @@ use keychain::{BlindSum, BlindingFactor, Keychain};
|
|||
use libtx::error::{Error, ErrorKind};
|
||||
use libtx::{aggsig, build, tx_fee};
|
||||
|
||||
use util::secp::Signature;
|
||||
use util::secp::key::{PublicKey, SecretKey};
|
||||
use util::secp::Signature;
|
||||
use util::{secp, LOGGER};
|
||||
|
||||
/// Public data for each participant in the slate
|
||||
|
@ -261,11 +261,7 @@ impl Slate {
|
|||
// double check the fee amount included in the partial tx
|
||||
// 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
|
||||
let fee = tx_fee(
|
||||
self.tx.inputs.len(),
|
||||
self.tx.outputs.len(),
|
||||
None,
|
||||
);
|
||||
let fee = tx_fee(self.tx.inputs.len(), self.tx.outputs.len(), None);
|
||||
if fee > self.tx.fee() {
|
||||
return Err(ErrorKind::Fee(
|
||||
format!("Fee Dispute Error: {}, {}", self.tx.fee(), fee,).to_string(),
|
||||
|
|
|
@ -22,32 +22,33 @@ use std::marker::PhantomData;
|
|||
use core::ser;
|
||||
use keychain::Keychain;
|
||||
use libtx::slate::Slate;
|
||||
use libwallet::Error;
|
||||
use libwallet::internal::{tx, updater};
|
||||
use libwallet::types::{BlockFees, CbData, OutputData, TxWrapper, WalletBackend, WalletClient,
|
||||
WalletInfo};
|
||||
use libwallet::types::{
|
||||
BlockFees, CbData, OutputData, TxWrapper, WalletBackend, WalletClient, WalletInfo,
|
||||
};
|
||||
use libwallet::Error;
|
||||
use util::{self, LOGGER};
|
||||
|
||||
/// Wrapper around internal API functions, containing a reference to
|
||||
/// the wallet/keychain that they're acting upon
|
||||
pub struct APIOwner<'a, W, K>
|
||||
pub struct APIOwner<'a, W: ?Sized, K>
|
||||
where
|
||||
W: 'a + WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
{
|
||||
/// Wallet, contains its keychain (TODO: Split these up into 2 traits
|
||||
/// perhaps)
|
||||
pub wallet: &'a mut W,
|
||||
pub wallet: &'a mut Box<W>,
|
||||
phantom: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<'a, W, K> APIOwner<'a, W, K>
|
||||
impl<'a, W: ?Sized, K> APIOwner<'a, W, K>
|
||||
where
|
||||
W: 'a + WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
{
|
||||
/// 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 {
|
||||
wallet: wallet_in,
|
||||
phantom: PhantomData,
|
||||
|
@ -67,7 +68,7 @@ where
|
|||
}
|
||||
Ok((
|
||||
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 {
|
||||
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))
|
||||
}
|
||||
|
||||
|
@ -95,7 +96,7 @@ where
|
|||
fluff: bool,
|
||||
) -> Result<(), Error> {
|
||||
let (slate, context, lock_fn) = tx::create_send_tx(
|
||||
self.wallet,
|
||||
&mut **self.wallet,
|
||||
amount,
|
||||
minimum_confirmations,
|
||||
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
|
||||
let tx_hex = util::to_hex(ser::ser_vec(&slate.tx).unwrap());
|
||||
|
@ -132,7 +133,12 @@ where
|
|||
minimum_confirmations: u64,
|
||||
max_outputs: usize,
|
||||
) -> 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());
|
||||
self.wallet.post_tx(&TxWrapper { tx_hex: tx_hex }, false)?;
|
||||
Ok(())
|
||||
|
@ -160,7 +166,7 @@ where
|
|||
|
||||
/// Attempt to update outputs in wallet, return whether it was successful
|
||||
fn update_outputs(&mut self) -> bool {
|
||||
match updater::refresh_outputs(self.wallet) {
|
||||
match updater::refresh_outputs(&mut **self.wallet) {
|
||||
Ok(_) => true,
|
||||
Err(_) => false,
|
||||
}
|
||||
|
@ -169,24 +175,24 @@ where
|
|||
|
||||
/// Wrapper around external API functions, intended to communicate
|
||||
/// with other parties
|
||||
pub struct APIForeign<'a, W, K>
|
||||
pub struct APIForeign<'a, W: ?Sized, K>
|
||||
where
|
||||
W: 'a + WalletBackend<K> + WalletClient,
|
||||
W: WalletBackend<K> + WalletClient + 'a,
|
||||
K: Keychain,
|
||||
{
|
||||
/// Wallet, contains its keychain (TODO: Split these up into 2 traits
|
||||
/// perhaps)
|
||||
pub wallet: &'a mut W,
|
||||
pub wallet: &'a mut Box<W>,
|
||||
phantom: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<'a, W, K> APIForeign<'a, W, K>
|
||||
impl<'a, W: ?Sized, K> APIForeign<'a, W, K>
|
||||
where
|
||||
W: 'a + WalletBackend<K> + WalletClient,
|
||||
W: WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
{
|
||||
/// 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 {
|
||||
wallet: wallet_in,
|
||||
phantom: PhantomData,
|
||||
|
@ -195,11 +201,11 @@ where
|
|||
|
||||
/// Build a new (potential) coinbase transaction in the wallet
|
||||
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
|
||||
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 libtx::slate::Slate;
|
||||
use libwallet::api::{APIForeign, APIOwner};
|
||||
use libwallet::types::{BlockFees, CbData, OutputData, SendTXArgs, WalletBackend, WalletClient,
|
||||
WalletInfo};
|
||||
use libwallet::types::{
|
||||
BlockFees, CbData, OutputData, SendTXArgs, WalletBackend, WalletClient, WalletInfo, WalletInst,
|
||||
};
|
||||
use libwallet::{Error, ErrorKind};
|
||||
|
||||
use util::LOGGER;
|
||||
|
||||
/// Instantiate wallet Owner API for a single-use (command line) 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
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
F: FnOnce(&mut APIOwner<T, K>) -> Result<(), Error>,
|
||||
K: Keychain,
|
||||
{
|
||||
wallet.open_with_credentials()?;
|
||||
f(&mut APIOwner::new(wallet))?;
|
||||
wallet.close()?;
|
||||
let mut w = wallet;
|
||||
w.open_with_credentials()?;
|
||||
f(&mut APIOwner::new(&mut w))?;
|
||||
w.close()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Instantiate wallet Foreign API for a single-use (command line) 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
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
F: FnOnce(&mut APIForeign<T, K>) -> Result<(), Error>,
|
||||
|
@ -67,9 +69,9 @@ where
|
|||
|
||||
/// Listener version, providing same API but listening for requests on a
|
||||
/// 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
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
T: WalletInst<K>,
|
||||
OwnerAPIGetHandler<T, K>: Handler,
|
||||
OwnerAPIPostHandler<T, K>: Handler,
|
||||
K: Keychain,
|
||||
|
@ -99,9 +101,9 @@ where
|
|||
|
||||
/// Listener version, providing same API but listening for requests on a
|
||||
/// 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
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
T: WalletInst<K>,
|
||||
ForeignAPIHandler<T, K>: Handler,
|
||||
K: Keychain,
|
||||
{
|
||||
|
@ -124,23 +126,23 @@ where
|
|||
}
|
||||
/// API Handler/Wrapper for owner functions
|
||||
|
||||
pub struct OwnerAPIGetHandler<T, K>
|
||||
pub struct OwnerAPIGetHandler<T: ?Sized, K>
|
||||
where
|
||||
T: WalletBackend<K>,
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
{
|
||||
/// Wallet instance
|
||||
pub wallet: Arc<Mutex<T>>,
|
||||
pub wallet: Arc<Mutex<Box<T>>>,
|
||||
phantom: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<T, K> OwnerAPIGetHandler<T, K>
|
||||
impl<T: ?Sized, K> OwnerAPIGetHandler<T, K>
|
||||
where
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
{
|
||||
/// 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 {
|
||||
wallet,
|
||||
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
|
||||
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
||||
K: Keychain + 'static,
|
||||
|
@ -215,7 +217,8 @@ where
|
|||
error!(LOGGER, "Error opening wallet: {:?}", e);
|
||||
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);
|
||||
if !resp_json.is_err() {
|
||||
resp_json
|
||||
|
@ -232,23 +235,23 @@ where
|
|||
}
|
||||
|
||||
/// Handles all owner API POST requests
|
||||
pub struct OwnerAPIPostHandler<T, K>
|
||||
pub struct OwnerAPIPostHandler<T: ?Sized, K>
|
||||
where
|
||||
T: WalletBackend<K>,
|
||||
K: Keychain,
|
||||
{
|
||||
/// Wallet instance
|
||||
pub wallet: Arc<Mutex<T>>,
|
||||
pub wallet: Arc<Mutex<Box<T>>>,
|
||||
phantom: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<T, K> OwnerAPIPostHandler<T, K>
|
||||
impl<T: ?Sized, K> OwnerAPIPostHandler<T, K>
|
||||
where
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
{
|
||||
/// 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 {
|
||||
wallet,
|
||||
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
|
||||
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
||||
K: Keychain + 'static,
|
||||
|
@ -329,12 +332,15 @@ where
|
|||
// every request should open with stored credentials,
|
||||
// do its thing and then de-init whatever secrets have been
|
||||
// stored
|
||||
{
|
||||
let mut wallet = self.wallet.lock().unwrap();
|
||||
wallet.open_with_credentials().map_err(|e| {
|
||||
error!(LOGGER, "Error opening wallet: {:?}", e);
|
||||
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) {
|
||||
Ok(r) => self.create_ok_response(&r),
|
||||
Err(e) => {
|
||||
|
@ -367,23 +373,23 @@ impl Handler for OwnerAPIOptionsHandler where {
|
|||
}
|
||||
/// API Handler/Wrapper for foreign functions
|
||||
|
||||
pub struct ForeignAPIHandler<T, K>
|
||||
pub struct ForeignAPIHandler<T: ?Sized, K>
|
||||
where
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
{
|
||||
/// Wallet instance
|
||||
pub wallet: Arc<Mutex<T>>,
|
||||
pub wallet: Arc<Mutex<Box<T>>>,
|
||||
phantom: PhantomData<K>,
|
||||
}
|
||||
|
||||
impl<T, K> ForeignAPIHandler<T, K>
|
||||
impl<T: ?Sized, K> ForeignAPIHandler<T, K>
|
||||
where
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
{
|
||||
/// 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 {
|
||||
wallet,
|
||||
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
|
||||
T: WalletBackend<K> + WalletClient + Send + Sync + 'static,
|
||||
K: Keychain + 'static,
|
||||
|
@ -451,12 +457,15 @@ where
|
|||
// every request should open with stored credentials,
|
||||
// do its thing and then de-init whatever secrets have been
|
||||
// stored
|
||||
{
|
||||
let mut wallet = self.wallet.lock().unwrap();
|
||||
wallet.open_with_credentials().map_err(|e| {
|
||||
error!(LOGGER, "Error opening wallet: {:?}", e);
|
||||
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);
|
||||
api.wallet
|
||||
.close()
|
||||
|
|
|
@ -48,8 +48,11 @@ pub enum ErrorKind {
|
|||
},
|
||||
|
||||
/// Fee Exceeds amount
|
||||
#[fail(display = "Fee exceeds amount: sender amount {}, recipient fee {}", sender_amount,
|
||||
recipient_fee)]
|
||||
#[fail(
|
||||
display = "Fee exceeds amount: sender amount {}, recipient fee {}",
|
||||
sender_amount,
|
||||
recipient_fee
|
||||
)]
|
||||
FeeExceedsAmount {
|
||||
/// sender amount
|
||||
sender_amount: u64,
|
||||
|
|
|
@ -18,7 +18,7 @@ use libwallet::error::Error;
|
|||
use libwallet::types::WalletBackend;
|
||||
|
||||
/// 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
|
||||
T: WalletBackend<K>,
|
||||
K: Keychain,
|
||||
|
@ -30,7 +30,7 @@ where
|
|||
}
|
||||
|
||||
/// Retrieve an existing key from a wallet
|
||||
pub fn retrieve_existing_key<T, K>(
|
||||
pub fn retrieve_existing_key<T: ?Sized, K>(
|
||||
wallet: &T,
|
||||
key_id: Identifier,
|
||||
) -> Result<(Identifier, u32), Error>
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
use core::global;
|
||||
use keychain::{Identifier, Keychain};
|
||||
use libtx::proof;
|
||||
use libwallet::Error;
|
||||
use libwallet::types::*;
|
||||
use util::secp::{pedersen, key::SecretKey};
|
||||
use libwallet::Error;
|
||||
use util::secp::{key::SecretKey, pedersen};
|
||||
use util::LOGGER;
|
||||
|
||||
/// Utility struct for return values from below
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
//! Selection of inputs for building transactions
|
||||
|
||||
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::internal::{keys, sigcontext};
|
||||
use libwallet::types::*;
|
||||
|
@ -25,7 +25,7 @@ use libwallet::types::*;
|
|||
/// and saves the private wallet identifiers of our selected outputs
|
||||
/// into our transaction context
|
||||
|
||||
pub fn build_send_tx_slate<T, K>(
|
||||
pub fn build_send_tx_slate<T: ?Sized, K>(
|
||||
wallet: &mut T,
|
||||
num_participants: usize,
|
||||
amount: u64,
|
||||
|
@ -122,7 +122,7 @@ where
|
|||
/// returning the key of the fresh output and a closure
|
||||
/// that actually performs the addition of the output to the
|
||||
/// wallet
|
||||
pub fn build_recipient_output_with_slate<T, K>(
|
||||
pub fn build_recipient_output_with_slate<T: ?Sized, K>(
|
||||
wallet: &mut T,
|
||||
slate: &mut Slate,
|
||||
) -> Result<
|
||||
|
@ -182,7 +182,7 @@ where
|
|||
/// 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,
|
||||
/// 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,
|
||||
amount: u64,
|
||||
current_height: u64,
|
||||
|
@ -287,7 +287,7 @@ where
|
|||
}
|
||||
|
||||
/// 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>,
|
||||
wallet: &mut T,
|
||||
amount: u64,
|
||||
|
@ -313,10 +313,7 @@ where
|
|||
for coin in coins {
|
||||
let key_id = wallet.keychain().derive_key_id(coin.n_child)?;
|
||||
if coin.is_coinbase {
|
||||
parts.push(build::coinbase_input(
|
||||
coin.value,
|
||||
key_id,
|
||||
));
|
||||
parts.push(build::coinbase_input(coin.value, key_id));
|
||||
} else {
|
||||
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
|
||||
/// 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
|
||||
T: WalletBackend<K>,
|
||||
K: Keychain,
|
||||
|
@ -53,7 +53,7 @@ where
|
|||
|
||||
/// Issue a new transaction to the provided sender by spending some of our
|
||||
/// wallet
|
||||
pub fn create_send_tx<T, K>(
|
||||
pub fn create_send_tx<T: ?Sized, K>(
|
||||
wallet: &mut T,
|
||||
amount: u64,
|
||||
minimum_confirmations: u64,
|
||||
|
@ -110,7 +110,7 @@ where
|
|||
}
|
||||
|
||||
/// Complete a transaction as the sender
|
||||
pub fn complete_tx<T, K>(
|
||||
pub fn complete_tx<T: ?Sized, K>(
|
||||
wallet: &mut T,
|
||||
slate: &mut Slate,
|
||||
context: &sigcontext::Context,
|
||||
|
@ -129,7 +129,7 @@ where
|
|||
}
|
||||
|
||||
/// Issue a burn tx
|
||||
pub fn issue_burn_tx<T, K>(
|
||||
pub fn issue_burn_tx<T: ?Sized, K>(
|
||||
wallet: &mut T,
|
||||
amount: u64,
|
||||
minimum_confirmations: u64,
|
||||
|
|
|
@ -26,13 +26,17 @@ use libtx::reward;
|
|||
use libwallet;
|
||||
use libwallet::error::{Error, ErrorKind};
|
||||
use libwallet::internal::keys;
|
||||
use libwallet::types::{BlockFees, CbData, OutputData, OutputStatus, WalletBackend, WalletClient,
|
||||
WalletInfo};
|
||||
use libwallet::types::{
|
||||
BlockFees, CbData, OutputData, OutputStatus, WalletBackend, WalletClient, WalletInfo,
|
||||
};
|
||||
use util::secp::pedersen;
|
||||
use util::{self, LOGGER};
|
||||
|
||||
/// 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
|
||||
T: WalletBackend<K>,
|
||||
K: Keychain,
|
||||
|
@ -57,7 +61,7 @@ where
|
|||
|
||||
/// Refreshes the outputs in a wallet with the latest information
|
||||
/// 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
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
|
@ -69,7 +73,7 @@ where
|
|||
|
||||
/// build a local map of wallet outputs keyed by commit
|
||||
/// 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,
|
||||
) -> Result<HashMap<pedersen::Commitment, Identifier>, Error>
|
||||
where
|
||||
|
@ -90,7 +94,7 @@ where
|
|||
}
|
||||
|
||||
/// 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_outputs: &HashMap<pedersen::Commitment, Identifier>,
|
||||
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.
|
||||
/// 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
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
|
@ -144,7 +148,7 @@ where
|
|||
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
|
||||
T: WalletBackend<K>,
|
||||
K: Keychain,
|
||||
|
@ -168,7 +172,7 @@ where
|
|||
|
||||
/// Retrieve summary info about the wallet
|
||||
/// 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
|
||||
T: WalletBackend<K> + WalletClient,
|
||||
K: Keychain,
|
||||
|
@ -209,7 +213,7 @@ where
|
|||
}
|
||||
|
||||
/// 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
|
||||
T: WalletBackend<K>,
|
||||
K: Keychain,
|
||||
|
@ -234,7 +238,7 @@ where
|
|||
|
||||
//TODO: Split up the output creation and the wallet insertion
|
||||
/// Build a coinbase output and the corresponding kernel
|
||||
pub fn receive_coinbase<T, K>(
|
||||
pub fn receive_coinbase<T: ?Sized, K>(
|
||||
wallet: &mut T,
|
||||
block_fees: &BlockFees,
|
||||
) -> Result<(Output, TxKernel, BlockFees), Error>
|
||||
|
|
|
@ -33,6 +33,19 @@ use libwallet::error::{Error, ErrorKind};
|
|||
|
||||
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:
|
||||
/// Wallets should implement this backend for their storage. All functions
|
||||
/// 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 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 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> {
|
||||
db: store::Store,
|
||||
config: WalletConfig,
|
||||
|
@ -64,6 +71,13 @@ impl<K> LMDBBackend<K> {
|
|||
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>
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
use std::cmp::min;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{Read, Write};
|
||||
use std::path::MAIN_SEPARATOR;
|
||||
use std::path::Path;
|
||||
use std::path::MAIN_SEPARATOR;
|
||||
|
||||
use blake2;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
|
Loading…
Reference in a new issue