Cosign tests - #710
Conversation
…, avoid overflow panic
This reverts commit 4a1cf91.
kayabaNerve
left a comment
There was a problem hiding this comment.
This is all exceptionally clear and straighforward tests (and bug fixes) for the cosign module I can say I'm incredibly happy with. While I've left a littany of comments, they're largely just review nits and style as we work together moving forward. The dedicated shim RPC really seems to be the way to go for testing re: the Serai node's behavior, even if I'm not entirely sold on all of the designs of fixtures/abstractions here. Thankfully, because they're test files, I can accept they work and be happy with them in that regard. The usage of coverage also really seems to have been great at clearly establishing all the test cases, and I appreciated the fuzz test re: intend.
| // this is a critical issue and will not be solved after re-tries, | ||
| // missing Stakes from previous blocks will remain missing until re-indexed | ||
| // if encountered halt the process | ||
| .expect("unable to deallocate with no prior existing stake"); |
There was a problem hiding this comment.
No, actually, but I see why you did this.
If a validator has never staked, they will have 0 allocated as stake.
If they then try to deallocate 0 stake, the amount they're deallocating is less than or equal to the amount allocated, so the system allows it.
It's silly, but it's something I've learned to do over the years. Specifically, it descends from rejecting transferring 0, which is pointless. The reason not to reject transferring 0 is because sometimes, you want to always issue a transfer on a regular basis (one a week), and some weeks, there may not be any value to transfer. When the regular operation occurs, it still occurs, it just transfers 0. If it errored, it may bork the regular operation and screw up the caller.
With that mind, as my personal practice, I write code to never bork on any legitimate amount, even if a silly amount.
There was a problem hiding this comment.
Yes but here it is checking for a previous indexed Stakes object, so it's just a sanity check in the case the task did not succesfully index a stake any size it is, but I added tests here:
To verify that given a stake event, and the existing Stake index, deallocate always works even if 0-denominated, or either stake and deallocate are 0.
But given you say
If a validator has never staked, they will have 0 allocated as stake.
should the stake just be considered 0,when hitting this case on deallocate, even if not indexed in a db, and pass, or should it be indexed as 0, for every existing validator beforehand to then also allow this to pass?
|
Per https://github.com/serai-dex/serai/blob/next-polkadot-sdk/LICENSE.md (which this caused me to add), please update the Also, should the utilities to test a task simply be part of |
… & re-word readme.md
This begins on serai-dex#315, defining the framework to do so and clarifying the role of `patches/`. It also begins with the first few audit statements, and updates some patches to reduce the size of our dependency tree at this time. Tangentially, in the CI, `--locked` is added for what-intended-to-be-pinned `cargo install`s.
- `fmt`, `clippy`, `machete`, `deny` - `serai-shim-rpc` was added to the CI, `Cargo.toml`, `deny.toml` - Original documentation restored when clearer (IMO) - Fixed cached evaluated cosign's lifetime, which should be cleared on global session change (a bug in the code prior to this PR) - Fixed how `HasEvents::No` early returned and missed the following log statements - Missing, non-linear blocks promoted to panics as they're fatal errors - Ensured non-existent validators could deallocate `0` - Minor formatting tweaks, including some lifetime reductions to clarify scope and ensure safety - Consolidated from `log` to `serai-env`
b298649 to
95ea47d
Compare
9719782 to
afb2e1f
Compare
|
Ugh. When I merged |
Changes:
common/task/src/lib.rs1) [bug] wrong usage of .max():
This line:
Had a bug. As the
.max()typedocs define:The intended use of
.max()here was to, given anew_sleeptime, and a maximum constant value inSelf::MAX_DELAY_BETWEEN_ITERATIONS, thenew_sleeptime should never be greater than the constant and if greater, always default the sleeping time to the constant's time instead. Otherwise, a forever increasingnew_sleepcould occur and hold tasks indefinitely.2) [feat] Made the addition of
test-helpersbehind a cargo flag, to help with the testing on the running of tasks.coordinator/cosign/src/intend.rs1) [bug] Zero-stake
Event::SetKeyswould panicIdentified a bug would panic every time on a Notable
Event::SetKeysevent where the total stake amounts to 0, and would always come back to panic preventing the cosign task from ever continuing. A 0 total stake notable event scenario is a possibility and this should be handled instead, for example at network's launch as there is a genesis period where liquidity is provided before any coins and any stake yet exist. The solution being adding the following:Where not only the
if stake > 0 {was added to guard the addition of aLatestSetbut alsohas_events = HasEvents::Notable;is only set as a Notable event type there to guard against the later condition that initiates a new global session for this event. Events with 0 stake don't need to be considered as Notable and can be skipped w.r.t. the cosigning protocol.2) [feat] Empty validator set from
Event::SetDecidedAdded a sanity check:
3) [bug] Block indexing start
The current implementation begins indexing by block 1, changed it to:
Otherwise gets the task permanently stuck with error
node's block #1 doesn't build upon the block #0 prior indexedif genesis was not indexed.coordinator/cosign/src/evaluator.rs1) [bug] added initial check for a global session because it is not possible to evaluate cosigns for a non-existing global session, so skip.
Now the evaluator initiates a new BlockEvent with:
2) [feat] added has_events to CosignedBlocks so delay can skip no event blocks
Now the db entry looks like:
and the addition of the
boolforhas_eventsallows the delay task to not need to sleep onHasEvents::Noblockscoordinator/cosign/src/delay.rs1) [feat] sanity check to avoid index regression
Simply made it consider skipping later blocks if already indexed, following a rule to not regress indexing.
2) [feat] skip no event blocks from delay
as explained above with the evaluator, this was added:
3) [bug] fixed the wrong calculation being used for the time to sleep
Now calculates as
coordinator/cosign/src/lib.rs1) [bug] fixed cosign task handles not being held and being dropped
Now uses a:
2) [bug] fixed Cosigning::latest_cosigned_block_number() always defaulting to 0, as if block 0 was already cosigned
Returns a
Result<Option<...>>instead:And is more clear when a block has actually been indexed/cosigned or not
Misc
Cargo.toml:unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage)'] }hides spammy warnings when running tests.coordinator/cosign/README.md: re-worded a bit the phrasing in an attempt to make it clearer at least to myself when re-reading