@ -5464,13 +5464,19 @@ uint64_t wallet2::balance(uint32_t index_major) const
return amount ;
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2 : : unlocked_balance ( uint32_t index_major ) const
uint64_t wallet2 : : unlocked_balance ( uint32_t index_major , uint64_t * blocks_to_unlock ) const
{
uint64_t amount = 0 ;
if ( blocks_to_unlock )
* blocks_to_unlock = 0 ;
if ( m_light_wallet )
return m_light_wallet_balance ;
for ( const auto & i : unlocked_balance_per_subaddress ( index_major ) )
amount + = i . second ;
{
amount + = i . second . first ;
if ( blocks_to_unlock & & i . second . second > * blocks_to_unlock )
* blocks_to_unlock = i . second . second ;
}
return amount ;
}
//----------------------------------------------------------------------------------------------------
@ -5503,18 +5509,36 @@ std::map<uint32_t, uint64_t> wallet2::balance_per_subaddress(uint32_t index_majo
return amount_per_subaddr ;
}
//----------------------------------------------------------------------------------------------------
std : : map < uint32_t , uint64_t > wallet2 : : unlocked_balance_per_subaddress ( uint32_t index_major ) const
std : : map < uint32_t , std : : pair < uint64_t , uint64_t > > wallet2 : : unlocked_balance_per_subaddress ( uint32_t index_major ) const
{
std : : map < uint32_t , uint64_t > amount_per_subaddr ;
std : : map < uint32_t , std : : pair < uint64_t , uint64_t > > amount_per_subaddr ;
const uint64_t blockchain_height = get_blockchain_current_height ( ) ;
for ( const transfer_details & td : m_transfers )
{
if ( td . m_subaddr_index . major = = index_major & & ! td . m_spent & & ! td . m_frozen & & is_transfer_unlocked ( td ) )
if ( td . m_subaddr_index . major = = index_major & & ! td . m_spent & & ! td . m_frozen )
{
uint64_t amount = 0 , blocks_to_unlock = 0 ;
if ( is_transfer_unlocked ( td ) )
{
amount = td . amount ( ) ;
blocks_to_unlock = 0 ;
}
else
{
uint64_t unlock_height = td . m_block_height + std : : max < uint64_t > ( CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE , CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS ) ;
if ( td . m_tx . unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER & & td . m_tx . unlock_time > unlock_height )
unlock_height = td . m_tx . unlock_time ;
blocks_to_unlock = unlock_height > blockchain_height ? unlock_height - blockchain_height : 0 ;
amount = 0 ;
}
auto found = amount_per_subaddr . find ( td . m_subaddr_index . minor ) ;
if ( found = = amount_per_subaddr . end ( ) )
amount_per_subaddr [ td . m_subaddr_index . minor ] = td . amount ( ) ;
amount_per_subaddr [ td . m_subaddr_index . minor ] = std: : make_pair ( amount , blocks_to_unlock ) ;
else
found - > second + = td . amount ( ) ;
{
found - > second . first + = amount ;
found - > second . second = std : : max ( found - > second . second , blocks_to_unlock ) ;
}
}
}
return amount_per_subaddr ;
@ -5528,11 +5552,18 @@ uint64_t wallet2::balance_all() const
return r ;
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2 : : unlocked_balance_all ( ) const
uint64_t wallet2 : : unlocked_balance_all ( uint64_t * blocks_to_unlock ) const
{
uint64_t r = 0 ;
if ( blocks_to_unlock )
* blocks_to_unlock = 0 ;
for ( uint32_t index_major = 0 ; index_major < get_num_subaddress_accounts ( ) ; + + index_major )
r + = unlocked_balance ( index_major ) ;
{
uint64_t local_blocks_to_unlock ;
r + = unlocked_balance ( index_major , blocks_to_unlock ? & local_blocks_to_unlock : NULL ) ;
if ( blocks_to_unlock )
* blocks_to_unlock = std : : max ( * blocks_to_unlock , local_blocks_to_unlock ) ;
}
return r ;
}
//----------------------------------------------------------------------------------------------------
@ -9078,7 +9109,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// throw if attempting a transaction with no money
THROW_WALLET_EXCEPTION_IF ( needed_money = = 0 , error : : zero_destination ) ;
std : : map < uint32_t , uint64_t > unlocked_balance_per_subaddr = unlocked_balance_per_subaddress ( subaddr_account ) ;
std : : map < uint32_t , std : : pair < uint64_t , uint64_t > > unlocked_balance_per_subaddr = unlocked_balance_per_subaddress ( subaddr_account ) ;
std : : map < uint32_t , uint64_t > balance_per_subaddr = balance_per_subaddress ( subaddr_account ) ;
if ( subaddr_indices . empty ( ) ) // "index=<N1>[,<N2>,...]" wasn't specified -> use all the indices with non-zero unlocked balance
@ -9096,7 +9127,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
for ( uint32_t index_minor : subaddr_indices )
{
balance_subtotal + = balance_per_subaddr [ index_minor ] ;
unlocked_balance_subtotal + = unlocked_balance_per_subaddr [ index_minor ] ;
unlocked_balance_subtotal + = unlocked_balance_per_subaddr [ index_minor ] .first ;
}
THROW_WALLET_EXCEPTION_IF ( needed_money + min_fee > balance_subtotal , error : : not_enough_money ,
balance_subtotal , needed_money , 0 ) ;
@ -9162,7 +9193,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
{
auto sort_predicate = [ & unlocked_balance_per_subaddr ] ( const std : : pair < uint32_t , std : : vector < size_t > > & x , const std : : pair < uint32_t , std : : vector < size_t > > & y )
{
return unlocked_balance_per_subaddr [ x . first ] > unlocked_balance_per_subaddr [ y . first ] ;
return unlocked_balance_per_subaddr [ x . first ] . first > unlocked_balance_per_subaddr [ y . first ] . first ;
} ;
std : : sort ( unused_transfers_indices_per_subaddr . begin ( ) , unused_transfers_indices_per_subaddr . end ( ) , sort_predicate ) ;
std : : sort ( unused_dust_indices_per_subaddr . begin ( ) , unused_dust_indices_per_subaddr . end ( ) , sort_predicate ) ;