-
Notifications
You must be signed in to change notification settings - Fork 547
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
Increase test coverage for transaction pool module #16415
base: compatible
Are you sure you want to change the base?
Conversation
!ci-build-me |
I like the idea of extraction of transaction pool tests to a standalone file. Let's restructure the PR in the following way:
|
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.
Review is still in progress, posting the first few comments...
if Keypair.equal test_keys.(n) x then n | ||
else find_in_test_keys x ~n:(n+1) | ||
|
||
let create key_idx balance nonce = |
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 remove this function and create values directly
src/lib/network_pool/test_utils.ml
Outdated
Mina_ledger.Ledger.apply_initial_ledger_state new_ledger init_ledger_state ; | ||
t.best_tip_ref := new_ledger | ||
|
||
let ledger_snapshot 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.
Suggest to inline it into src/lib/network_pool/transacation_pool_reorg_tests.ml
and return Account_spec.t
instead of a tuple
let apply_payment amount fee t = | ||
create t.key_idx (t.balance - amount - fee) (t.nonce + 1) | ||
|
||
let apply_zkapp fee t = create t.key_idx (t.balance - fee) (t.nonce + 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.
Are all zkapps in this test created with with zero account updates?
If so, this looks ok, but let's add a comment in the code about this matter.
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 name is misleading. apply_zkapp function in context of account_spec is only modify spec state which we are using for tracking balance and nonce. So no zkapp command or update is done. Just noting that from this account zkapp was sent and we are deducting fee and increases nonce
let minor_acc_opt = Array.find_map minor ~f:(fun minor_acc -> | ||
Array.find major ~f:(fun major_acc -> | ||
Int.equal minor_acc.nonce major_acc.nonce && | ||
minor_acc.balance - major_acc.balance < 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.
What is the chance that such two accounts won't be found?
Won't the probability of the test being executed be too low?
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.
What if we:
- pick a random account with initial balance
B
(which won't be used in a generator for other transactions) - generate two random sequences
s1
ands2
(small, 2-10 transactions) of transactions using it, which won't use more thanB/2
MINA in total, let's assume|s1| < |s2|
- calculate total balance spent in sequence
s1
asb1
- select a number
i
:|s1| < i < |s2|
- calculate sum
t2
as balance spent by transactions ins2
with index range[|s1|, i)
- increase amount of a random transaction in
s1
byB - b1 - t2
- inject the resulting sequences
s1
ands2
randomly into major and minor sequences (at random indices, preserving order)
This way we deterministically have a use case, not on the luck (later sounds a bit more complicated to analyze than it should be, to my taste). Also, I am not sure if the current method is correct at all.
; ("major accounts state", `List log_major_accounts_state) | ||
]; | ||
|
||
let prefix = gen_commands_from_specs (Array.concat [prefix_specs]) test in |
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.
Why not simply let prefix = gen_commands_from_specs prefix_specs test in
??
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 didn't see it. thanks!
let minor_acc_opt = Array.find_map minor ~f:(fun minor_acc -> | ||
Array.find major ~f:(fun major_acc -> | ||
Int.equal minor_acc.nonce major_acc.nonce && | ||
minor_acc.balance - major_acc.balance < 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.
What if we:
- pick a random account with initial balance
B
(which won't be used in a generator for other transactions) - generate two random sequences
s1
ands2
(small, 2-10 transactions) of transactions using it, which won't use more thanB/2
MINA in total, let's assume|s1| < |s2|
- calculate total balance spent in sequence
s1
asb1
- select a number
i
:|s1| < i < |s2|
- calculate sum
t2
as balance spent by transactions ins2
with index range[|s1|, i)
- increase amount of a random transaction in
s1
byB - b1 - t2
- inject the resulting sequences
s1
ands2
randomly into major and minor sequences (at random indices, preserving order)
This way we deterministically have a use case, not on the luck (later sounds a bit more complicated to analyze than it should be, to my taste). Also, I am not sure if the current method is correct at all.
let gen_branches init_ledger_state ~permission_change ~limited_capacity ?(sequence_max_length=3) () = | ||
let open Quickcheck.Generator.Let_syntax in | ||
let%bind prefix_length = Int.gen_incl 1 sequence_max_length in | ||
let%bind branch_length = Int.gen_incl 1 sequence_max_length in |
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 generate sequence length separately for minor and major, they do not have to be the same
Otherwise it will be dropped as we already have transaction with the same nonce from major sequence | ||
*) | ||
let sender = major.(sender.key_idx) in | ||
let%bind aux_minor_cmd = Command_spec.gen_single_from minor (sender.key_idx,sender) in |
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 logic won't imitate the required behavior if maj1 >= min1
, where maj1
and min1
represent the number of txs from sender
in major
and minor
respectively.
I.e. aux_minor_cmd
will simply be thrown away. We need to add as many aux cmds as necessary to ensure that resulting minor sequence has more transactions from sender than major.
*) | ||
let%bind permission_change_cmd = Command_spec.gen_zkapp_blocking_send major in | ||
let sender = Command_spec.sender permission_change_cmd in | ||
(* We need to increase nonce so transaction has a chance to be placed in the pool. |
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.
where is the actual increase happening?
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.
In gen_single_from function
let%bind receiver_idx = test_keys |> Array.mapi ~f:(fun i _-> i) |> Quickcheck_lib.of_array in | ||
let%bind amount = Int.gen_incl 5_000_000_000_000 10_000_000_000_000 in | ||
let new_account_spec = Account_spec.apply_payment amount minimum_fee account_spec in | ||
Array.set spec idx new_account_spec; |
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.
What if balance goes negative? Perhaps we set amount to 0
if amount is less than balance. And if balance is less than min fee, throw an exception.
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.
Case of fee applies to zkapp tx above as well
]; | ||
|
||
let assert_pool_contains pool_state (pk,nonce)= | ||
let actual_opt = List.find pool_state ~f:(fun (fee_payer_pk, actual_nonce ) -> |
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.
Rewrite this and next function: extract calculation of actual_opt
into a helper function
) | ||
in | ||
match account_spec with | ||
| Some account_spec -> |
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.
Extract sent_blocking_zkapp
, total_cost
out of match construction (put it before).
Rewrite match
without ifs:
| Some account_spec when sender.nonce < account_spec.nonce -> (..)
| Some account_spec when sent_blocking_zkapp major_specs pk -> (..)
| Some account_spec when account_spec.balance > total_cost -> (..)
| Some account_spec -> (..)
| None -> (..)
@@ -17,7 +17,7 @@ module Account_spec = struct | |||
; nonce: int | |||
} [@@deriving sexp] | |||
|
|||
let rec find_in_test_keys ?(n=0) (x:Keypair.t) = | |||
let find_in_test_keys (x : Keypair.t) = Array.findi_exn test_keys ~f:(fun _ -> Keypair.equal x) |> fst |
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.
And remove the two lines below
cb1b2ac
to
07d610b
Compare
…ds from limited account capacity with rest of commands
!ci-build-me |
!ci-build-me |
Increase coverage for ledger reorg functionality with new property based tests. Apart from general all valid commands generator one can also configure generator to send some edge cases (zkapp which blocking sending further transactions or replace small amount transaction with big amount transaction which should prevent from applying entire chain of commands due to balance drain) . Last commit propose reorganization of all transaction tests since reorg tests require mini test framework.
PR related to #16401
Tests currently are failing but after we merge above PR they should be green.
Notes to reviewer: