-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GH-711: Completion of fundamental Payment Adjuster and its peripheries #442
base: master
Are you sure you want to change the base?
Conversation
…lved for the time being
…implemented for a try
… features that are missing here
… tests for BlockchainInterfaceClandestine should be made first
…nterfaceClandestine
…ith some missing features
node/src/accountant/payment_adjuster/criterion_calculators/balance_calculator.rs
Show resolved
Hide resolved
node/src/accountant/payment_adjuster/criterion_calculators/balance_calculator.rs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node/src/accountant/payment_adjuster/miscellaneous/account_stages_conversions.rs:26
node/src/accountant/payment_adjuster/logging_and_diagnostics/log_functions.rs
Show resolved
Hide resolved
const BLANK_SPACE: &str = ""; | ||
|
||
pub fn format_brief_adjustment_summary( | ||
original_account_balances_mapped: HashMap<Wallet, u128>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use Address
instead of Wallet
, we would end up optimising it further.
node/src/accountant/payment_adjuster/logging_and_diagnostics/log_functions.rs
Show resolved
Hide resolved
node/src/accountant/payment_adjuster/logging_and_diagnostics/log_functions.rs
Show resolved
Hide resolved
node/src/accountant/payment_adjuster/logging_and_diagnostics/log_functions.rs
Show resolved
Hide resolved
logger: &Logger, | ||
account: &DisqualificationSuspectedAccount, | ||
) { | ||
info!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that it could be overwhelming to user to see so many info notifications for each account. Ideally, it should be a summary along the lines, "X accounts haven't been paid yet, due to low MASQ balance."
) { | ||
warning!( | ||
logger, | ||
"Transaction fee balance of {} wei is not going to cover the anticipated fee to send {} \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's mention how much balance the user needs to maintain to pass the tx fee barrier. Similar with the above service fee.
account.balance_wei = non_finalized_adjustment.proposed_adjusted_balance_minor; | ||
account | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to review the comments in this file to make them more explanatory.
|
||
// This is used when we detect that the upcoming iterations begins with a surplus in the remaining | ||
// unallocated CW service fee, and therefore we grant the remaining accounts with the full balance | ||
// they requested |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just the disqualification limit and not the full balance
use crate::accountant::AnalyzedPayableAccount; | ||
|
||
#[test] | ||
fn conversion_between_non_finalized_account_and_payable_account_is_implemented() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test name inconsistent with those others
original_payable_account.balance_wei = 200_000_000; | ||
let mut weighted_account = prepare_weighted_account(original_payable_account.clone()); | ||
weighted_account.weight = 321654; | ||
let unconfirmed_adjustment = UnconfirmedAdjustment::new(weighted_account, 111_222_333); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might look better if that 111_222_333 was assigned to a variable with a self-explaining name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node/src/accountant/payment_adjuster/adjustment_runners.rs:118
return payment_adjuster | ||
.begin_with_adjustment_by_transaction_fee(weighted_accounts, limit) | ||
} | ||
None => (), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can change it to if let
.
fn initialize_payment_adjuster( | ||
now: SystemTime, | ||
service_fee_balance: u128, | ||
largest_exceeding_balance_recently_qualified: u128, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the name max_balance_over_threshold_of_qualified_payables
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node/src/accountant/payment_adjuster/logging_and_diagnostics/diagnostics.rs:103
payable_2: WeightedPayable, | ||
cw_service_fee_balance_minor: u128, | ||
expected_proposed_balance_1: u128, | ||
expected_proposed_balance_2: u128, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use arrays for payables and expected balance with 2 elements instead of arguments.
payment_adjuster: &mut PaymentAdjusterReal, | ||
weighted_accounts: Vec<WeightedPayable>, | ||
) -> Self::ReturnType; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using it as a trait, it could be used as an enum.
It would make an impact on the other function:
fn propose_adjustments_recursively<AR, RT>(
&mut self,
unresolved_accounts: Vec<WeightedPayable>,
adjustment_runner: AR, // It would become an enum
) -> RT
where
AR: AdjustmentRunner<ReturnType = RT>,
{
diagnostics!(
"\nUNRESOLVED QUALIFIED ACCOUNTS IN CURRENT ITERATION:",
&unresolved_accounts
);
adjustment_runner.adjust_accounts(self, unresolved_accounts) // we would make it a method of self and will pass the variant
}
n: u64, | ||
initial_balance_minor: u128, | ||
) -> WeightedPayable { | ||
let mut account = make_weighed_payable(n, initial_balance_minor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want make_weighted_payable
, the t
is missing.
} | ||
|
||
#[test] | ||
fn means_equal_requested_money_after_dsq_in_previous_iteration_to_return_capped_accounts() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A suggested new name:
fn untaken_cw_balance_equals_full_two_debts_after_loosing_an_account_results_in_constrained_balances()
Note: We had a nice discussion and it turns out you'd prefer untaken over unallocated. I think that's a great change.
#[test] | ||
fn means_equal_requested_money_after_dsq_in_previous_iteration_to_return_capped_accounts() { | ||
let subject = ServiceFeeOnlyAdjustmentRunner {}; | ||
let cw_service_fee_balance_minor = 10_000_000_000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once the test rename is done, please rename this variable to include untaken
.
let mut account_2 = account; | ||
account_2.bare_account.wallet = wallet_2.clone(); | ||
let adjustment = Adjustment::TransactionFeeInPriority { | ||
affordable_transaction_count: 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment here to say that the limit is set here. Maybe you want to add more explanation.
let adjustment = Adjustment::TransactionFeeInPriority { | ||
affordable_transaction_count: 1, | ||
}; | ||
let service_fee_balance_minor = (10 * balance) / 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's consuming wallet balance.
@bertllll was puzzled by this number and it was enough to make the test pass.
let mut payment_adjuster = PaymentAdjusterReal::new(); | ||
payment_adjuster.initialize_inner( | ||
service_fee_balance_minor, | ||
adjustment, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call it tx_fee_adjustment
analyzed_account: AnalyzedPayableAccount::new(account, 3_000_000_000), | ||
weight: 4_000_000_000, | ||
}; | ||
let weighted_accounts = vec![weighted_account(account_1), weighted_account(account_2)]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can create the weighted_accounts in the beginning of the test.
use masq_lib::constants::WALLET_ADDRESS_LENGTH; | ||
use std::fmt::Debug; | ||
|
||
const PRINT_RESULTS_OF_PARTIAL_COMPUTATIONS: bool = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can say RUN_DIAGNOSTICS
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node/src/accountant/payment_adjuster/disqualification_arbiter.rs:383
|
||
#[derive(Debug, PartialEq, Eq)] | ||
pub struct DisqualificationSuspectedAccount<'account> { | ||
pub wallet: &'account Wallet, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you store an Address here (which implements Copy), can help you get rid of unnecessary lifetimes.
Ordering::Equal => with_smallest_weight_so_far, | ||
}, | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better alternative to fold()
is min_by_key()
.
https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min_by_key
In case min_by_key
fails to serve you, you can use min_by
- https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min_by
pub disqualification_limit_minor: u128, | ||
} | ||
|
||
impl<'unconfirmed_accounts> From<&'unconfirmed_accounts UnconfirmedAdjustment> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe move it to the file which contains all the from
implementations.
permanent_debt_allowed_minor: u128, | ||
) -> u128 { | ||
if threshold_intercept_minor == permanent_debt_allowed_minor { | ||
return account_balance_minor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning permanent_debt_allowed_minor
is better.
return account_balance_minor; | ||
} | ||
let exceeding_debt_part = account_balance_minor - threshold_intercept_minor; | ||
if DisqualificationGaugeReal::qualifies_for_double_margin( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you'd merge the if condition with the function qualifies_for_double_margin
(and rename it too), then you can return the required u128
.
let minimal_payment_accepted = exceeding_threshold + permanent_debt_allowed_minor; | ||
|
||
let first_condition = | ||
minimal_payment_accepted >= Self::FIRST_CONDITION_COEFFICIENT * considered_forgiven; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better if we make this condition lighter, by changing the constant's value to 1
.
exceeding_debt_part + permanent_debt_allowed_minor | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you can add the diagrams using a tool which converts "diagram into code comments", that would make the logic easier to understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/miscellaneous/helper_functions.rs:120
|
||
unconfirmed_adjustments.iter().for_each(|payable| { | ||
// Condition of disqualification at the horizontal threshold | ||
assert!(payable.proposed_adjusted_balance_minor < 120_000_000_000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's assert on the exact proposed balance. It's preferable if you sort it and you directly put the numbers in the assert.
} | ||
|
||
fn make_dsq_suspected_accounts( | ||
accounts_and_dsq_edges: &[UnconfirmedAdjustment], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's rename it to accounts
|
||
#[derive(Debug, PartialEq, Eq)] | ||
pub struct AdjustmentIterationResult { | ||
pub decided_accounts: DecidedAccounts, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you'd call this field decided_accounts_opt
and also make it an Option. Then we can safely eliminate the type DecidedAccounts
.
} | ||
} | ||
|
||
pub struct TransactionCountsBy16bits { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the first glance, By16bits
seemed like a mandatory constrain, since it's not, we decided to keep the name TransactionCounts
.
let result = corrections_from_u16_max | ||
.into_iter() | ||
.map(plus_minus_correction_for_u16_max) | ||
.map(U256::from) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's collect this vector first inside a variable and then use it to calculate result.
pub fn sum_as<N, T, F>(collection: &[T], arranger: F) -> N | ||
where | ||
N: From<u128>, | ||
F: Fn(&T) -> u128, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you can make it more generic and it doesn't care about u128
it'll be even better.
collection.iter().map(arranger).sum::<u128>().into() | ||
} | ||
|
||
pub fn weights_total(weights_and_accounts: &[WeightedPayable]) -> u128 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd prefer to use the guts directly instead of this wrapper function.
.collect() | ||
} | ||
|
||
fn sort_in_descendant_order_by_weights(unsorted: Vec<WeightedPayable>) -> Vec<WeightedPayable> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to use descending
instead.
}) | ||
.collect::<Vec<u128>>(); | ||
find_largest_u128(&diffs) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may like to use the max()
instead.
account_info.proposed_adjusted_balance_minor | ||
}); | ||
|
||
let cw_reminder = original_cw_service_fee_balance_minor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can call it cw_remaining
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:87
} else { | ||
not_exhausting_cw_balance_diagnostics(&non_finalized_account); | ||
|
||
status.add(non_finalized_account) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of add()
, let's call it append()
, and also for the handle fn, we can say update_balance_and_append()
.
If we split the duties of the handle_balance_update_and_add
, such that we only update the balance inside the if clause and append the account to the vector outside the if-else, it would be better.
} | ||
|
||
struct ConsumingWalletExhaustingStatus { | ||
remainder: u128, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We decided to call this remaining_cw_balance
in the other place, so let's use that here too.
use std::time::SystemTime; | ||
|
||
#[test] | ||
fn found_zero_affordable_accounts_found_returns_true_for_non_finalized_accounts() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The word found
in the test name is an extra.
} | ||
|
||
#[test] | ||
fn found_zero_affordable_accounts_returns_true_for_finalized_accounts() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too.
} | ||
|
||
#[test] | ||
fn found_zero_affordable_accounts_returns_false_for_finalized_accounts() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also here 😢
} | ||
|
||
#[test] | ||
fn three_non_exhaustive_accounts_all_refilled() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A suggested name: proposed_balance_refills_to_original_balance_for_all_three_non_exhaustive_accounts
.
fn three_non_exhaustive_accounts_all_refilled() { | ||
// A seemingly irrational situation, this can happen when some of those originally qualified | ||
// payables could get disqualified. Those would free some means that could be used for | ||
// the other accounts. In the end, we have a final set with suboptimal balances, despite |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of In the end, we have
, you'd like to say Therefore, we have
.
Result<Either<Vec<QualifiedPayableAccount>, AdjustmentAnalysis>, PaymentAdjusterError>; | ||
|
||
pub trait PaymentAdjuster { | ||
fn search_for_indispensable_adjustment( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd like to call it consider_adjustment
. That's an exceptionally simple name and I love it.
// and sticking it inside the vector that stores them. | ||
|
||
pub type AdjustmentAnalysisResult = | ||
Result<Either<Vec<QualifiedPayableAccount>, AdjustmentAnalysis>, PaymentAdjusterError>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You wanted to give an alias to Vec<QualifiedPayableAccount>
. You may use the name UnadjustedAccounts
.
now: SystemTime, | ||
) -> Result<OutboundPaymentsInstructions, PaymentAdjusterError>; | ||
|
||
as_any_ref_in_trait!(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you don't need to keep this anymore, go for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:203
self.initialize_inner( | ||
initial_service_fee_balance_minor, | ||
required_adjustment, | ||
largest_exceeding_balance_recently_qualified, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a point to rename this, if you do rename it, reuse it.
PS: I've made peace with this name, I'd prefer if you'd not change it at all.
let largest_exceeding_balance_recently_qualified = | ||
find_largest_exceeding_balance(&analyzed_payables); | ||
|
||
self.initialize_inner( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we wrap the inner with a Refcell, we won't need to use &mut self
, we can use &self
. Since, this function returns something it's ideal.
now, | ||
); | ||
|
||
let sketched_debug_info_opt = self.sketch_debug_info_opt(&analyzed_payables); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want to confuse info
with the log level here, so prefer a rename sketch_debug_log_opt
. We want to do the same on line 133 with the function complete_debug_info_if_enabled()
.
Also, don't forget to rename the variable name.
now: SystemTime, | ||
) { | ||
let transaction_fee_limitation_opt = match required_adjustment { | ||
Adjustment::TransactionFeeInPriority { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call it Adjustment::BeginByTxFee
let weighted_accounts = self.calculate_weights(analyzed_accounts); | ||
let processed_accounts = self.propose_adjustments_recursively( | ||
weighted_accounts, | ||
TransactionAndServiceFeeAdjustmentRunner {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please take a look into the code to identify if we can keep either the enum Adjustment
or this struct. They both are differentiating between the same thing but resulting in different combinations.
A proposed idea was to not use this TransactionAndServiceFeeAdjustmentRunner {}
at all and instead use a boolean (checking if it's an initial call) with the old enum. You might need to use an Either
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:277
fn propose_adjustments_recursively<AR, RT>( | ||
&mut self, | ||
unresolved_accounts: Vec<WeightedPayable>, | ||
adjustment_runner: AR, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will go away.
Have a nice day! 👨💻👽
|
||
fn propose_adjustments_recursively<AR, RT>( | ||
&mut self, | ||
unresolved_accounts: Vec<WeightedPayable>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call it weighted_accounts
.
fn begin_with_adjustment_by_transaction_fee( | ||
&mut self, | ||
weighted_accounts: Vec<WeightedPayable>, | ||
already_known_affordable_transaction_count: u16, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call it transaction_count_limit
.
cw_service_fee_balance_minor, | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certain suggestions to names here:
fn make(
&self,
number_of_accounts: usize, // accounts_allowed_by_tx_fee_check
_required_service_fee_total: u128,
cw_service_fee_balance_minor: u128,
) -> PaymentAdjusterError {
PaymentAdjusterError::LateNotEnoughFeeForSingleTransaction {
// InsufficientServiceFeePostTxFeeAdjustment
original_number_of_accounts: self.original_number_of_accounts,
number_of_accounts,
original_service_fee_required_total_minor: self
.original_service_fee_required_total_minor,
cw_service_fee_balance_minor,
}
}
let error_factory = LateServiceFeeSingleTxErrorFactory::new(&weighted_accounts); | ||
|
||
let weighted_accounts_affordable_by_transaction_fee = | ||
dump_unaffordable_accounts_by_transaction_fee( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may use the name:
eliminate_accounts_by_tx_fee_limit()
)? { | ||
diagnostics!("STILL NECESSARY TO CONTINUE BY ADJUSTMENT IN BALANCES"); | ||
|
||
let adjustment_result_before_verification = self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A suggestion:
result_before_exhausting_cw_balance
fn propose_possible_adjustment_recursively( | ||
&mut self, | ||
weighed_accounts: Vec<WeightedPayable>, | ||
) -> Vec<AdjustedAccountBeforeFinalization> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a vague comment. I apologise for that.
It's here because I feel the need to refactor this function such that the recursive calls are visible inside the scope of the function.
If the function follows this criteria:
fn recursive_fn() -> Something {
if breaking_condition {
return Something;
} else {
recursive_fn()
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit of refactoring got us here, I hope you'll find it useful during your changes:
fn propose_possible_adjustment_recursively_new(
&mut self,
weighed_accounts: Vec<WeightedPayable>,
) -> Vec<AdjustedAccountBeforeFinalization> {
let disqualification_arbiter = &self.disqualification_arbiter;
let unallocated_cw_service_fee_balance =
self.inner.unallocated_cw_service_fee_balance_minor();
let logger = &self.logger;
let current_iteration_result = self.service_fee_adjuster.perform_adjustment_by_service_fee(
weighed_accounts,
disqualification_arbiter,
unallocated_cw_service_fee_balance,
logger,
);
let remaining_undecided_accounts = current_iteration_result.remaining_undecided_accounts;
let decided_accounts: Vec<AdjustedAccountBeforeFinalization> =
current_iteration_result.decided_accounts.into();
if remaining_undecided_accounts.is_empty() {
return decided_accounts;
}
if !decided_accounts.is_empty() {
self.adjust_remaining_unallocated_cw_balance_down(&decided_accounts)
}
let merged = if self.is_cw_balance_under_limit(&remaining_undecided_accounts) {
// Fast return after a direct conversion into the expected type
Self::add_decided_accounts(
convert_collection(remaining_undecided_accounts),
decided_accounts,
)
} else {
Self::add_decided_accounts(
self.propose_possible_adjustment_recursively(remaining_undecided_accounts),
decided_accounts,
)
};
diagnostics!(
"\nFINAL SET OF ADJUSTED ACCOUNTS IN CURRENT ITERATION:",
&merged
);
merged
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:422
.iter() | ||
.map(|payable| { | ||
( | ||
payable.qualified_as.bare_account.wallet.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope you'll use the Address
here in case of the Wallet
, it'll prevent clone()
.
fn complete_debug_info_if_enabled( | ||
&self, | ||
sketched_debug_info_opt: Option<HashMap<Wallet, u128>>, | ||
affordable_accounts: &[PayableAccount], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may call it fully_processed_accounts
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:807
PaymentAdjusterError::LateNotEnoughFeeForSingleTransaction { .. } => true, | ||
PaymentAdjusterError::AllAccountsEliminated => true, | ||
// We haven't needed to worry so yet, but adding an error not implying that | ||
// an insolvency was found out, might become relevant in the future. Then, it'll |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mentioned that the ,
in this sentence is wrong.
#[test] | ||
#[should_panic(expected = "Broken code: Called the null implementation of \ | ||
the unallocated_cw_service_fee_balance_minor() method in PaymentAdjusterInner")] | ||
fn payment_adjuster_new_is_created_with_inner_null() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's change the panic message to say:
The PaymentAdjuster Inner is uninitialised. It was detected while executing unallocated_cw_service_fee_balance_minor().
Also, inside the test, you want to replace result
with subject
.
#[test] | ||
fn search_for_indispensable_adjustment_happy_path() { | ||
init_test_logging(); | ||
let test_name = "search_for_indispensable_adjustment_gives_negative_answer"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test name is different.
Some(TestConfigForServiceFeeBalances { | ||
account_balances: Either::Right(vec![ | ||
gwei_to_wei::<u128, u64>(85), | ||
gwei_to_wei::<u128, u64>(15) - 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The u128
seems unnecessary here. There's a suggestion to use the _u64
with the numbers that are provided as arguments.
let input_3 = make_input_for_initial_check_tests( | ||
None, | ||
Some(TestConfigForTransactionFees { | ||
agreed_transaction_fee_per_computed_unit_major: 100, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be gas_price
.
agreed_transaction_fee_per_computed_unit_major: 100, | ||
number_of_accounts, | ||
estimated_transaction_fee_units_per_transaction: 55_000, | ||
cw_transaction_fee_balance_major: 100 * 3 * 55_000 - 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mentioned that you'd prefer (
here to isolate the - 1
.
|
||
let result = subject.search_for_indispensable_adjustment(qualified_payables, &*agent); | ||
|
||
assert_eq!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The analyzed_payables
should be declared right above this assertion.
Some(TestConfigForServiceFeeBalances { | ||
account_balances: Either::Right(vec![ | ||
gwei_to_wei::<u128, u64>(85), | ||
gwei_to_wei::<u128, u64>(15) + 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more time, we can use the _u64
.
|
||
let result = subject.search_for_indispensable_adjustment(qualified_payables, &*agent); | ||
|
||
assert_eq!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to keep analysed_payables
above this assertion.
} | ||
|
||
#[test] | ||
fn transaction_fee_balance_is_unbearably_low_but_service_fee_balance_is_fine() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you want throws_err_for_tx_fee_but_service_fee_balance_is_fine()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:1045
let number_of_accounts = 3; | ||
let (qualified_payables, agent) = make_input_for_initial_check_tests( | ||
Some(TestConfigForServiceFeeBalances { | ||
account_balances: Either::Left(vec![123]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're expecting 3
accounts, and the balance here is for 1
account. Maybe None
is good enough.
agreed_transaction_fee_per_computed_unit_major: 100, | ||
number_of_accounts, | ||
estimated_transaction_fee_units_per_transaction: 55_000, | ||
cw_transaction_fee_balance_major: 54_000 * 100, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make it closer to the edge with (55_000 * 100) - 1
.
let result = subject.search_for_indispensable_adjustment(qualified_payables, &*agent); | ||
|
||
let per_transaction_requirement_minor = | ||
TRANSACTION_FEE_MARGIN.add_percent_to(55_000 * gwei_to_wei::<u128, u64>(100)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is noticed in different tests, and you'd want to change it everywhere in the codebase. The idea is to pass the type along with the numerals.
Let's rename TRANSACTION_FEE_MARGIN
-> TX_FEE_MARGIN_IN_PERCENT
.
cw_balance_minor: cw_service_fee_balance_minor, | ||
}); | ||
let (qualified_payables, agent) = | ||
make_input_for_initial_check_tests(service_fee_balances_config_opt, None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to revisit how the disqualification limit is picked. You should iterate through qualified_payables
and choose some value for each. Make sure that PaymentThresholdIntercept == PermanentDebtAllowed
. Let's add a comment too. 😉
cw_transaction_fee_balance_minor: U256::zero(), | ||
}), | ||
service_fee_opt: Some(ServiceFeeImmoderateInsufficiency { | ||
total_service_fee_required_minor: multiple_by_billion(500), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another Idea would be to create a constant:
const BILLION = 1_000_000_000;
service_fee_opt: None | ||
}, | ||
"Current transaction fee balance is not enough to pay a single payment. Number of \ | ||
canceled payments: 4. Transaction fee per payment: 70,000,000,000,000 wei, while \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's create a card for this (not a high priority, since it's just cosmetics). The intention is to use a better method to display these numbers such that a higher unit is picked, such that the number can be represented using multiple zeros.
( | ||
PaymentAdjusterError::AllAccountsEliminated, | ||
"The adjustment algorithm had to eliminate each payable from the recently urged \ | ||
payment due to lack of resources.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call the error: RecursionDrainedAllAccounts
.
And the string to: "The payment adjuster wasn't able to compose any combination of payables that can be paid immediately with provided finances."
} | ||
|
||
#[test] | ||
fn tinier_but_larger_in_weight_account_is_prioritized_and_gains_up_to_its_disqualification_limit( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to discuss the name change or the test removal.
In case name change is picked, then a suggestion: account_with_larger_weight_is_prioritized_and_gains_up_to_its_disqualification_limit()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:1194
let mut account_2 = make_analyzed_account_by_wallet("def"); | ||
let wallet_2 = account_2.qualified_as.bare_account.wallet.clone(); | ||
let balance_2 = multiple_by_billion(2_500_000); | ||
let disqualification_limit_2 = multiple_by_billion(1_800_000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better if you create variables for weights here and you can supply them on line 1077.
None, | ||
Some(largest_exceeding_balance), | ||
None, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional: I think this could be done using a Builder Pattern. It'll prevent us from supplying None
values.
.determine_limit_result(disqualification_limit_1) | ||
.determine_limit_params(&determine_limit_params_arc); | ||
subject.disqualification_arbiter = | ||
DisqualificationArbiter::new(Box::new(disqualification_gauge)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole gauge can go away.
.unwrap(); | ||
|
||
// Let's have an example to explain why this test is important. | ||
prove_that_proposed_adjusted_balance_could_have_exceeded_the_original_value( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A new name suggestion:
illustrate_that_we_need_to_prevent_exceeding_the_original_value
unconfirmed_adjustments[1].wallet(), | ||
&wallet_of_expected_outweighed | ||
); | ||
// The weight of this account grew progressively due to the additional criterion added |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't want to use the
before additional criterion
. Instead you'd prefer due to an additional criterion used to calculate the sum
.
// Later it was changed to other policy. so called "outweighed" account gains automatically | ||
// a balance equal to its disqualification limit, also a prominent front position in | ||
// the resulting set of the accounts to pay out. Additionally, due to its favorable position, | ||
// it can be given a bit more from the remains still languishing in the consuming wallet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A modified version:
Later it was changed to a different policy, so called "outweighed" account gains automatically a balance equal to its disqualification limit. Still, later on it's very likely to be given a bit more from the remains languishing in the consuming wallet.
); | ||
assert_eq!( | ||
second_returned_account.proposed_adjusted_balance_minor, | ||
2_300_000_000_000_000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently, we want this value to be equal to the disqualification_limit
. All you need to do is to use the variable disqualification_limit_1
here.
balance_wei: balance_3, | ||
last_paid_timestamp: now.checked_sub(Duration::from_secs(70_000)).unwrap(), | ||
pending_payable_opt: None, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better if you explain the disqualification process using a comment.
The way you explained this test to me verbally was more explanatory than the current state of the test (along with the comments), so please add them.
Note: While restating or removing and replacing the comment below with a new one, it would help a lot if we keep it more specific that which account outplays which one (at what stage) and the reason behind it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:1258
let calculator_mock = CriterionCalculatorMock::default() | ||
.calculate_result(multiple_by_billion(2_000_000_000)) | ||
.calculate_result(0) | ||
.calculate_result(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another explanation for how this mock is being differently.
fn adjustment_started_but_all_accounts_were_eliminated_anyway() { | ||
let test_name = "adjustment_started_but_all_accounts_were_eliminated_anyway"; | ||
let now = SystemTime::now(); | ||
let balance_1 = multiple_by_billion(3_000_000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A typo here: You want multiply
.
x | ||
), | ||
}; | ||
let agent = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment, it seems doable to use the old agent. Also, we're not even asserting on the id stamp, since all we want to look at is the error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs: 1664
balance_wei: balance_3, | ||
last_paid_timestamp: now.checked_sub(Duration::from_secs(160_000)).unwrap(), | ||
pending_payable_opt: None, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the timestamps should be the same, when I read the test, I thought these will cause some side effects that you want and think are necessary for the test. On the other hand, it just adds more confusion when figuring out the prioirity of the accounts.
I'd suggest you also create the variables for weights together with the accounts.
.calculate_result(multiple_by_billion(50_000_000_000)) | ||
.calculate_result(multiple_by_billion(50_000_000_000)); | ||
let mut subject = PaymentAdjusterReal::new(); | ||
subject.calculators.push(Box::new(calculator_mock)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd like to replace the real calculator with the mock.
You should try to refactor the test such that it is more explicit which account has the lowest priority. Also, you'd like to check how the values that are being generated for disqualification limit. So, you might want to hardcode them instead. Feel free to customise it according to your needs.
You want to check what happens if you remove the condition, this test is meant for. You'd like to change the act, so that it could be closer to the level where condition lives.
subject.logger = Logger::new(test_name); | ||
let agent_id_stamp = ArbitraryIdStamp::new(); | ||
let accounts_sum: u128 = balance_1 + balance_2 + balance_3; | ||
let service_fee_balance_in_minor_units = accounts_sum - ((balance_1 * 90) / 100); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd want to see it like this:
let service_fee_balance_in_minor_units = balance_2 + balance_3 + ((balance_1 * 10) / 100);
} | ||
|
||
#[test] | ||
fn overloading_with_exaggerated_debt_conditions_to_see_if_we_can_pass_through_safely() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of exaggerated_debt_conditions
we can say impossible_debt_sizes
.
let mut subject = PaymentAdjusterReal::new(); | ||
subject.logger = Logger::new(test_name); | ||
// In turn, tiny cw balance | ||
let cw_service_fee_balance = 1_000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd like to add minor
in the name of the variable.
CreditorThresholds::new(multiple_by_billion(permanent_debt_allowed_major)), | ||
) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want a line of demarcation here to separate the tests which have a happy path.
let balance_2 = multiple_by_billion(6_000_000_000); | ||
let qualified_account_2 = | ||
make_plucked_qualified_account("def", balance_2, 2_500_000_000, 2_000_000_000); | ||
let balance_3 = multiple_by_billion(6_666_666_666); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me it is quite appealing that balance_1 + balance_3 = 2 * balance_2.
I'd be spending a lot of time figuring out the relation if I'd be reading this test on my own. If this pattern is meaningless to you, then maybe eliminate it.
wallet_addr_fragment: &str, | ||
balance_minor: u128, | ||
threshold_intercept_major: u128, | ||
permanent_debt_allowed_major: u128, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An amazing idea would be if you pass the disqualification_limit
instead of threshold_intercept_major
and permanent_debt_allowed_major
, and you'll compute these values inside the function.
balance_1.separate_with_commas(), | ||
expected_adjusted_balance_1.separate_with_commas() | ||
); | ||
TestLogHandler::new().exists_log_containing(&log_msg.replace("|", "")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's really cool. 🎉
agent: Box::new(agent), | ||
adjustment_analysis: AdjustmentAnalysis::new( | ||
Adjustment::TransactionFeeInPriority { | ||
affordable_transaction_count: 2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's create a variable for the count somewhere during the preparatory statements of the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:1917
let balance_2 = multiple_by_billion(111_000_000); | ||
let account_2 = make_plucked_qualified_account("def", balance_2, 50_000_000, 10_000_000); | ||
// Account to be disqualified | ||
let balance_3 = multiple_by_billion(600_000_000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use these points as comments for the balances. I hope it'll be easier to figure out.
- Second Highest Weight, Partially Paid
- Highest Weight, Fully Paid
- Third Highest Weight, Disqualified
Note: Since you'd be moving the weights to preparatory statements in the other tests, you'd prefer to do the same to this test.
init_test_logging(); | ||
let test_name = "service_fee_as_well_as_transaction_fee_limits_the_payments_count"; | ||
let now = SystemTime::now(); | ||
let balance_1 = multiple_by_billion(100_000_000_000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some function like:
let balance_1 = to_quintillion(100);
} | ||
|
||
#[test] | ||
fn late_error_after_transaction_fee_adjustment_but_rechecked_transaction_fee_found_fatally_insufficient( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A new test name suggestion:
late_error_after_tx_fee_adjusted_but_rechecked_service_fee_found_fatally_insufficient
subject.logger = Logger::new(test_name); | ||
let disqualification_arbiter = DisqualificationArbiter::default(); | ||
let disqualification_limit_2 = | ||
disqualification_arbiter.calculate_disqualification_edge(&account_2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to calculate it by using the arbiter, instead you can take it out of the account.
let err = match result { | ||
Ok(_) => panic!("expected an error but got Ok()"), | ||
Err(e) => e, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should revisit the declaration of the agent, to make it use debug
. It would allow us to use unwrap_err()
here.
|
||
struct TestConfigForServiceFeeBalances { | ||
// Either gwei or wei | ||
account_balances: Either<Vec<u64>, Vec<u128>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can only use one unit, that'll be better, maybe Wei
, because precision is important.
number_of_accounts: usize, | ||
estimated_transaction_fee_units_per_transaction: u64, | ||
cw_transaction_fee_balance_major: u64, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can change agreed_transaction_fee_per_computed_unit_major
-> gas_price
and estimated_transaction_fee_units_per_transaction
-> tx_computation_units
Note: It's preferable if the rename can be done globally.
|
||
fn make_input_for_initial_check_tests( | ||
service_fee_balances_config_opt: Option<TestConfigForServiceFeeBalances>, | ||
transaction_fee_config_opt: Option<TestConfigForTransactionFees>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can just call them:
service_fee_config_opt
and tx_fee_config_opt
It'll be symmetric.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/mod.rs:2060
account_balances: Either::Left(vec![1, 1]), | ||
cw_balance_minor: u64::MAX as u128, | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you implement the Default
for TestConfigForServiceFeeBalances
. Then we could use the default()
directly inside the tests, and there won't be need of this function.
estimated_transaction_fee_units_per_transaction: 55_000, | ||
cw_transaction_fee_balance_major: u64::MAX, | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think inside the tests, we can do something like this.
let config = config_opt.unwrap_or(default_tx_fee_config(accounts_count));
}) | ||
.collect() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might like to refactor it using a new function:
fn prepare_payable_accounts_from(Either<Vec<u128>, u64>);
You may call this new function in both of the scopes of if-else statement.
.collect() | ||
} | ||
|
||
fn make_agent( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mentioned, it would be better if we use prepare_agent
instead of make_agent
.
let min = (current_result * 97) / 100; | ||
let max = (current_result * 97) / 100; | ||
assert_ne!(current_result, 0); | ||
assert!(min <= previous_result || previous_result <= max); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The two changes that we need here:
- The
min
andmax
should be different (97 and 103) - We can assert for not in the range by using
assert_ne!(min <= previous_result && previous_result <= max);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node/src/accountant/payment_adjuster/mod.rs:2191
let input_matrix: InputMatrixConfigurator = | ||
|(nominal_account_1, nominal_account_2, _now)| { | ||
vec![ | ||
// First test case: BalanceCalculator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe here you can say as a comment, "Test Case for only 1st Calculator"
|
||
#[test] | ||
fn defaulted_calculators_react_on_correct_params() { | ||
// When adding a test case for a new calculator, you need to make an array of inputs. Don't |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to make this sentence more explicit, "you need to make an array of inputs" -> "you need to make a 2-element array"
|
||
type InputMatrixConfigurator = fn( | ||
(QualifiedPayableAccount, QualifiedPayableAccount, SystemTime), | ||
) -> Vec<[(QualifiedPayableAccount, u128); 2]>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you prefer to convert this into a struct, I think it's good.
struct CalculatorTestScenario {
account: QualifiedPayableAccount,
expected_weight: u128
}
type InputMatrixConfigurator = fn([QualifiedPayableAccount; 2], SystemTime) -> Vec<[CalculatorTestScenario; 2]>
let mut account_2 = nominal_account_2; | ||
account_2.bare_account.balance_wei += 999_999_999; | ||
[(account_1, 8000001876543209), (account_2, 8000000999999999)] | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to add a comment here:
// Your new scenario for a unique calculator will live here
} | ||
|
||
struct ExpectedWeightWithWallet { | ||
wallet: Wallet, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I'd like Address
here instead of Wallet
.
now, | ||
cw_service_fee_balance_minor, | ||
); | ||
assert_eq!(template_computed_weight.common_weight, nominal_weight); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was an idea that you mentioned that you'd like to make nominal_weight
a constant. I think it's a great idea. Let's do that.
calculators_count, | ||
"If you've recently added in a new calculator, you should add in its new test case to \ | ||
this test. See the input matrix, it is the place where you should use the two accounts \ | ||
you can clone. Make sure you modify only those parameters processed by your new calculator " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you're asserting on equality this statement will make sense when the length of matrix is less than the calculators_count but if it's greater, the statement will loose it meaning.
Either change the assertion or the message according to your convenience.
cw_service_fee_balance_minor: u128, | ||
template_computed_weight: TemplateComputedWeight, | ||
) { | ||
fn prepare_args_expected_weights_for_comparison( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd like to rename this to prepare_inputs_with_expected_weights
.
); | ||
|
||
assert_results( | ||
weighted_accounts, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call this actual_weighted_accounts
.
} | ||
|
||
fn assert_results( | ||
weighted_accounts: Vec<WeightedPayable>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also here, actual_weighted_accounts
.
|
||
pub trait DisqualificationLimitProvidingAccount { | ||
fn disqualification_limit(&self) -> u128; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you can combine the trait, it'll be more concise:
So, if you think generic name is the only limitation, then this is the name we both came up with: AccountWithBalanceAndDisqLimit
where | ||
Product: BalanceProvidingAccount + DisqualificationLimitProvidingAccount, | ||
{ | ||
fn prepare_analyzable_account( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
provide_account_with_disqualification_limit
is a new name suggestion by @bertllll
} | ||
} | ||
|
||
// The thin term "outweighed account" coma from a phenomenon with an account whose weight |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want comes
instead of coma
.
// On the other hand, if it begins being clear that the remaining money can keep no other | ||
// account up in the selection there is yet another operation to come where the already | ||
// selected accounts are reviewed again in the order of their significance and some of | ||
// the unused money is poured into them, which goes on until zero. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you have some ideas to improve it, go ahead and do it...
fn handle_winning_accounts( | ||
unconfirmed_adjustments: Vec<UnconfirmedAdjustment>, | ||
) -> Either<Vec<UnconfirmedAdjustment>, AdjustmentIterationResult> { | ||
let (thriving_competitors, losing_competitors) = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call them accounts_above_disq_limit
and accounts_below_disq_limit
.
} | ||
|
||
#[derive(Default)] | ||
pub struct AdjustmentComputer {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there is no field stored in this struct (and in case we plan not to add it in a near future), I'd suggest, we convert this function implemented in the impl
block into a pure function.
.into_iter() | ||
.map(|weighted_account| { | ||
let proposed_adjusted_balance = | ||
compute_proposed_adjusted_balance(weighted_account.weight); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer if we limit the balance to the disqualification limit inside this function here.
If you want to keep the calculations for historical reasons, maybe prefer printing the diagnostics inside this function with both the over-computed and amended values.
|
||
lazy_static! { | ||
pub static ref MAX_POSSIBLE_SERVICE_FEE_BALANCE_IN_MINOR: u128 = | ||
MASQ_TOTAL_SUPPLY as u128 * 10_u128.pow(18); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd like to use the new to_quintillion()
function here.
pub static ref ONE_MONTH_LONG_DEBT_SEC: u64 = 30 * 24 * 60 * 60; | ||
} | ||
|
||
pub fn make_initialized_subject( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be better if we use the builder method here.
let disqualification_limit_minor = (3 * proposed_adjusted_balance_minor) / 4; | ||
let analyzed_account = | ||
AnalyzedPayableAccount::new(qualified_account, disqualification_limit_minor); | ||
let weight = (n as u128).pow(3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead multiply by a billion.
fn estimated_transaction_fee_total(&self, _number_of_transactions: usize) -> u128 { | ||
self.log_function_call("estimated_transaction_fee_total()"); | ||
fn estimated_transaction_fee_per_transaction_minor(&self) -> u128 { | ||
self.log_function_call("estimated_transaction_fee_per_transaction_minor()"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd like to change it to gas_price
.
let gwei_amount = ((77_777 + WEB3_MAXIMAL_GAS_LIMIT_MARGIN) as u128) * 244; | ||
gwei_to_wei(gwei_amount) | ||
}; | ||
assert_eq!(result, expected_result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you'd provide a number here, it's appreciated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue from node/src/accountant/payment_adjuster/non_unit_tests/mod.rs:295
(thresholds.maturity_threshold_sec + thresholds.threshold_interval_sec) as usize, | ||
) / 2 | ||
}; | ||
let debt_age = generate_age_segment() + generate_age_segment(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You told that generating the age from starting a number fairly different from 1 isn't right and instead you should start from maturity_threshold_sec.
Instead of dividing by 2
, you'd prefer to multiply it with 2/3
or 3/4
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/non_unit_tests/mod.rs:628
use thousands::Separable; | ||
use web3::types::U256; | ||
|
||
#[test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the location of the generated file:
node/generated/test/payment_adjuster/tests/home/loading_test_output.txt
Regarding adding a library, I don't want you to get in trouble with that. It might not produces anything substantial that you're happy with.
) / 2 | ||
}; | ||
let debt_age = generate_age_segment() + generate_age_segment(); | ||
let service_fee_balance_minor = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Computing the service fee balance raises a lot of questions. So a comment could be helpful here explaining that it basically provides different magnitudes in the produced numbers.
thresholds: Either<Vec<PaymentThresholds>, HashMap<Wallet, PaymentThresholds>>, | ||
} | ||
|
||
fn try_make_qualified_payables_by_applied_thresholds( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'd like to move this fn closer to make_payable_account
.
With 'AllAccountsEliminated':.......... {}\n\ | ||
With late insufficient balance errors:. {}\n\n\ | ||
Legend\n\ | ||
Partially adjusted accounts mark:...... {}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding an explanation of X
would be a good idea.
let balance_average = { | ||
let sum: u128 = sum_as(&qualified_payables, |account| account.balance_minor()); | ||
sum / accounts_count as u128 | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The numbers are picked by experimenting different values. (Empirical Values)
accounts | ||
.iter() | ||
.map(|account| AccountInfo { | ||
wallet: account.qualified_as.bare_account.wallet.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Address
will be more efficient.
let test_overall_output_collector = | ||
scenario_results | ||
.into_iter() | ||
.fold(overall_output_collector, |acc, scenario_result| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, let's use the same name as the variable by using shadowing.
.fold(overall_output_collector, |acc, scenario_result| { | ||
do_final_processing_of_single_scenario(&mut file, acc, scenario_result) | ||
}); | ||
let total_scenarios_evaluated = test_overall_output_collector |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you could make a method of this structure, it would be better.
+ test_overall_output_collector.oks | ||
+ test_overall_output_collector.all_accounts_eliminated | ||
+ test_overall_output_collector.late_immoderately_insufficient_service_fee_balance; | ||
write_brief_test_summary_into_file( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may include the word tail
here.
let ok_adjustment_percentage = (test_overall_output_collector.oks * 100) | ||
/ (total_scenarios_evaluated | ||
- test_overall_output_collector.scenarios_denied_before_adjustment_started); | ||
let required_success_rate = 70; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's replace rate
with percent
here and also in the required_pass_rate
. Maybe all the places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/preparatory_analyser/mod.rs
file: &mut File, | ||
overall_output_collector: &TestOverallOutputCollector, | ||
number_of_requested_scenarios: usize, | ||
total_of_scenarios_evaluated: usize, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you'd like to shorten the names with scenarios_requated
and scenarios_evaluated
.
) -> TestOverallOutputCollector { | ||
match scenario.result { | ||
Ok(positive) => { | ||
if positive.were_no_accounts_eliminated { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you'd like to just say, no_accounts_eliminated
.
.collected_fulfillment_percentages | ||
.push(positive.portion_of_cw_cumulatively_used_percents) | ||
} | ||
if positive.common.required_adjustment == Adjustment::ByServiceFee { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use matches!()
here too, for symmetry. - @bertllll
file.write_fmt(format_args!( | ||
"CW service fee balance: {} wei\n\ | ||
Portion of CW balance used: {}%\n\ | ||
Maximal txt count due to CW txt fee balance: {}\n\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found txt
a bit confusing, so please change it to tx
wherever possible.
Another suggestion by @bertllll - For symmetry add indentation so that all the data is in a column.
.separate_with_commas(), | ||
portion_of_cw_used_percents, | ||
resolve_affordable_transaction_count(&scenario_common.required_adjustment), | ||
resolve_comment_on_thresholds(&scenario_common.used_thresholds) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two fns can be converted into methods.
account, | ||
set_of_individual_thresholds_opt.map(|thresholds| { | ||
thresholds | ||
.get(&account.wallet()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the relation in HashMap is Address
-> PaymentThresholds
, it would be a bit more efficient.
|
||
const NON_EXHAUSTED_ACCOUNT_MARKER: &str = "# # # # # # # #"; | ||
|
||
fn resolve_account_ending_status_graphically( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of ending_status
it could be fulfilment_status
.
result_b.info.initially_requested_service_fee_minor, | ||
), | ||
) | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard to read. Please add the comment explaining that:
The priority order will be such that - Percentage Descending, Service Fee Ascending
Ord::cmp( | ||
&result_a.info.initially_requested_service_fee_minor, | ||
&result_b.info.initially_requested_service_fee_minor, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Descending order would be more appropriate here.
} | ||
|
||
impl AppliedThresholds { | ||
fn fix_individual_thresholds_if_needed( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call it switch_to_hashmap_if_needed
- @bertllll
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/payment_adjuster/preparatory_analyser/mod.rs:535
{ | ||
let number_of_accounts = qualified_payables.len(); | ||
let cw_transaction_fee_balance_minor = agent.transaction_fee_balance_minor(); | ||
let per_transaction_requirement_minor = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call it gas_price
.
number_of_accounts: usize, | ||
transaction_fee_check_result: Result<Option<u16>, TransactionFeeImmoderateInsufficiency>, | ||
service_fee_check_result: Result<(), ServiceFeeImmoderateInsufficiency>, | ||
) -> Result<Option<u16>, PaymentAdjusterError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if we create an alias here to identify ConstrainedTxCount
, it would make code more readable.
analyzed_accounts_count, | ||
required_service_fee_total, | ||
cw_service_fee_balance_minor, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps you could pass the prepared_accounts
in the make()
and would perform the computations there.
) { | ||
init_test_logging(); | ||
let determine_limit_params_arc = Arc::new(Mutex::new(vec![])); | ||
let disqualification_gauge = double_mock_results_queue(disqualification_gauge) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A different name: make_mock_results_doubled
(suggested by @bertllll )
.agreed_transaction_fee_margin_result(*TRANSACTION_FEE_MARGIN) | ||
.transaction_fee_balance_minor_result(U256::MAX) | ||
.estimated_transaction_fee_per_transaction_minor_result(123456) | ||
.service_fee_balance_minor_result(cw_service_fee_balance); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it could be migrated into a function, go ahead! 🫡
|
||
fn test_not_enough_for_even_the_least_demanding_account_causes_error<F, ErrorFactory, Error>( | ||
error_factory: ErrorFactory, | ||
expected_error_preparer: F, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another suggestion by @bertllll - prepare_expected_error
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue at node/src/accountant/scanners/mod.rs:325
} | ||
|
||
#[test] | ||
fn not_enough_for_even_the_least_demanding_account_error_right_after_positive_tx_fee_check() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A new name by @bertllll -
least_demanding_account_error_in_pre_adjustment_stage
fn not_enough_for_even_the_least_demanding_account_error_right_after_positive_tx_fee_check() { | ||
let error_factory = EarlyServiceFeeSingleTXErrorFactory::default(); | ||
|
||
let expected_error_preparer = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a better name
let original_number_of_accounts = original_accounts.len(); | ||
let initial_sum = sum_as(&original_accounts, |account| account.balance_minor()); | ||
let error_factory = LateServiceFeeSingleTxErrorFactory::new(&original_accounts); | ||
let expected_error_preparer = |number_of_accounts, _, cw_service_fee_balance_minor| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's rename the act here to say,prepare_expected_error
.
Please fix it in the previous test too.
} | ||
|
||
#[test] | ||
fn not_enough_for_even_the_least_demanding_account_error_right_after_tx_fee_accounts_dump() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here also, you want to start with just the least_demanding_account_...
#[test] | ||
fn not_enough_for_even_the_least_demanding_account_error_right_after_tx_fee_accounts_dump() { | ||
let original_accounts = vec![ | ||
make_weighed_account(123), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A small typo here - make_weighted_account
.balance_wei = balance_2; | ||
let accounts = vec![weighted_account_1, weighted_account_2]; | ||
let service_fee_totally_required_minor = balance_1 + balance_2; | ||
let cw_service_fee_balance_minor = service_fee_totally_required_minor + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a comment explaining why we're adding 1
here.
} | ||
|
||
fn double_mock_results_queue(mock: DisqualificationGaugeMock) -> DisqualificationGaugeMock { | ||
let originally_prepared_results = (0..2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call the variable popped_results
2
-> len_of_queue
4
-> 2 * len_of_queue
your balances can cover neither reasonable portion of any of those payables \ | ||
recently qualified for an imminent payment. You must add more funds into your \ | ||
consuming wallet in order to stay off delinquency bans that your creditors may \ | ||
apply against you otherwise. Details: {}.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use ChatGPT to reword into a single sentence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finally, it's done! 👏
You don't know how happy I am.
Good Luck with the changes, I wish you'll enjoy the process.
account, | ||
&self.common.payment_thresholds, | ||
now, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm particularly not fond of the idea to waste your time on asking you to refactor this change but if you'd like to spare some time on this function then please take a look whether we can construct PayableInspector
with PaymentThresholds
so that we don't need to pass a reference here.
@@ -801,7 +835,7 @@ impl PendingPayableScanner { | |||
} | |||
} | |||
|
|||
fn add_to_the_total_of_paid_payable( | |||
fn add_percent_to_the_total_of_paid_payable( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's revert it back to it's original name here.
@@ -1276,7 +1325,7 @@ mod tests { | |||
let test_name = "payable_scanner_can_initiate_a_scan"; | |||
let now = SystemTime::now(); | |||
let (qualified_payable_accounts, _, all_non_pending_payables) = | |||
make_payables(now, &PaymentThresholds::default()); | |||
make_unqualified_and_qualified_payables(now, &PaymentThresholds::default()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please call this function to make_qualified_and_unqualified_payables
because the first argument of the returned tuple is qualified payables.
self | ||
) | ||
&mut self.receivable_dao_factory, | ||
ReceivableDaoFactoryMock::new(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two changes:
- Let's append
_opt
in the name of the factory. - You can convert the argument of this function to
Either
so that it accepts only one.
@@ -1086,6 +1099,9 @@ impl PayableScannerBuilder { | |||
payable_dao: PayableDaoMock::new(), | |||
pending_payable_dao: PendingPayableDaoMock::new(), | |||
payment_thresholds: PaymentThresholds::default(), | |||
payable_inspector: PayableInspector::new(Box::new( | |||
PayableThresholdsGaugeReal::default(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's provide a Mock instead.
adjust_payments_results: RefCell<Vec<OutboundPaymentsInstructions>>, | ||
Arc<Mutex<Vec<(Vec<QualifiedPayableAccount>, ArbitraryIdStamp)>>>, | ||
search_for_indispensable_adjustment_results: RefCell< | ||
Vec<Result<Either<Vec<QualifiedPayableAccount>, AdjustmentAnalysis>, PaymentAdjusterError>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you create a Type for the Either
part, then don't forget to modify the code in the mocks too.
@@ -1699,3 +1734,88 @@ impl ScanSchedulers { | |||
} | |||
} | |||
} | |||
|
|||
pub fn make_non_guaranteed_qualified_payable(n: u64) -> QualifiedPayableAccount { | |||
// Without guarantee that the generated payable would cross the given thresholds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// It's not guaranteed that the payables would cross the given thresholds.
QualifiedPayableAccount::new( | ||
make_payable_account(n), | ||
n as u128 * 12345, | ||
CreditorThresholds::new(111_111_111), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't be hardcoding the creditor thresholds ans instead you should be using the n
.
} | ||
|
||
pub fn make_analyzed_account(n: u64) -> AnalyzedPayableAccount { | ||
AnalyzedPayableAccount::new(make_non_guaranteed_qualified_payable(n), 123456789) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too, use the n
for the second argument.
No description provided.