2021-03-05 21:30:51 +03:00
// Copyright 2021 The Grin Develope;
2019-03-17 22:14:58 +03:00
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Generic implementation of owner API functions
use uuid ::Uuid ;
2019-03-26 19:02:31 +03:00
use crate ::grin_core ::core ::hash ::Hashed ;
2022-02-18 13:06:04 +03:00
use crate ::grin_core ::core ::{ Output , OutputFeatures , Transaction } ;
use crate ::grin_core ::libtx ::proof ;
2021-12-14 15:23:17 +03:00
use crate ::grin_keychain ::ViewKey ;
2019-08-06 14:50:41 +03:00
use crate ::grin_util ::secp ::key ::SecretKey ;
2019-11-06 13:04:42 +03:00
use crate ::grin_util ::Mutex ;
2021-12-14 15:23:17 +03:00
use crate ::grin_util ::ToHex ;
2020-05-22 13:48:11 +03:00
use crate ::util ::{ OnionV3Address , OnionV3AddressError } ;
2019-03-17 22:14:58 +03:00
2019-11-18 13:49:51 +03:00
use crate ::api_impl ::owner_updater ::StatusMessage ;
2022-02-18 13:06:04 +03:00
use crate ::grin_keychain ::{ BlindingFactor , Identifier , Keychain , SwitchCommitmentType } ;
2019-11-06 13:04:42 +03:00
use crate ::internal ::{ keys , scan , selection , tx , updater } ;
2020-05-19 13:19:03 +03:00
use crate ::slate ::{ PaymentInfo , Slate , SlateState } ;
2020-02-14 12:16:43 +03:00
use crate ::types ::{ AcctPathMapping , NodeClient , TxLogEntry , WalletBackend , WalletInfo } ;
2022-07-28 12:21:45 +03:00
use crate ::Error ;
2019-05-01 22:12:23 +03:00
use crate ::{
2022-02-18 13:06:04 +03:00
address , wallet_lock , BuiltOutput , InitTxArgs , IssueInvoiceTxArgs , NodeHeightResult ,
OutputCommitMapping , PaymentProof , ScannedBlockInfo , Slatepack , SlatepackAddress , Slatepacker ,
SlatepackerArgs , TxLogEntryType , ViewWallet , WalletInitStatus , WalletInst , WalletLCProvider ,
2019-05-01 22:12:23 +03:00
} ;
2019-11-28 17:34:27 +03:00
use ed25519_dalek ::PublicKey as DalekPublicKey ;
2020-01-22 16:16:24 +03:00
use ed25519_dalek ::SecretKey as DalekSecretKey ;
2020-08-10 16:42:53 +03:00
use ed25519_dalek ::Verifier ;
2019-11-28 17:34:27 +03:00
2020-11-26 22:46:03 +03:00
use std ::convert ::{ TryFrom , TryInto } ;
2019-11-18 13:49:51 +03:00
use std ::sync ::mpsc ::Sender ;
2019-11-06 13:04:42 +03:00
use std ::sync ::Arc ;
2019-03-17 22:14:58 +03:00
/// List of accounts
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
pub fn accounts < ' a , T : ? Sized , C , K > ( w : & mut T ) -> Result < Vec < AcctPathMapping > , Error >
2019-03-17 22:14:58 +03:00
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
keys ::accounts ( & mut * w )
}
/// new account path
2019-08-06 14:50:41 +03:00
pub fn create_account_path < ' a , T : ? Sized , C , K > (
w : & mut T ,
keychain_mask : Option < & SecretKey > ,
label : & str ,
) -> Result < Identifier , Error >
2019-03-17 22:14:58 +03:00
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2019-08-06 14:50:41 +03:00
keys ::new_acct_path ( & mut * w , keychain_mask , label )
2019-03-17 22:14:58 +03:00
}
/// set active account
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
pub fn set_active_account < ' a , T : ? Sized , C , K > ( w : & mut T , label : & str ) -> Result < ( ) , Error >
2019-03-17 22:14:58 +03:00
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
w . set_parent_key_id_by_name ( label )
}
2021-12-14 15:23:17 +03:00
/// Hash of the wallet root public key
pub fn get_rewind_hash < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
keychain_mask : Option < & SecretKey > ,
) -> Result < String , Error >
where
L : WalletLCProvider < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
wallet_lock! ( wallet_inst , w ) ;
let keychain = w . keychain ( keychain_mask ) ? ;
let root_public_key = keychain . public_root_key ( ) ;
let rewind_hash = ViewKey ::rewind_hash ( keychain . secp ( ) , root_public_key ) . to_hex ( ) ;
Ok ( rewind_hash )
}
2020-05-28 10:17:51 +03:00
/// Retrieve the slatepack address for the current parent key at
2019-11-28 17:34:27 +03:00
/// the given index
2020-05-28 10:17:51 +03:00
pub fn get_slatepack_address < ' a , L , C , K > (
2019-11-28 17:34:27 +03:00
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
keychain_mask : Option < & SecretKey > ,
index : u32 ,
2020-05-28 10:17:51 +03:00
) -> Result < SlatepackAddress , Error >
2019-11-28 17:34:27 +03:00
where
L : WalletLCProvider < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
wallet_lock! ( wallet_inst , w ) ;
let parent_key_id = w . parent_key_id ( ) ;
let k = w . keychain ( keychain_mask ) ? ;
let sec_addr_key = address ::address_from_derivation_path ( & k , & parent_key_id , index ) ? ;
2020-05-28 10:17:51 +03:00
SlatepackAddress ::try_from ( & sec_addr_key )
2019-11-28 17:34:27 +03:00
}
2020-05-22 13:48:11 +03:00
/// Retrieve the decryption key for the current parent key
/// the given index
2020-05-28 10:17:51 +03:00
pub fn get_slatepack_secret_key < ' a , L , C , K > (
2020-05-22 13:48:11 +03:00
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
keychain_mask : Option < & SecretKey > ,
index : u32 ,
) -> Result < DalekSecretKey , Error >
where
L : WalletLCProvider < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
wallet_lock! ( wallet_inst , w ) ;
let parent_key_id = w . parent_key_id ( ) ;
let k = w . keychain ( keychain_mask ) ? ;
let sec_addr_key = address ::address_from_derivation_path ( & k , & parent_key_id , index ) ? ;
let d_skey = match DalekSecretKey ::from_bytes ( & sec_addr_key . 0 ) {
Ok ( k ) = > k ,
Err ( e ) = > {
return Err ( OnionV3AddressError ::InvalidPrivateKey ( format! (
" Unable to create secret key: {} " ,
e
) )
. into ( ) ) ;
}
} ;
Ok ( d_skey )
}
2020-05-28 10:17:51 +03:00
/// Create a slatepack message from the given slate
pub fn create_slatepack_message < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
keychain_mask : Option < & SecretKey > ,
slate : & Slate ,
sender_index : Option < u32 > ,
recipients : Vec < SlatepackAddress > ,
) -> Result < String , Error >
where
L : WalletLCProvider < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
let sender = match sender_index {
Some ( i ) = > Some ( get_slatepack_address ( wallet_inst , keychain_mask , i ) ? ) ,
None = > None ,
} ;
let packer = Slatepacker ::new ( SlatepackerArgs {
sender ,
recipients ,
dec_key : None ,
} ) ;
let slatepack = packer . create_slatepack ( slate ) ? ;
packer . armor_slatepack ( & slatepack )
}
/// Unpack a slate from the given slatepack message,
/// optionally decrypting
pub fn slate_from_slatepack_message < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
keychain_mask : Option < & SecretKey > ,
slatepack : String ,
secret_indices : Vec < u32 > ,
) -> Result < Slate , Error >
where
L : WalletLCProvider < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
if secret_indices . is_empty ( ) {
let packer = Slatepacker ::new ( SlatepackerArgs {
sender : None ,
recipients : vec ! [ ] ,
dec_key : None ,
} ) ;
2020-08-03 12:29:54 +03:00
let slatepack = packer . deser_slatepack ( slatepack . as_bytes ( ) , true ) ? ;
2020-05-28 10:17:51 +03:00
return packer . get_slate ( & slatepack ) ;
} else {
for index in secret_indices {
let dec_key = Some ( get_slatepack_secret_key (
wallet_inst . clone ( ) ,
keychain_mask ,
index ,
) ? ) ;
let packer = Slatepacker ::new ( SlatepackerArgs {
sender : None ,
recipients : vec ! [ ] ,
dec_key : ( & dec_key ) . as_ref ( ) ,
} ) ;
2020-08-03 12:29:54 +03:00
let res = packer . deser_slatepack ( slatepack . as_bytes ( ) , true ) ;
2020-05-28 10:17:51 +03:00
let slatepack = match res {
Ok ( sp ) = > sp ,
Err ( _ ) = > {
continue ;
}
} ;
return packer . get_slate ( & slatepack ) ;
}
2022-07-28 12:21:45 +03:00
return Err ( Error ::SlatepackDecryption (
2020-05-28 10:17:51 +03:00
" Could not decrypt slatepack with any provided index on the address derivation path "
2022-07-28 12:21:45 +03:00
. to_owned ( ) ,
2020-05-28 10:17:51 +03:00
)
. into ( ) ) ;
}
}
/// Decode a slatepack message, to allow viewing
2020-06-15 16:39:52 +03:00
/// Will decrypt if possible, otherwise will return
/// undecrypted slatepack
pub fn decode_slatepack_message < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
keychain_mask : Option < & SecretKey > ,
slatepack : String ,
secret_indices : Vec < u32 > ,
) -> Result < Slatepack , Error >
where
L : WalletLCProvider < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
2020-05-28 10:17:51 +03:00
let packer = Slatepacker ::new ( SlatepackerArgs {
sender : None ,
recipients : vec ! [ ] ,
dec_key : None ,
} ) ;
2020-06-15 16:39:52 +03:00
if secret_indices . is_empty ( ) {
2020-08-03 12:29:54 +03:00
packer . deser_slatepack ( slatepack . as_bytes ( ) , false )
2020-06-15 16:39:52 +03:00
} else {
for index in secret_indices {
let dec_key = Some ( get_slatepack_secret_key (
wallet_inst . clone ( ) ,
keychain_mask ,
index ,
) ? ) ;
let packer = Slatepacker ::new ( SlatepackerArgs {
sender : None ,
recipients : vec ! [ ] ,
dec_key : ( & dec_key ) . as_ref ( ) ,
} ) ;
2020-08-03 12:29:54 +03:00
let res = packer . deser_slatepack ( slatepack . as_bytes ( ) , true ) ;
2020-06-15 16:39:52 +03:00
let slatepack = match res {
Ok ( sp ) = > sp ,
Err ( _ ) = > {
continue ;
}
} ;
return Ok ( slatepack ) ;
}
2020-08-03 12:29:54 +03:00
packer . deser_slatepack ( slatepack . as_bytes ( ) , false )
2020-06-15 16:39:52 +03:00
}
2020-05-28 10:17:51 +03:00
}
2019-03-17 22:14:58 +03:00
/// retrieve outputs
2019-11-06 13:04:42 +03:00
pub fn retrieve_outputs < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
2019-11-18 13:49:51 +03:00
status_send_channel : & Option < Sender < StatusMessage > > ,
2019-03-17 22:14:58 +03:00
include_spent : bool ,
refresh_from_node : bool ,
tx_id : Option < u32 > ,
2019-03-22 15:03:25 +03:00
) -> Result < ( bool , Vec < OutputCommitMapping > ) , Error >
2019-03-17 22:14:58 +03:00
where
2019-11-06 13:04:42 +03:00
L : WalletLCProvider < ' a , C , K > ,
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2020-02-07 12:39:56 +03:00
let validated = if refresh_from_node {
update_wallet_state (
2019-11-18 13:49:51 +03:00
wallet_inst . clone ( ) ,
keychain_mask ,
status_send_channel ,
false ,
2020-02-07 12:39:56 +03:00
) ?
} else {
false
} ;
2019-03-17 22:14:58 +03:00
2019-11-06 13:04:42 +03:00
wallet_lock! ( wallet_inst , w ) ;
let parent_key_id = w . parent_key_id ( ) ;
2019-03-17 22:14:58 +03:00
Ok ( (
validated ,
2019-08-06 14:50:41 +03:00
updater ::retrieve_outputs (
2019-11-06 13:04:42 +03:00
& mut * * w ,
2019-08-06 14:50:41 +03:00
keychain_mask ,
include_spent ,
tx_id ,
Some ( & parent_key_id ) ,
) ? ,
2019-03-17 22:14:58 +03:00
) )
}
/// Retrieve txs
2019-11-06 13:04:42 +03:00
pub fn retrieve_txs < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
2019-11-18 13:49:51 +03:00
status_send_channel : & Option < Sender < StatusMessage > > ,
2019-03-17 22:14:58 +03:00
refresh_from_node : bool ,
tx_id : Option < u32 > ,
tx_slate_id : Option < Uuid > ,
) -> Result < ( bool , Vec < TxLogEntry > ) , Error >
where
2019-11-06 13:04:42 +03:00
L : WalletLCProvider < ' a , C , K > ,
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2020-02-07 12:39:56 +03:00
let validated = if refresh_from_node {
update_wallet_state (
2019-11-18 13:49:51 +03:00
wallet_inst . clone ( ) ,
keychain_mask ,
status_send_channel ,
false ,
2020-02-07 12:39:56 +03:00
) ?
} else {
false
} ;
2019-03-17 22:14:58 +03:00
2019-11-06 13:04:42 +03:00
wallet_lock! ( wallet_inst , w ) ;
let parent_key_id = w . parent_key_id ( ) ;
let txs = updater ::retrieve_txs ( & mut * * w , tx_id , tx_slate_id , Some ( & parent_key_id ) , false ) ? ;
2019-09-24 11:56:10 +03:00
Ok ( ( validated , txs ) )
2019-03-17 22:14:58 +03:00
}
/// Retrieve summary info
2019-11-06 13:04:42 +03:00
pub fn retrieve_summary_info < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
2019-11-18 13:49:51 +03:00
status_send_channel : & Option < Sender < StatusMessage > > ,
2019-03-17 22:14:58 +03:00
refresh_from_node : bool ,
minimum_confirmations : u64 ,
) -> Result < ( bool , WalletInfo ) , Error >
where
2019-11-06 13:04:42 +03:00
L : WalletLCProvider < ' a , C , K > ,
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2020-02-07 12:39:56 +03:00
let validated = if refresh_from_node {
update_wallet_state (
2019-11-18 13:49:51 +03:00
wallet_inst . clone ( ) ,
keychain_mask ,
status_send_channel ,
false ,
2020-02-07 12:39:56 +03:00
) ?
} else {
false
} ;
2019-03-17 22:14:58 +03:00
2019-11-06 13:04:42 +03:00
wallet_lock! ( wallet_inst , w ) ;
let parent_key_id = w . parent_key_id ( ) ;
let wallet_info = updater ::retrieve_info ( & mut * * w , & parent_key_id , minimum_confirmations ) ? ;
2019-03-17 22:14:58 +03:00
Ok ( ( validated , wallet_info ) )
}
2020-01-22 16:16:24 +03:00
/// Retrieve payment proof
pub fn retrieve_payment_proof < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
keychain_mask : Option < & SecretKey > ,
status_send_channel : & Option < Sender < StatusMessage > > ,
refresh_from_node : bool ,
tx_id : Option < u32 > ,
tx_slate_id : Option < Uuid > ,
) -> Result < PaymentProof , Error >
where
L : WalletLCProvider < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
if tx_id . is_none ( ) & & tx_slate_id . is_none ( ) {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProofRetrieval (
" Transaction ID or Slate UUID must be specified " . to_owned ( ) ,
) ) ;
2020-01-22 16:16:24 +03:00
}
if refresh_from_node {
2020-02-07 12:39:56 +03:00
update_wallet_state (
2020-01-22 16:16:24 +03:00
wallet_inst . clone ( ) ,
keychain_mask ,
status_send_channel ,
false ,
2020-02-07 12:39:56 +03:00
) ?
} else {
false
} ;
2020-01-22 16:16:24 +03:00
let txs = retrieve_txs (
wallet_inst . clone ( ) ,
keychain_mask ,
status_send_channel ,
refresh_from_node ,
tx_id ,
tx_slate_id ,
) ? ;
if txs . 1. len ( ) ! = 1 {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProofRetrieval (
" Transaction doesn't exist " . to_owned ( ) ,
) ) ;
2020-01-22 16:16:24 +03:00
}
// Pull out all needed fields, returning an error if they're not present
let tx = txs . 1 [ 0 ] . clone ( ) ;
let proof = match tx . payment_proof {
Some ( p ) = > p ,
None = > {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProofRetrieval (
" Transaction does not contain a payment proof " . to_owned ( ) ,
) ) ;
2020-01-22 16:16:24 +03:00
}
} ;
let amount = if tx . amount_credited > = tx . amount_debited {
tx . amount_credited - tx . amount_debited
} else {
let fee = match tx . fee {
2021-05-19 21:27:42 +03:00
Some ( f ) = > f . fee ( ) , // apply fee mask past HF4
2020-01-22 16:16:24 +03:00
None = > 0 ,
} ;
tx . amount_debited - tx . amount_credited - fee
} ;
let excess = match tx . kernel_excess {
Some ( e ) = > e ,
None = > {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProofRetrieval (
" Transaction does not contain kernel excess " . to_owned ( ) ,
) ) ;
2020-01-22 16:16:24 +03:00
}
} ;
let r_sig = match proof . receiver_signature {
Some ( e ) = > e ,
None = > {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProofRetrieval (
" Proof does not contain receiver signature " . to_owned ( ) ,
) ) ;
2020-01-22 16:16:24 +03:00
}
} ;
let s_sig = match proof . sender_signature {
Some ( e ) = > e ,
None = > {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProofRetrieval (
" Proof does not contain sender signature " . to_owned ( ) ,
) ) ;
2020-01-22 16:16:24 +03:00
}
} ;
Ok ( PaymentProof {
amount : amount ,
excess : excess ,
2020-05-28 10:17:51 +03:00
recipient_address : SlatepackAddress ::new ( & proof . receiver_address ) ,
2020-01-22 16:16:24 +03:00
recipient_sig : r_sig ,
2020-05-28 10:17:51 +03:00
sender_address : SlatepackAddress ::new ( & proof . sender_address ) ,
2020-01-22 16:16:24 +03:00
sender_sig : s_sig ,
} )
}
2019-03-17 22:14:58 +03:00
/// Initiate tx as sender
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
pub fn init_send_tx < ' a , T : ? Sized , C , K > (
2019-03-17 22:14:58 +03:00
w : & mut T ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
2019-03-29 19:00:02 +03:00
args : InitTxArgs ,
2019-03-22 15:03:25 +03:00
use_test_rng : bool ,
2019-03-17 22:14:58 +03:00
) -> Result < Slate , Error >
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2020-11-19 14:54:49 +03:00
let parent_key_id = match & args . src_acct_name {
2019-03-17 22:14:58 +03:00
Some ( d ) = > {
2020-11-19 14:54:49 +03:00
let pm = w . get_acct_path ( d . clone ( ) ) ? ;
2019-03-17 22:14:58 +03:00
match pm {
Some ( p ) = > p . path ,
None = > w . parent_key_id ( ) ,
}
}
None = > w . parent_key_id ( ) ,
} ;
2020-05-19 13:19:03 +03:00
let mut slate = tx ::new_tx_slate (
& mut * w ,
args . amount ,
false ,
2 ,
use_test_rng ,
args . ttl_blocks ,
) ? ;
2019-03-17 22:14:58 +03:00
2020-05-19 13:19:03 +03:00
if let Some ( v ) = args . target_slate_version {
slate . version_info . version = v ;
} ;
2019-03-29 19:00:02 +03:00
// if we just want to estimate, don't save a context, just send the results
// back
if let Some ( true ) = args . estimate_only {
let ( total , fee ) = tx ::estimate_send_tx (
& mut * w ,
2019-08-06 14:50:41 +03:00
keychain_mask ,
2019-03-29 19:00:02 +03:00
args . amount ,
2022-07-26 12:15:53 +03:00
args . amount_includes_fee . unwrap_or ( false ) ,
2019-03-29 19:00:02 +03:00
args . minimum_confirmations ,
args . max_outputs as usize ,
args . num_change_outputs as usize ,
args . selection_strategy_is_use_all ,
& parent_key_id ,
) ? ;
slate . amount = total ;
2020-11-26 22:46:03 +03:00
slate . fee_fields = fee . try_into ( ) . unwrap ( ) ;
2019-03-29 19:00:02 +03:00
return Ok ( slate ) ;
}
2019-03-17 22:14:58 +03:00
2020-05-19 13:19:03 +03:00
let height = w . w2n_client ( ) . get_chain_tip ( ) ? . 0 ;
2020-11-19 14:54:49 +03:00
let mut context = if args . late_lock . unwrap_or ( false ) {
tx ::create_late_lock_context (
& mut * w ,
keychain_mask ,
& mut slate ,
height ,
& args ,
& parent_key_id ,
use_test_rng ,
) ?
} else {
tx ::add_inputs_to_slate (
& mut * w ,
keychain_mask ,
& mut slate ,
height ,
args . minimum_confirmations ,
args . max_outputs as usize ,
args . num_change_outputs as usize ,
args . selection_strategy_is_use_all ,
& parent_key_id ,
true ,
use_test_rng ,
2022-07-26 12:15:53 +03:00
args . amount_includes_fee . unwrap_or ( false ) ,
2020-11-19 14:54:49 +03:00
) ?
} ;
2019-03-17 22:14:58 +03:00
2019-11-28 17:34:27 +03:00
// Payment Proof, add addresses to slate and save address
// TODO: Note we only use single derivation path for now,
// probably want to allow sender to specify which one
let deriv_path = 0 u32 ;
if let Some ( a ) = args . payment_proof_recipient_address {
let k = w . keychain ( keychain_mask ) ? ;
let sec_addr_key = address ::address_from_derivation_path ( & k , & parent_key_id , deriv_path ) ? ;
2020-01-24 16:02:09 +03:00
let sender_address = OnionV3Address ::from_private ( & sec_addr_key . 0 ) ? ;
2019-11-28 17:34:27 +03:00
slate . payment_proof = Some ( PaymentInfo {
2020-01-24 16:02:09 +03:00
sender_address : sender_address . to_ed25519 ( ) ? ,
2020-05-28 10:17:51 +03:00
receiver_address : a . pub_key ,
2019-11-28 17:34:27 +03:00
receiver_signature : None ,
} ) ;
context . payment_proof_derivation_index = Some ( deriv_path ) ;
}
2019-03-17 22:14:58 +03:00
// Save the aggsig context in our DB for when we
// recieve the transaction back
{
2019-08-06 14:50:41 +03:00
let mut batch = w . batch ( keychain_mask ) ? ;
2020-05-19 13:19:03 +03:00
batch . save_private_context ( slate . id . as_bytes ( ) , & context ) ? ;
2019-03-17 22:14:58 +03:00
batch . commit ( ) ? ;
}
2020-05-19 13:19:03 +03:00
2020-07-31 12:33:45 +03:00
slate . compact ( ) ? ;
2019-11-28 17:34:27 +03:00
2019-03-17 22:14:58 +03:00
Ok ( slate )
}
2019-05-01 22:12:23 +03:00
/// Initiate a transaction as the recipient (invoicing)
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
pub fn issue_invoice_tx < ' a , T : ? Sized , C , K > (
2019-05-01 22:12:23 +03:00
w : & mut T ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
2019-05-01 22:12:23 +03:00
args : IssueInvoiceTxArgs ,
use_test_rng : bool ,
) -> Result < Slate , Error >
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-05-01 22:12:23 +03:00
{
let parent_key_id = match args . dest_acct_name {
Some ( d ) = > {
let pm = w . get_acct_path ( d ) ? ;
match pm {
Some ( p ) = > p . path ,
None = > w . parent_key_id ( ) ,
}
}
None = > w . parent_key_id ( ) ,
} ;
2020-05-19 13:19:03 +03:00
let mut slate = tx ::new_tx_slate ( & mut * w , args . amount , true , 2 , use_test_rng , None ) ? ;
let height = w . w2n_client ( ) . get_chain_tip ( ) ? . 0 ;
2019-05-01 22:12:23 +03:00
let context = tx ::add_output_to_slate (
& mut * w ,
2019-08-06 14:50:41 +03:00
keychain_mask ,
2019-05-01 22:12:23 +03:00
& mut slate ,
2020-05-19 13:19:03 +03:00
height ,
2019-05-01 22:12:23 +03:00
& parent_key_id ,
true ,
use_test_rng ,
) ? ;
2020-05-19 13:19:03 +03:00
if let Some ( v ) = args . target_slate_version {
slate . version_info . version = v ;
} ;
2019-05-01 22:12:23 +03:00
// Save the aggsig context in our DB for when we
// recieve the transaction back
{
2019-08-06 14:50:41 +03:00
let mut batch = w . batch ( keychain_mask ) ? ;
2020-05-19 13:19:03 +03:00
batch . save_private_context ( slate . id . as_bytes ( ) , & context ) ? ;
2019-05-01 22:12:23 +03:00
batch . commit ( ) ? ;
}
2020-07-31 12:33:45 +03:00
slate . compact ( ) ? ;
2019-05-31 10:33:23 +03:00
2019-05-01 22:12:23 +03:00
Ok ( slate )
}
/// Receive an invoice tx, essentially adding inputs to whatever
/// output was specified
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
pub fn process_invoice_tx < ' a , T : ? Sized , C , K > (
2019-05-01 22:12:23 +03:00
w : & mut T ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
2019-05-01 22:12:23 +03:00
slate : & Slate ,
args : InitTxArgs ,
use_test_rng : bool ,
) -> Result < Slate , Error >
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-05-01 22:12:23 +03:00
{
let mut ret_slate = slate . clone ( ) ;
2019-12-02 16:54:57 +03:00
check_ttl ( w , & ret_slate ) ? ;
2019-05-01 22:12:23 +03:00
let parent_key_id = match args . src_acct_name {
Some ( d ) = > {
2020-02-07 12:39:56 +03:00
let pm = w . get_acct_path ( d ) ? ;
2019-05-01 22:12:23 +03:00
match pm {
Some ( p ) = > p . path ,
None = > w . parent_key_id ( ) ,
}
}
None = > w . parent_key_id ( ) ,
} ;
// Don't do this multiple times
let tx = updater ::retrieve_txs (
& mut * w ,
None ,
Some ( ret_slate . id ) ,
Some ( & parent_key_id ) ,
use_test_rng ,
) ? ;
for t in & tx {
if t . tx_type = = TxLogEntryType ::TxSent {
2022-07-28 12:21:45 +03:00
return Err ( Error ::TransactionAlreadyReceived ( ret_slate . id . to_string ( ) ) ) ;
2019-05-01 22:12:23 +03:00
}
}
2020-05-19 13:19:03 +03:00
let height = w . w2n_client ( ) . get_chain_tip ( ) ? . 0 ;
2019-05-21 12:00:19 +03:00
2019-12-02 16:54:57 +03:00
// update ttl if desired
if let Some ( b ) = args . ttl_blocks {
2020-05-19 13:19:03 +03:00
ret_slate . ttl_cutoff_height = height + b ;
}
// if this is compact mode, we need to create the transaction now
2020-09-07 20:04:07 +03:00
ret_slate . tx = Some ( Slate ::empty_transaction ( ) ) ;
2019-12-02 16:54:57 +03:00
2020-05-19 13:19:03 +03:00
// if self sending, make sure to store 'initiator' keys
let context_res = w . get_private_context ( keychain_mask , slate . id . as_bytes ( ) ) ;
let mut context = tx ::add_inputs_to_slate (
2019-05-01 22:12:23 +03:00
& mut * w ,
2019-08-06 14:50:41 +03:00
keychain_mask ,
2019-05-01 22:12:23 +03:00
& mut ret_slate ,
2020-05-19 13:19:03 +03:00
height ,
2019-05-01 22:12:23 +03:00
args . minimum_confirmations ,
args . max_outputs as usize ,
args . num_change_outputs as usize ,
args . selection_strategy_is_use_all ,
& parent_key_id ,
false ,
use_test_rng ,
2022-07-26 12:15:53 +03:00
false ,
2019-05-01 22:12:23 +03:00
) ? ;
2020-05-19 13:19:03 +03:00
let keychain = w . keychain ( keychain_mask ) ? ;
2020-11-19 14:54:49 +03:00
// Add our contribution to the offset
if context_res . is_ok ( ) {
// Self sending: don't correct for inputs and outputs
// here, as we will do it during finalization.
let mut tmp_context = context . clone ( ) ;
tmp_context . input_ids . clear ( ) ;
tmp_context . output_ids . clear ( ) ;
ret_slate . adjust_offset ( & keychain , & tmp_context ) ? ;
} else {
ret_slate . adjust_offset ( & keychain , & context ) ? ;
}
2020-05-19 13:19:03 +03:00
// needs to be stored as we're removing sig data for return trip. this needs to be present
// when locking transaction context and updating tx log with excess later
context . calculated_excess = Some ( ret_slate . calc_excess ( keychain . secp ( ) ) ? ) ;
// if self-sending, merge contexts
if let Ok ( c ) = context_res {
context . initial_sec_key = c . initial_sec_key ;
context . initial_sec_nonce = c . initial_sec_nonce ;
context . fee = c . fee ;
context . amount = c . amount ;
for o in c . output_ids . iter ( ) {
context . output_ids . push ( o . clone ( ) ) ;
}
for i in c . input_ids . iter ( ) {
context . input_ids . push ( i . clone ( ) ) ;
}
}
2020-07-31 12:33:45 +03:00
selection ::repopulate_tx ( & mut * w , keychain_mask , & mut ret_slate , & context , false ) ? ;
2020-05-19 13:19:03 +03:00
2019-05-01 22:12:23 +03:00
// Save the aggsig context in our DB for when we
// recieve the transaction back
{
2019-08-06 14:50:41 +03:00
let mut batch = w . batch ( keychain_mask ) ? ;
2020-05-19 13:19:03 +03:00
batch . save_private_context ( slate . id . as_bytes ( ) , & context ) ? ;
2019-05-01 22:12:23 +03:00
batch . commit ( ) ? ;
}
2020-05-19 13:19:03 +03:00
// Can remove amount as well as other sig data now
2020-07-31 12:33:45 +03:00
ret_slate . amount = 0 ;
ret_slate . remove_other_sigdata ( & keychain , & context . sec_nonce , & context . sec_key ) ? ;
2019-05-31 10:33:23 +03:00
2020-05-19 13:19:03 +03:00
ret_slate . state = SlateState ::Invoice2 ;
2019-05-01 22:12:23 +03:00
Ok ( ret_slate )
}
2019-03-17 22:14:58 +03:00
/// Lock sender outputs
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
pub fn tx_lock_outputs < ' a , T : ? Sized , C , K > (
2019-05-23 18:27:57 +03:00
w : & mut T ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
2019-05-23 18:27:57 +03:00
slate : & Slate ,
) -> Result < ( ) , Error >
2019-03-17 22:14:58 +03:00
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2020-05-19 13:19:03 +03:00
let context = w . get_private_context ( keychain_mask , slate . id . as_bytes ( ) ) ? ;
let mut excess_override = None ;
2020-07-31 12:33:45 +03:00
let mut sl = slate . clone ( ) ;
if sl . tx = = None {
2020-09-07 20:04:07 +03:00
sl . tx = Some ( Slate ::empty_transaction ( ) ) ;
2020-05-19 13:19:03 +03:00
selection ::repopulate_tx ( & mut * w , keychain_mask , & mut sl , & context , true ) ? ;
2020-07-31 12:33:45 +03:00
}
if slate . participant_data . len ( ) = = 1 {
2020-05-19 13:19:03 +03:00
// purely for invoice workflow, payer needs the excess back temporarily for storage
excess_override = context . calculated_excess ;
}
2020-07-31 12:33:45 +03:00
2020-05-19 13:19:03 +03:00
let height = w . w2n_client ( ) . get_chain_tip ( ) ? . 0 ;
selection ::lock_tx_context (
& mut * w ,
keychain_mask ,
& sl ,
height ,
& context ,
excess_override ,
)
2019-03-17 22:14:58 +03:00
}
/// Finalize slate
2019-08-06 14:50:41 +03:00
pub fn finalize_tx < ' a , T : ? Sized , C , K > (
w : & mut T ,
keychain_mask : Option < & SecretKey > ,
slate : & Slate ,
) -> Result < Slate , Error >
2019-03-17 22:14:58 +03:00
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2019-03-22 15:03:25 +03:00
let mut sl = slate . clone ( ) ;
2019-12-02 16:54:57 +03:00
check_ttl ( w , & sl ) ? ;
2020-11-19 14:54:49 +03:00
let mut context = w . get_private_context ( keychain_mask , sl . id . as_bytes ( ) ) ? ;
let keychain = w . keychain ( keychain_mask ) ? ;
2019-11-28 17:34:27 +03:00
let parent_key_id = w . parent_key_id ( ) ;
2020-05-19 13:19:03 +03:00
2020-11-19 14:54:49 +03:00
if let Some ( args ) = context . late_lock_args . take ( ) {
// Transaction was late locked, select inputs+change now
// and insert into original context
let current_height = w . w2n_client ( ) . get_chain_tip ( ) ? . 0 ;
let mut temp_sl =
tx ::new_tx_slate ( & mut * w , context . amount , false , 2 , false , args . ttl_blocks ) ? ;
let temp_context = selection ::build_send_tx (
w ,
& keychain ,
keychain_mask ,
& mut temp_sl ,
current_height ,
args . minimum_confirmations ,
args . max_outputs as usize ,
args . num_change_outputs as usize ,
args . selection_strategy_is_use_all ,
2021-05-19 21:27:42 +03:00
Some ( context . fee . map ( | f | f . fee ( ) ) . unwrap_or ( 0 ) ) ,
2020-11-19 14:54:49 +03:00
parent_key_id . clone ( ) ,
false ,
true ,
2022-07-26 12:15:53 +03:00
false ,
2020-11-19 14:54:49 +03:00
) ? ;
// Add inputs and outputs to original context
context . input_ids = temp_context . input_ids ;
context . output_ids = temp_context . output_ids ;
// Store the updated context
{
let mut batch = w . batch ( keychain_mask ) ? ;
batch . save_private_context ( sl . id . as_bytes ( ) , & context ) ? ;
batch . commit ( ) ? ;
}
// Now do the actual locking
tx_lock_outputs ( w , keychain_mask , & sl ) ? ;
}
// Add our contribution to the offset
sl . adjust_offset ( & keychain , & context ) ? ;
2020-05-19 13:19:03 +03:00
2020-07-31 12:33:45 +03:00
selection ::repopulate_tx ( & mut * w , keychain_mask , & mut sl , & context , true ) ? ;
2020-05-19 13:19:03 +03:00
tx ::complete_tx ( & mut * w , keychain_mask , & mut sl , & context ) ? ;
2020-01-22 16:16:24 +03:00
tx ::verify_slate_payment_proof ( & mut * w , keychain_mask , & parent_key_id , & context , & sl ) ? ;
2020-02-07 12:39:56 +03:00
tx ::update_stored_tx ( & mut * w , keychain_mask , & context , & sl , false ) ? ;
2019-03-17 22:14:58 +03:00
{
2019-08-06 14:50:41 +03:00
let mut batch = w . batch ( keychain_mask ) ? ;
2020-05-19 13:19:03 +03:00
batch . delete_private_context ( sl . id . as_bytes ( ) ) ? ;
2019-03-17 22:14:58 +03:00
batch . commit ( ) ? ;
}
2020-05-19 13:19:03 +03:00
sl . state = SlateState ::Standard3 ;
2020-07-31 12:33:45 +03:00
sl . amount = 0 ;
2019-03-22 15:03:25 +03:00
Ok ( sl )
2019-03-17 22:14:58 +03:00
}
/// cancel tx
2019-11-06 13:04:42 +03:00
pub fn cancel_tx < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
2019-11-18 13:49:51 +03:00
status_send_channel : & Option < Sender < StatusMessage > > ,
2019-03-17 22:14:58 +03:00
tx_id : Option < u32 > ,
tx_slate_id : Option < Uuid > ,
) -> Result < ( ) , Error >
where
2019-11-06 13:04:42 +03:00
L : WalletLCProvider < ' a , C , K > ,
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2019-11-18 13:49:51 +03:00
if ! update_wallet_state (
wallet_inst . clone ( ) ,
keychain_mask ,
status_send_channel ,
false ,
) ? {
2022-07-28 12:21:45 +03:00
return Err ( Error ::TransactionCancellationError (
2019-03-17 22:14:58 +03:00
" Can't contact running Grin node. Not Cancelling. " ,
2022-07-28 12:21:45 +03:00
) ) ;
2019-03-17 22:14:58 +03:00
}
2019-11-06 13:04:42 +03:00
wallet_lock! ( wallet_inst , w ) ;
let parent_key_id = w . parent_key_id ( ) ;
tx ::cancel_tx ( & mut * * w , keychain_mask , & parent_key_id , tx_id , tx_slate_id )
2019-03-17 22:14:58 +03:00
}
/// get stored tx
2020-11-26 22:46:03 +03:00
/// crashes if stored tx has total fees exceeding 2^40 nanogrin
2020-06-25 12:06:04 +03:00
pub fn get_stored_tx < ' a , T : ? Sized , C , K > (
w : & T ,
tx_id : Option < u32 > ,
slate_id : Option < & Uuid > ,
) -> Result < Option < Slate > , Error >
2019-03-17 22:14:58 +03:00
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2020-06-25 12:06:04 +03:00
let mut uuid = None ;
if let Some ( i ) = tx_id {
let tx = w . tx_log_iter ( ) . find ( | t | t . id = = i ) ;
if let Some ( t ) = tx {
uuid = t . tx_slate_id ;
}
}
if uuid . is_none ( ) {
if let Some ( sid ) = slate_id {
uuid = Some ( sid . to_owned ( ) ) ;
}
}
let id = match uuid {
Some ( u ) = > u ,
None = > {
2022-07-28 12:21:45 +03:00
return Err ( Error ::StoredTx (
2020-06-25 12:06:04 +03:00
" Both the provided Transaction Id and Slate UUID are invalid. " . to_owned ( ) ,
2022-07-28 12:21:45 +03:00
) ) ;
2020-06-25 12:06:04 +03:00
}
} ;
let tx_res = w . get_stored_tx ( & format! ( " {} " , id ) ) ? ;
match tx_res {
Some ( tx ) = > {
let mut slate = Slate ::blank ( 2 , false ) ;
slate . tx = Some ( tx . clone ( ) ) ;
2021-05-19 21:27:42 +03:00
slate . fee_fields = tx . aggregate_fee_fields ( ) . unwrap ( ) ; // apply fee mask past HF4
2021-03-17 17:51:53 +03:00
slate . id = id ;
2020-06-25 12:06:04 +03:00
slate . offset = tx . offset ;
slate . state = SlateState ::Standard3 ;
Ok ( Some ( slate ) )
}
None = > Ok ( None ) ,
}
2019-03-17 22:14:58 +03:00
}
/// Posts a transaction to the chain
/// take a client impl instead of wallet so as not to have to lock the wallet
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
pub fn post_tx < ' a , C > ( client : & C , tx : & Transaction , fluff : bool ) -> Result < ( ) , Error >
2019-03-17 22:14:58 +03:00
where
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
C : NodeClient + ' a ,
2019-03-17 22:14:58 +03:00
{
2020-02-14 12:16:43 +03:00
let res = client . post_tx ( tx , fluff ) ;
2019-03-17 22:14:58 +03:00
if let Err ( e ) = res {
error! ( " api: post_tx: failed with error: {} " , e ) ;
Err ( e )
} else {
debug! (
" api: post_tx: successfully posted tx: {}, fluff? {} " ,
tx . hash ( ) ,
fluff
) ;
Ok ( ( ) )
}
}
2021-12-14 15:23:17 +03:00
/// Scan outputs with the rewind hash of a third-party wallet.
/// Help to retrieve outputs information that belongs it
pub fn scan_rewind_hash < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
rewind_hash : String ,
start_height : Option < u64 > ,
status_send_channel : & Option < Sender < StatusMessage > > ,
) -> Result < ViewWallet , Error >
where
L : WalletLCProvider < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
let is_hex = rewind_hash . chars ( ) . all ( | c | c . is_ascii_hexdigit ( ) ) ;
let rewind_hash = rewind_hash . to_lowercase ( ) ;
if ! ( is_hex & & rewind_hash . len ( ) = = 64 ) {
let msg = format! ( " Invalid Rewind Hash " ) ;
2022-07-28 12:21:45 +03:00
return Err ( Error ::RewindHash ( msg ) ) ;
2021-12-14 15:23:17 +03:00
}
let tip = {
wallet_lock! ( wallet_inst , w ) ;
w . w2n_client ( ) . get_chain_tip ( ) ?
} ;
let start_height = match start_height {
Some ( h ) = > h ,
None = > 1 ,
} ;
let info = scan ::scan_rewind_hash (
wallet_inst ,
rewind_hash ,
start_height ,
tip . 0 ,
status_send_channel ,
) ? ;
Ok ( info )
}
2019-03-17 22:14:58 +03:00
/// check repair
2019-11-06 13:04:42 +03:00
/// Accepts a wallet inst instead of a raw wallet so it can
/// lock as little as possible
pub fn scan < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
2019-11-06 13:04:42 +03:00
start_height : Option < u64 > ,
2019-08-06 14:50:41 +03:00
delete_unconfirmed : bool ,
2019-11-18 13:49:51 +03:00
status_send_channel : & Option < Sender < StatusMessage > > ,
2019-08-06 14:50:41 +03:00
) -> Result < ( ) , Error >
2019-03-17 22:14:58 +03:00
where
2019-11-06 13:04:42 +03:00
L : WalletLCProvider < ' a , C , K > ,
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2019-11-06 13:04:42 +03:00
update_outputs ( wallet_inst . clone ( ) , keychain_mask , true ) ? ;
let tip = {
wallet_lock! ( wallet_inst , w ) ;
w . w2n_client ( ) . get_chain_tip ( ) ?
} ;
let start_height = match start_height {
Some ( h ) = > h ,
None = > 1 ,
} ;
let mut info = scan ::scan (
wallet_inst . clone ( ) ,
keychain_mask ,
delete_unconfirmed ,
start_height ,
tip . 0 ,
2019-11-18 13:49:51 +03:00
status_send_channel ,
2019-11-06 13:04:42 +03:00
) ? ;
2019-11-05 00:10:05 +03:00
info . hash = tip . 1 ;
2019-11-06 13:04:42 +03:00
wallet_lock! ( wallet_inst , w ) ;
2019-11-05 00:10:05 +03:00
let mut batch = w . batch ( keychain_mask ) ? ;
batch . save_last_scanned_block ( info ) ? ;
batch . commit ( ) ? ;
Ok ( ( ) )
2019-03-17 22:14:58 +03:00
}
/// node height
2019-11-06 13:04:42 +03:00
pub fn node_height < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
) -> Result < NodeHeightResult , Error >
2019-03-17 22:14:58 +03:00
where
2019-11-06 13:04:42 +03:00
L : WalletLCProvider < ' a , C , K > ,
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2019-11-06 13:04:42 +03:00
let res = {
wallet_lock! ( wallet_inst , w ) ;
w . w2n_client ( ) . get_chain_tip ( )
} ;
2019-03-17 22:14:58 +03:00
match res {
2019-11-05 00:10:05 +03:00
Ok ( r ) = > Ok ( NodeHeightResult {
height : r . 0 ,
header_hash : r . 1 ,
2019-03-29 19:00:02 +03:00
updated_from_node : true ,
} ) ,
2019-03-17 22:14:58 +03:00
Err ( _ ) = > {
2019-11-18 13:49:51 +03:00
let outputs = retrieve_outputs ( wallet_inst , keychain_mask , & None , true , false , None ) ? ;
2019-03-22 15:03:25 +03:00
let height = match outputs . 1. iter ( ) . map ( | m | m . output . height ) . max ( ) {
2019-03-17 22:14:58 +03:00
Some ( height ) = > height ,
None = > 0 ,
} ;
2019-03-29 19:00:02 +03:00
Ok ( NodeHeightResult {
height ,
2019-11-05 00:10:05 +03:00
header_hash : " " . to_owned ( ) ,
2019-03-29 19:00:02 +03:00
updated_from_node : false ,
} )
2019-03-17 22:14:58 +03:00
}
}
}
2020-05-19 13:19:03 +03:00
2019-11-05 00:10:05 +03:00
/// Experimental, wrap the entire definition of how a wallet's state is updated
2019-11-18 13:49:51 +03:00
pub fn update_wallet_state < ' a , L , C , K > (
2019-11-06 13:04:42 +03:00
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
2019-11-05 00:10:05 +03:00
keychain_mask : Option < & SecretKey > ,
2019-11-18 13:49:51 +03:00
status_send_channel : & Option < Sender < StatusMessage > > ,
2019-11-05 00:10:05 +03:00
update_all : bool ,
) -> Result < bool , Error >
where
2019-11-06 13:04:42 +03:00
L : WalletLCProvider < ' a , C , K > ,
2019-11-05 00:10:05 +03:00
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
2019-11-06 13:04:42 +03:00
let parent_key_id = {
wallet_lock! ( wallet_inst , w ) ;
2020-02-07 12:39:56 +03:00
w . parent_key_id ( )
2019-11-06 13:04:42 +03:00
} ;
let client = {
wallet_lock! ( wallet_inst , w ) ;
w . w2n_client ( ) . clone ( )
} ;
2019-11-05 00:10:05 +03:00
// Step 1: Update outputs and transactions purely based on UTXO state
2019-11-18 13:49:51 +03:00
if let Some ( ref s ) = status_send_channel {
let _ = s . send ( StatusMessage ::UpdatingOutputs (
" Updating outputs from node " . to_owned ( ) ,
) ) ;
}
2019-11-06 13:04:42 +03:00
let mut result = update_outputs ( wallet_inst . clone ( ) , keychain_mask , update_all ) ? ;
2019-11-05 00:10:05 +03:00
if ! result {
2019-11-18 13:49:51 +03:00
if let Some ( ref s ) = status_send_channel {
let _ = s . send ( StatusMessage ::UpdateWarning (
" Updater Thread unable to contact node " . to_owned ( ) ,
) ) ;
}
2019-11-05 00:10:05 +03:00
return Ok ( result ) ;
}
2019-11-18 13:49:51 +03:00
if let Some ( ref s ) = status_send_channel {
let _ = s . send ( StatusMessage ::UpdatingTransactions (
" Updating transactions " . to_owned ( ) ,
) ) ;
}
2019-11-05 00:10:05 +03:00
// Step 2: Update outstanding transactions with no change outputs by kernel
2019-11-06 13:04:42 +03:00
let mut txs = {
wallet_lock! ( wallet_inst , w ) ;
updater ::retrieve_txs ( & mut * * w , None , None , Some ( & parent_key_id ) , true ) ?
} ;
result = update_txs_via_kernel ( wallet_inst . clone ( ) , keychain_mask , & mut txs ) ? ;
2019-11-05 00:10:05 +03:00
if ! result {
2019-11-18 13:49:51 +03:00
if let Some ( ref s ) = status_send_channel {
let _ = s . send ( StatusMessage ::UpdateWarning (
" Updater Thread unable to contact node " . to_owned ( ) ,
) ) ;
}
2019-11-05 00:10:05 +03:00
return Ok ( result ) ;
}
// Step 3: Scan back a bit on the chain
2019-11-06 13:04:42 +03:00
let res = client . get_chain_tip ( ) ;
// if we can't get the tip, don't continue
let tip = match res {
Ok ( t ) = > t ,
2019-11-18 13:49:51 +03:00
Err ( _ ) = > {
if let Some ( ref s ) = status_send_channel {
let _ = s . send ( StatusMessage ::UpdateWarning (
" Updater Thread unable to contact node " . to_owned ( ) ,
) ) ;
}
return Ok ( false ) ;
}
2019-11-06 13:04:42 +03:00
} ;
// Check if this is a restored wallet that needs a full scan
let last_scanned_block = {
wallet_lock! ( wallet_inst , w ) ;
match w . init_status ( ) ? {
WalletInitStatus ::InitNeedsScanning = > ScannedBlockInfo {
height : 0 ,
hash : " " . to_owned ( ) ,
start_pmmr_index : 0 ,
last_pmmr_index : 0 ,
} ,
WalletInitStatus ::InitNoScanning = > ScannedBlockInfo {
height : tip . clone ( ) . 0 ,
hash : tip . clone ( ) . 1 ,
start_pmmr_index : 0 ,
last_pmmr_index : 0 ,
} ,
WalletInitStatus ::InitComplete = > w . last_scanned_block ( ) ? ,
}
} ;
2019-11-05 00:10:05 +03:00
let start_index = last_scanned_block . height . saturating_sub ( 100 ) ;
if last_scanned_block . height = = 0 {
2020-02-07 12:39:56 +03:00
let msg = " This wallet has not been scanned against the current chain. Beginning full scan... (this first scan may take a while, but subsequent scans will be much quicker) " . to_string ( ) ;
2019-11-18 13:49:51 +03:00
if let Some ( ref s ) = status_send_channel {
let _ = s . send ( StatusMessage ::FullScanWarn ( msg ) ) ;
}
2019-11-05 00:10:05 +03:00
}
2019-11-06 13:04:42 +03:00
let mut info = scan ::scan (
wallet_inst . clone ( ) ,
keychain_mask ,
false ,
start_index ,
tip . 0 ,
2019-11-18 13:49:51 +03:00
status_send_channel ,
2019-11-06 13:04:42 +03:00
) ? ;
2019-11-05 00:10:05 +03:00
info . hash = tip . 1 ;
2019-12-02 16:54:57 +03:00
{
wallet_lock! ( wallet_inst , w ) ;
let mut batch = w . batch ( keychain_mask ) ? ;
batch . save_last_scanned_block ( info ) ? ;
// init considered complete after first successful update
batch . save_init_status ( WalletInitStatus ::InitComplete ) ? ;
batch . commit ( ) ? ;
}
// Step 5: Cancel any transactions with an expired TTL
for tx in txs {
if let Some ( e ) = tx . ttl_cutoff_height {
2019-12-04 16:04:28 +03:00
if tip . 0 > = e {
2019-12-02 16:54:57 +03:00
wallet_lock! ( wallet_inst , w ) ;
let parent_key_id = w . parent_key_id ( ) ;
tx ::cancel_tx ( & mut * * w , keychain_mask , & parent_key_id , Some ( tx . id ) , None ) ? ;
}
}
}
2019-11-05 00:10:05 +03:00
Ok ( result )
}
2019-03-17 22:14:58 +03:00
2019-12-02 16:54:57 +03:00
/// Check TTL
pub fn check_ttl < ' a , T : ? Sized , C , K > ( w : & mut T , slate : & Slate ) -> Result < ( ) , Error >
where
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
// Refuse if TTL is expired
let last_confirmed_height = w . last_confirmed_height ( ) ? ;
2020-05-19 13:19:03 +03:00
if slate . ttl_cutoff_height ! = 0 {
if last_confirmed_height > = slate . ttl_cutoff_height {
2022-07-28 12:21:45 +03:00
return Err ( Error ::TransactionExpired ) ;
2019-12-02 16:54:57 +03:00
}
}
Ok ( ( ) )
}
2020-01-22 16:16:24 +03:00
/// Verify/validate arbitrary payment proof
/// Returns (whether this wallet is the sender, whether this wallet is the recipient)
pub fn verify_payment_proof < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
keychain_mask : Option < & SecretKey > ,
proof : & PaymentProof ,
) -> Result < ( bool , bool ) , Error >
where
L : WalletLCProvider < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
2020-05-28 10:17:51 +03:00
let sender_pubkey = proof . sender_address . pub_key ;
2020-01-22 16:16:24 +03:00
let msg = tx ::payment_proof_message ( proof . amount , & proof . excess , sender_pubkey ) ? ;
let ( mut client , parent_key_id , keychain ) = {
wallet_lock! ( wallet_inst , w ) ;
(
w . w2n_client ( ) . clone ( ) ,
w . parent_key_id ( ) ,
w . keychain ( keychain_mask ) ? ,
)
} ;
// Check kernel exists
match client . get_kernel ( & proof . excess , None , None ) {
Err ( e ) = > {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProof ( format! (
2020-02-07 12:39:56 +03:00
" Error retrieving kernel from chain: {} " ,
e
2022-07-28 12:21:45 +03:00
) ) ) ;
2020-01-22 16:16:24 +03:00
}
Ok ( None ) = > {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProof ( format! (
2020-02-07 12:39:56 +03:00
" Transaction kernel with excess {:?} not found on chain " ,
proof . excess
2022-07-28 12:21:45 +03:00
) ) ) ;
2020-01-22 16:16:24 +03:00
}
Ok ( Some ( _ ) ) = > { }
} ;
// Check Sigs
2020-05-28 10:17:51 +03:00
let recipient_pubkey = proof . recipient_address . pub_key ;
2020-02-07 12:39:56 +03:00
if recipient_pubkey . verify ( & msg , & proof . recipient_sig ) . is_err ( ) {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProof (
" Invalid recipient signature " . to_owned ( ) ,
) ) ;
2020-01-22 16:16:24 +03:00
} ;
2020-05-28 10:17:51 +03:00
let sender_pubkey = proof . sender_address . pub_key ;
2020-02-07 12:39:56 +03:00
if sender_pubkey . verify ( & msg , & proof . sender_sig ) . is_err ( ) {
2022-07-28 12:21:45 +03:00
return Err ( Error ::PaymentProof ( " Invalid sender signature " . to_owned ( ) ) ) ;
2020-01-22 16:16:24 +03:00
} ;
// for now, simple test as to whether one of the addresses belongs to this wallet
let sec_key = address ::address_from_derivation_path ( & keychain , & parent_key_id , 0 ) ? ;
let d_skey = match DalekSecretKey ::from_bytes ( & sec_key . 0 ) {
Ok ( k ) = > k ,
Err ( e ) = > {
2022-07-28 12:21:45 +03:00
return Err ( Error ::ED25519Key ( format! ( " {} " , e ) ) ) ;
2020-01-22 16:16:24 +03:00
}
} ;
let my_address_pubkey : DalekPublicKey = ( & d_skey ) . into ( ) ;
let sender_mine = my_address_pubkey = = sender_pubkey ;
let recipient_mine = my_address_pubkey = = recipient_pubkey ;
Ok ( ( sender_mine , recipient_mine ) )
}
2019-03-17 22:14:58 +03:00
/// Attempt to update outputs in wallet, return whether it was successful
2019-11-06 13:04:42 +03:00
fn update_outputs < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
2019-08-06 14:50:41 +03:00
keychain_mask : Option < & SecretKey > ,
update_all : bool ,
2019-08-13 11:36:21 +03:00
) -> Result < bool , Error >
2019-03-17 22:14:58 +03:00
where
2019-11-06 13:04:42 +03:00
L : WalletLCProvider < ' a , C , K > ,
Merge milestone/2.1.0 into master (#199)
* version bump for next potential release
* Merge master into milestone/2.1.0 (#182)
* Derive --version output dynamically from cargo package version (#174)
* add --txid to the `wallet txs` command (#176)
* add --txid to the `wallet txs` command
* add test for `wallet txs` command with `--txid` parameter
* Refactor - Split WalletCommAdapter into multiple traits (#180)
* Derive --version output dynamically from cargo package version (#174)
* add server auth argument to http client
* Revert "add server auth argument to http client"
This reverts commit f52a8d2c7cdfb8583af5716ad621eb560811d6ee.
* modify WalletCommAdapter, moving dest argument into fields on implementors,
visiting havok on automated tests, at least one of which is now out of date and failing
* Split WalletCommAdapter into four traits, one for each of its intended behaviors.
* Remove two vestigals
1. args, a stringly typed argument to put_tx
2. NullAdapter, which is no longer used
* Remove unused "params" argument from listen method.
* Re-add previously existing TODO comment
* Fix non-test build
* completely Fix non-test build
* Full Lifecycle API Support (#184)
* refactoring wallet lib traits
* rustfmt
* rustfmt
* add new files
* explicit lifetime specifiers on all wallet traits
* rustfmt
* modify apis to use new walletinst
* rustfmt
* converting controller crate
* rustfmt
* controller crate compiling
* rustfmt
* compilation
* rustfmt
* Remove config from wallet, implement open_wallet, close_wallet in lifecycle provider, remove password + open_with_credentials from WalletBackend + impl
* rustfmt
* full compilation, changing recovery + init to new model
* rustfmt
* wallet initialisation working, init command output and flow identical to v2.0.0 wallet
* rustfmt
* fix listener and owner api startup
* rustfmt
* rustfmt
* move encryption test
* rustfmt
* fix api doctests
* rustfmt
* fix for most tests in controller crate
* rustfmt
* fix for check tests in controller crate
* fix main wallet tests
* rustfmt
* add explicit functions to handle mnemonic recovery, fix CLI recovery workflow
* rustfmt
* update keybase adapter to use new wallet format
* rustfmt
* test fix
* remove debug output
2019-07-29 15:25:03 +03:00
C : NodeClient + ' a ,
K : Keychain + ' a ,
2019-03-17 22:14:58 +03:00
{
2019-11-06 13:04:42 +03:00
wallet_lock! ( wallet_inst , w ) ;
2019-03-17 22:14:58 +03:00
let parent_key_id = w . parent_key_id ( ) ;
2019-11-06 13:04:42 +03:00
match updater ::refresh_outputs ( & mut * * w , keychain_mask , & parent_key_id , update_all ) {
2019-08-13 11:36:21 +03:00
Ok ( _ ) = > Ok ( true ) ,
Err ( e ) = > {
2022-07-28 12:21:45 +03:00
if let Error ::InvalidKeychainMask = e {
2019-08-13 11:36:21 +03:00
return Err ( e ) ;
}
Ok ( false )
}
2019-03-17 22:14:58 +03:00
}
}
2019-09-24 11:56:10 +03:00
/// Update transactions that need to be validated via kernel lookup
2019-11-06 13:04:42 +03:00
fn update_txs_via_kernel < ' a , L , C , K > (
wallet_inst : Arc < Mutex < Box < dyn WalletInst < ' a , L , C , K > > > > ,
2019-09-24 11:56:10 +03:00
keychain_mask : Option < & SecretKey > ,
txs : & mut Vec < TxLogEntry > ,
) -> Result < bool , Error >
where
2019-11-06 13:04:42 +03:00
L : WalletLCProvider < ' a , C , K > ,
2019-09-24 11:56:10 +03:00
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
2019-11-06 13:04:42 +03:00
let parent_key_id = {
wallet_lock! ( wallet_inst , w ) ;
2020-02-07 12:39:56 +03:00
w . parent_key_id ( )
2019-11-06 13:04:42 +03:00
} ;
let mut client = {
wallet_lock! ( wallet_inst , w ) ;
w . w2n_client ( ) . clone ( )
} ;
let height = match client . get_chain_tip ( ) {
2019-11-05 00:10:05 +03:00
Ok ( h ) = > h . 0 ,
2019-09-24 11:56:10 +03:00
Err ( _ ) = > return Ok ( false ) ,
} ;
2019-11-06 13:04:42 +03:00
2019-09-24 11:56:10 +03:00
for tx in txs . iter_mut ( ) {
if tx . confirmed {
continue ;
}
2019-10-03 17:15:25 +03:00
if tx . amount_debited ! = 0 & & tx . amount_credited ! = 0 {
continue ;
}
2019-09-24 11:56:10 +03:00
if let Some ( e ) = tx . kernel_excess {
2019-11-06 13:04:42 +03:00
let res = client . get_kernel ( & e , tx . kernel_lookup_min_height , Some ( height ) ) ;
2019-09-24 11:56:10 +03:00
let kernel = match res {
Ok ( k ) = > k ,
Err ( _ ) = > return Ok ( false ) ,
} ;
if let Some ( k ) = kernel {
debug! ( " Kernel Retrieved: {:?} " , k ) ;
2019-11-06 13:04:42 +03:00
wallet_lock! ( wallet_inst , w ) ;
2019-09-24 11:56:10 +03:00
let mut batch = w . batch ( keychain_mask ) ? ;
tx . confirmed = true ;
tx . update_confirmation_ts ( ) ;
batch . save_tx_log_entry ( tx . clone ( ) , & parent_key_id ) ? ;
batch . commit ( ) ? ;
}
2019-10-03 17:15:25 +03:00
} else {
warn! ( " Attempted to update via kernel excess for transaction {:?}, but kernel excess was not stored " , tx . tx_slate_id ) ;
2019-09-24 11:56:10 +03:00
}
}
Ok ( true )
}
2022-02-18 13:06:04 +03:00
/// Builds an output for the wallet's next available key
pub fn build_output < ' a , T : ? Sized , C , K > (
w : & mut T ,
keychain_mask : Option < & SecretKey > ,
features : OutputFeatures ,
amount : u64 ,
) -> Result < BuiltOutput , Error >
where
T : WalletBackend < ' a , C , K > ,
C : NodeClient + ' a ,
K : Keychain + ' a ,
{
let k = w . keychain ( keychain_mask ) ? ;
let key_id = keys ::next_available_key ( & mut * w , keychain_mask ) ? ;
let blind = k . derive_key ( amount , & key_id , SwitchCommitmentType ::Regular ) ? ;
let commit = k . secp ( ) . commit ( amount , blind . clone ( ) ) ? ;
let proof_builder = proof ::ProofBuilder ::new ( & k ) ;
let proof = proof ::create (
& k ,
& proof_builder ,
amount ,
& key_id ,
SwitchCommitmentType ::Regular ,
commit ,
None ,
) ? ;
let output = Output ::new ( features , commit , proof ) ;
Ok ( BuiltOutput {
blind : BlindingFactor ::from_secret_key ( blind ) ,
key_id : key_id ,
output : output ,
} )
}