From c580c301f40578f16c55921ee21d9e02c76ff58e Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Fri, 14 Nov 2014 20:30:44 -0500 Subject: [PATCH] wallet_repair_records can collect orphaned balances into a specified account; resolves #985 --- libraries/api/wallet_api.json | 11 ++++-- .../include/bts/blockchain/balance_record.hpp | 14 ++++---- libraries/client/wallet_api.cpp | 25 +++++++------ .../wallet/include/bts/wallet/wallet.hpp | 4 +-- libraries/wallet/wallet.cpp | 36 ++++++++++++++++--- 5 files changed, 64 insertions(+), 26 deletions(-) diff --git a/libraries/api/wallet_api.json b/libraries/api/wallet_api.json index d5982da74..eac80e8fe 100644 --- a/libraries/api/wallet_api.json +++ b/libraries/api/wallet_api.json @@ -2029,9 +2029,16 @@ }, { "method_name" : "wallet_repair_records", - "description" : "tries to repair any inconsistent wallet account and key records", + "description" : "tries to repair any inconsistent wallet account, key, and transaction records", "return_type" : "void", - "parameters" : [], + "parameters" : [ + { + "name" : "collecting_account_name", + "type" : "account_name", + "description" : "collect any orphan balances into this account", + "default_value" : "" + } + ], "prerequisites" : ["wallet_unlocked"] }, { diff --git a/libraries/blockchain/include/bts/blockchain/balance_record.hpp b/libraries/blockchain/include/bts/blockchain/balance_record.hpp index f42cb0322..dfbebba43 100644 --- a/libraries/blockchain/include/bts/blockchain/balance_record.hpp +++ b/libraries/blockchain/include/bts/blockchain/balance_record.hpp @@ -26,17 +26,17 @@ namespace bts { namespace blockchain { balance_record( const address& owner, const asset& balance, slate_id_type delegate_id ); - /** condition.get_address() */ - balance_id_type id()const { return condition.get_address(); } - asset get_spendable_balance( const time_point_sec& at_time )const; bool is_null()const { return balance == 0; } balance_record make_null()const { balance_record cpy(*this); cpy.balance = 0; return cpy; } - asset_id_type asset_id()const { return condition.asset_id; } - slate_id_type delegate_slate_id()const { return condition.delegate_slate_id; } - asset calculate_yield( fc::time_point_sec now, share_type amount, share_type yield_pool, share_type share_supply )const; - /** if condition is signature or by name, return the owner */ + balance_id_type id()const { return condition.get_address(); } + address owner()const; + slate_id_type delegate_slate_id()const { return condition.delegate_slate_id; } + + asset_id_type asset_id()const { return condition.asset_id; } + asset get_spendable_balance( const time_point_sec& at_time )const; + asset calculate_yield( fc::time_point_sec now, share_type amount, share_type yield_pool, share_type share_supply )const; withdraw_condition condition; share_type balance = 0; diff --git a/libraries/client/wallet_api.cpp b/libraries/client/wallet_api.cpp index f9ad89d37..e55d77563 100644 --- a/libraries/client/wallet_api.cpp +++ b/libraries/client/wallet_api.cpp @@ -94,8 +94,8 @@ void detail::client_impl::wallet_unlock( uint32_t timeout, const string& passwor reschedule_delegate_loop(); if( _config.wallet_callback_url.size() > 0 ) { - _http_callback_signal_connection = - _wallet->wallet_claimed_transaction.connect( + _http_callback_signal_connection = + _wallet->wallet_claimed_transaction.connect( [=]( ledger_entry e ) { this->wallet_http_callback( _config.wallet_callback_url, e ); } ); } } @@ -205,10 +205,10 @@ wallet_transaction_record detail::client_impl::wallet_transfer_to_public_account { auto to_key = _wallet->get_account_public_key( to_account_name ); return _wallet->transfer_asset_to_address(amount_to_transfer, - asset_symbol, + asset_symbol, from_account_name, - address(to_key), - memo_message, + address(to_key), + memo_message, selection_method, true); } @@ -306,7 +306,7 @@ wallet_transaction_record detail::client_impl::wallet_transfer_from_with_escrow( transaction_builder_ptr builder = _wallet->create_transaction_builder(); auto record = builder->deposit_asset_with_escrow(payer, recipient, escrow_account, agreement, - amount, memo_message, selection_method, + amount, memo_message, selection_method, sender.owner_key) .finalize() .sign(); @@ -691,7 +691,7 @@ wallet_transaction_record client_impl::wallet_account_register( const string& ac uint8_t delegate_pay_rate, const string& new_account_type ) { try { - const auto record = _wallet->register_account( account_name, data, delegate_pay_rate, + const auto record = _wallet->register_account( account_name, data, delegate_pay_rate, pay_with_account, variant(new_account_type).as(), false ); network_broadcast_transaction( record.trx ); @@ -987,11 +987,14 @@ wallet_transaction_record client_impl::wallet_publish_feeds( const std::string& return record; } -void client_impl::wallet_repair_records() -{ +void client_impl::wallet_repair_records( const string& collecting_account_name ) +{ try { _wallet->auto_backup( "before_record_repair" ); - return _wallet->repair_records(); -} + optional account_name; + if( !collecting_account_name.empty() ) + account_name = collecting_account_name; + return _wallet->repair_records( account_name ); +} FC_CAPTURE_AND_RETHROW( (collecting_account_name) ) } int32_t client_impl::wallet_regenerate_keys( const std::string& account, uint32_t number_to_regenerate ) { diff --git a/libraries/wallet/include/bts/wallet/wallet.hpp b/libraries/wallet/include/bts/wallet/wallet.hpp index 90f297553..4334493ad 100644 --- a/libraries/wallet/include/bts/wallet/wallet.hpp +++ b/libraries/wallet/include/bts/wallet/wallet.hpp @@ -183,7 +183,7 @@ namespace bts { namespace wallet { /** sign a block if this wallet controls the key for the active delegate, or throw */ void sign_block( signed_block_header& header )const; ///@} - + fc::ecc::compact_signature sign_hash(const string& signer, const fc::sha256& hash )const; /** @@ -536,7 +536,7 @@ namespace bts { namespace wallet { void remove_transaction_record( const string& record_id ); - void repair_records(); + void repair_records( const optional& collecting_account_name ); uint32_t regenerate_keys( const string& account_name, uint32_t num_keys_to_regenerate ); int32_t recover_accounts( int32_t number_of_accounts , int32_t max_number_of_attempts ); diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index c1368bdf4..248acd485 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -1960,13 +1960,41 @@ namespace detail { return builder->transaction_record; } FC_CAPTURE_AND_RETHROW( (authorizing_account_name)(delegate_name)(block_signing_key)(sign) ) } - void wallet::repair_records() + void wallet::repair_records( const optional& collecting_account_name ) { try { - FC_ASSERT( is_open() ); - FC_ASSERT( is_unlocked() ); + if( NOT is_open() ) FC_CAPTURE_AND_THROW( wallet_closed ); + if( NOT is_unlocked() ) FC_CAPTURE_AND_THROW( wallet_locked ); + ulog( "Repairing wallet records. This may take a while..." ); my->_wallet_db.repair_records( my->_wallet_password ); - } FC_CAPTURE_AND_RETHROW() } + + if( !collecting_account_name.valid() ) + return; + + const owallet_account_record account_record = my->_wallet_db.lookup_account( *collecting_account_name ); + FC_ASSERT( account_record.valid(), "Cannot find a local account with that name!", + ("collecting_account_name",*collecting_account_name) ); + + map> items = get_account_balance_records(); + for( const auto& item : items ) + { + const auto& name = item.first; + const auto& records = item.second; + + if( name.find( BTS_ADDRESS_PREFIX ) != 0 ) + continue; + + for( const auto& record : records ) + { + owallet_key_record key_record = my->_wallet_db.lookup_key( record.owner() ); + if( key_record.valid() ) + { + key_record->account_address = account_record->owner_address(); + my->_wallet_db.store_key( *key_record ); + } + } + } + } FC_CAPTURE_AND_RETHROW( (collecting_account_name) ) } uint32_t wallet::regenerate_keys( const string& account_name, uint32_t num_keys_to_regenerate ) { try {