-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
R4R: blockly minting #2825
R4R: blockly minting #2825
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #2825 +/- ##
===========================================
+ Coverage 56.84% 56.89% +0.04%
===========================================
Files 120 120
Lines 8298 8321 +23
===========================================
+ Hits 4717 4734 +17
- Misses 3263 3268 +5
- Partials 318 319 +1 |
Tests run well locally for me, but I'm prob not the best one to review the core logic here. Looks like the implementation follows whats in #2763 however. LGTM |
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.
General structure LGTM, a few nits / questions.
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.
Left some initial minor feedback, otherwise great work @rigelrozanski ⚡️
Looks like we need to come to consensus on when to do decimal truncation and address the broken CI |
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.
Tested ACK
A few more minor comments which might be worth addressing.
@@ -48,3 +52,81 @@ func ValAccumInvariants(k distr.Keeper, sk distr.StakeKeeper) simulation.Invaria | |||
return nil | |||
} | |||
} | |||
|
|||
// DelAccumInvariants checks that each validator del accum == sum all delegators' accum | |||
func DelAccumInvariants(k distr.Keeper, sk distr.StakeKeeper) simulation.Invariant { |
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 great invariant but it is very slow, I wonder if we should make it periodic by 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.
I think we should leave it at every block until we upgrade for more capable feature set in the simulator - From a debugging perspective it's nice to not have to be an expert and just "know" that we should reset an invariant to be running each block when it fails to determine the location of the bug. I'm also not so worried about the speed of the simulator - this doesn't seem to be an issue as I've been running things locally.
To improve the speed let's focus on things like the ability to load the simulator from a simulated state etc.
As per running this every block on chain - yeah that seems like a performance issue - not sure how to adjust that (is this per block invariants stuff already merged? - feel free to push here to make that fix, or we could add another PR)
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 we should run this on-chain and not run it for blockchain syncing for new nodes... I think it would be nice to halt the chain as soon as we know that something is off, at least in the beginning.
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 do this very easily, just edit the runtime invariants in cmd/gaia/app/invariants.go
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.
(right now we aren't running it on-chain @rigelrozanski, you have to add it explicitly)
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 also not so worried about the speed of the simulator - this doesn't seem to be an issue as I've been running things locally.
OK, maybe it's just my slow laptop - but we should ensure we can still run 500/1000-block simulations as they do catch issues.
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.
Well, depends on how fast it is... checking...
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.
ahhhhhhs didn't realize how much slower this is
I think that we should probably add an option to just "enable" or "disable" slow invar checks for the simulation here... maybe a flag
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.
Hmm I much prefer periodic invariants, which achieve essentially the same speed benefit while still ensuring errors are caught (and once caught, you can disable periodicity to figure out the exact operation).
// DelegatorSharesInvariant checks whether all the delegator shares which persist | ||
// in the delegator object add up to the correct total delegator shares | ||
// amount stored in each validator | ||
func DelegatorSharesInvariant(k stake.Keeper) simulation.Invariant { |
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 a computationally expensive invariant, maybe it should be periodic by default
Co-Authored-By: rigelrozanski <[email protected]>
Co-Authored-By: rigelrozanski <[email protected]>
@@ -42,16 +50,49 @@ func (di DelegationDistInfo) WithdrawRewards(wc WithdrawContext, vi ValidatorDis | |||
vi = vi.UpdateTotalDelAccum(wc.Height, totalDelShares) | |||
|
|||
if vi.DelAccum.Accum.IsZero() { |
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 don't understand why this code block is necessary. It's a slight optimization maybe, but it increases surface area for bugs. Also, if vi.DelAccum.Accum.IsZero(), di.DelPoolWithdrawHeight I don't think would matter anyways (even though it would be correct to update the height here).
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.
hmmm - yeah maybe this is an “over-optimization” and we should just delete this whole block instead of adding this defensive 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.
Another note... when adding more shares to a delegation we were assuming that the withdrawal height was set previously.
so we should add a panic check when we modify the delegation shares, that the withdrawal height is set to the current height.
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 not saying we should add the panic after it was clearly updated. there’s a timeline of dependencies here… withdrawal <-------> further-add-to-delegation-shares currently we made the bug fix where we update the withdrawal height on the left hand side. we want the very far right hand side, which is not the highest level of code… it’s a bit deeper in the call stack.
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.
Refining my thinking...
I was trying to refer to (I think) in x/stake/keeper/distribution.go,
validator types.Validator, subtractAccount bool) (newShares sdk.Dec, err sdk.Error) {
...
// Get or create the delegator delegation
delegation, found := k.GetDelegation(ctx, delAddr, validator.OperatorAddr)
...
// call the appropriate hook if present
if found {
k.OnDelegationSharesModified(ctx, delAddr, validator.OperatorAddr)
} else {
k.OnDelegationCreated(ctx, delAddr, validator.OperatorAddr)
}
...
// Update delegation
delegation.Shares = delegation.Shares.Add(newShares)
delegation.Height = ctx.BlockHeight()
k.SetDelegation(ctx, delegation)
}
Was the problem that we were calling OnDelegateSharesModified here, but because the shares was zero, we didn't update the height?
Some thoughts... OnDelegatorSharesModified here should be called WillModifyDelegatorShares maybe, otherwise it appears to be a misnomer. WillCreateDelegation as well... since the delegation hasn't been created or modified yet. Or, maybe we can keep the old info and pass it into OnDelegationSharesModified. Not a big deal ATM, just pointing out an inconsistency.
If we had an DidModifyDelegationShares, we could add the check in the distribution keeper to check that the withdrawal height was modified. But also, maybe this isn't necessary.
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.
Agreed - ref #2538
Clip withdrawal tokens
closes #2763
REF #2846
docs/
)PENDING.md
with issue #Files changed
in the github PR explorerFor Admin Use: