@ -8532,7 +8532,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
needed_fee = estimate_fee ( use_per_byte_fee , use_rct , tx . selected_transfers . size ( ) , fake_outs_count , tx . dsts . size ( ) + 1 , extra . size ( ) , bulletproof , base_fee , fee_multiplier , fee_quantization_mask ) ;
tx . dsts . push_back ( tx_destination_entry ( 1 , address , is_subaddress ) ) ;
// add N - 1 outputs for correct initial fee estimation
for ( size_t i = 0 ; i < ( ( outputs > 1 ) ? outputs - 1 : outputs ) ; + + i )
tx . dsts . push_back ( tx_destination_entry ( 1 , address , is_subaddress ) ) ;
LOG_PRINT_L2 ( " Trying to create a tx now, with " < < tx . dsts . size ( ) < < " destinations and " < <
tx . selected_transfers . size ( ) < < " outputs " ) ;
@ -8544,15 +8546,35 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
detail : : digit_split_strategy , tx_dust_policy ( : : config : : DEFAULT_DUST_THRESHOLD ) , test_tx , test_ptx ) ;
auto txBlob = t_serializable_object_to_blob ( test_ptx . tx ) ;
needed_fee = calculate_fee ( use_per_byte_fee , test_ptx . tx , txBlob . size ( ) , base_fee , fee_multiplier , fee_quantization_mask ) ;
available_for_fee = test_ptx . fee + test_ptx . dests [ 0 ] . amount + test_ptx . change_dts . amount ;
available_for_fee = test_ptx . fee + test_ptx . change_dts . amount ;
for ( auto & dt : test_ptx . dests )
available_for_fee + = dt . amount ;
LOG_PRINT_L2 ( " Made a " < < get_weight_string ( test_ptx . tx , txBlob . size ( ) ) < < " tx, with " < < print_money ( available_for_fee ) < < " available for fee ( " < <
print_money ( needed_fee ) < < " needed) " ) ;
// add last output, missed for fee estimation
if ( outputs > 1 )
tx . dsts . push_back ( tx_destination_entry ( 1 , address , is_subaddress ) ) ;
THROW_WALLET_EXCEPTION_IF ( needed_fee > available_for_fee , error : : wallet_internal_error , " Transaction cannot pay for itself " ) ;
do {
LOG_PRINT_L2 ( " We made a tx, adjusting fee and saving it " ) ;
tx . dsts [ 0 ] . amount = available_for_fee - needed_fee ;
// distribute total transferred amount between outputs
uint64_t amount_transferred = available_for_fee - needed_fee ;
uint64_t dt_amount = amount_transferred / outputs ;
// residue is distributed as one atomic unit per output until it reaches zero
uint64_t residue = amount_transferred % outputs ;
for ( auto & dt : tx . dsts )
{
uint64_t dt_residue = 0 ;
if ( residue > 0 )
{
dt_residue = 1 ;
residue - = 1 ;
}
dt . amount = dt_amount + dt_residue ;
}
if ( use_rct )
transfer_selected_rct ( tx . dsts , tx . selected_transfers , fake_outs_count , outs , unlock_time , needed_fee , extra ,
test_tx , test_ptx , range_proof_type ) ;