@ -4120,7 +4120,7 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money) co
return picks ;
}
static bool should_pick_a_second_output ( bool use_rct , size_t n_transfers , const std : : vector < size_t > & unused_transfers_indices , const std : : vector < size_t > & unused_dust_indices )
bool wallet2 : : should_pick_a_second_output ( bool use_rct , size_t n_transfers , const std : : vector < size_t > & unused_transfers_indices , const std : : vector < size_t > & unused_dust_indices ) const
{
if ( ! use_rct )
return false ;
@ -4128,9 +4128,43 @@ static bool should_pick_a_second_output(bool use_rct, size_t n_transfers, const
return false ;
if ( unused_dust_indices . empty ( ) & & unused_transfers_indices . empty ( ) )
return false ;
// we want at least one free rct output to avoid a corner case where
// we'd choose a non rct output which doesn't have enough "siblings"
// value-wise on the chain, and thus can't be mixed
bool found = false ;
for ( auto i : unused_dust_indices )
{
if ( m_transfers [ i ] . is_rct ( ) )
{
found = true ;
break ;
}
}
if ( ! found ) for ( auto i : unused_transfers_indices )
{
if ( m_transfers [ i ] . is_rct ( ) )
{
found = true ;
break ;
}
}
if ( ! found )
return false ;
return true ;
}
std : : vector < size_t > wallet2 : : get_only_rct ( const std : : vector < size_t > & unused_dust_indices , const std : : vector < size_t > & unused_transfers_indices ) const
{
std : : vector < size_t > indices ;
for ( size_t n : unused_dust_indices )
if ( m_transfers [ n ] . is_rct ( ) )
indices . push_back ( n ) ;
for ( size_t n : unused_transfers_indices )
if ( m_transfers [ n ] . is_rct ( ) )
indices . push_back ( n ) ;
return indices ;
}
// Another implementation of transaction creation that is hopefully better
// While there is anything left to pay, it goes through random outputs and tries
// to fill the next destination/amount. If it fully fills it, it will use the
@ -4195,8 +4229,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
THROW_WALLET_EXCEPTION_IF ( needed_money = = 0 , error : : zero_destination ) ;
// gather all our dust and non dust outputs
const std : : vector < size_t > unused_indices = select_available_outputs_from_histogram ( fake_outs_count + 1 , true , true , true , trusted_daemon ) ;
for ( size_t i : unused_indices )
for ( size_t i = 0 ; i < m_transfers . size ( ) ; + + i )
{
const transfer_details & td = m_transfers [ i ] ;
if ( ! td . m_spent & & ( use_rct ? true : ! td . is_rct ( ) ) & & is_transfer_unlocked ( td ) )
@ -4279,7 +4312,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
size_t idx ;
if ( ( dsts . empty ( ) | | dsts [ 0 ] . amount = = 0 ) & & ! adding_fee ) {
// the "make rct txes 2/2" case - we pick a small value output to "clean up" the wallet too
idx = pop_best_value ( unused_dust_indices . empty ( ) ? unused_transfers_indices : unused_dust_indices , tx . selected_transfers , true ) ;
std : : vector < size_t > indices = get_only_rct ( unused_dust_indices , unused_transfers_indices ) ;
idx = pop_best_value ( indices , tx . selected_transfers , true ) ;
// since we're trying to add a second output which is not strictly needed,
// we only add it if it's unrelated enough to the first one
@ -4289,6 +4323,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
LOG_PRINT_L2 ( " Second outout was not strictly needed, and relatedness " < < relatedness < < " , not adding " ) ;
break ;
}
pop_if_present ( unused_transfers_indices , idx ) ;
pop_if_present ( unused_dust_indices , idx ) ;
} else if ( ! prefered_inputs . empty ( ) ) {
idx = pop_back ( prefered_inputs ) ;
pop_if_present ( unused_transfers_indices , idx ) ;