-
Notifications
You must be signed in to change notification settings - Fork 637
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
imp(fee): capital efficient fee middleware #5571
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #5571 +/- ##
==========================================
- Coverage 81.22% 81.19% -0.04%
==========================================
Files 197 198 +1
Lines 15258 15284 +26
==========================================
+ Hits 12394 12410 +16
- Misses 2399 2406 +7
- Partials 465 468 +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.
generally lgtm! just a few small nits about testing/godocs/inline docs
"success: some refund amount", | ||
func() { | ||
// set the recv + ack fee to be greater than timeout fee so that the refund amount is non-zero | ||
fee = types.NewFee(sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(200))), defaultAckFee, defaultTimeoutFee) |
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.
do we need a new fee
testing var here? can't we just use continue using packetFee
and a const for 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.
It was defined previously. I didn't wanna remove it and break tests.
@@ -65,7 +65,7 @@ func (suite *FeeTestSuite) TestFeeTransfer() { | |||
) | |||
|
|||
suite.Require().Equal( | |||
fee.AckFee.Add(fee.TimeoutFee...), // ack fee paid, timeout fee refunded | |||
fee.AckFee, // ack fee paid, no refund needed since timeout_fee = recv_fee + ack_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.
i find this comment slightly confusing, it's more that the timeout fee wasn't escrowed since it was smaller than the recv+ack, correct?
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 this case, there is equality due to hard-coded values
modules/apps/29-fee/types/fee.go
Outdated
@@ -60,8 +60,10 @@ func NewFee(recvFee, ackFee, timeoutFee sdk.Coins) Fee { | |||
} | |||
|
|||
// Total returns the total amount for a given Fee | |||
// The total amount is the Max(TimeoutFee, AckFee + RecvFee) |
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 just a bit more explicit that only the max of these two will actually be escrowed?
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 also indicate the reasoning for this decision (to efficiently escrow capital)?
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.
Superb work! I'm very happy with how few diffs there are for non test code! I think it'd be nice if we added some documentation for this behaviour? Maybe a quick section on the main docs? Feels like a behaviour that would be useful for users to find out about
modules/apps/29-fee/types/fee.go
Outdated
@@ -60,8 +60,10 @@ func NewFee(recvFee, ackFee, timeoutFee sdk.Coins) Fee { | |||
} | |||
|
|||
// Total returns the total amount for a given Fee | |||
// The total amount is the Max(TimeoutFee, AckFee + RecvFee) |
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 also indicate the reasoning for this decision (to efficiently escrow capital)?
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.
Great work!! I noticed the tests on refund are doing exactly the same logic as the distribution logic.
While this is correct, if for whatever reason the functions are not doing what we expected them to do, we won't catch it. Effectively, I don't think we're testing anything real since we're checking if assert(Z - A - B = Z - A - B)
I think I'd be a bit more confident, if you hardcoded the expected refund amount in the tests, at least where you are explicitly trying to assert refund logic is correct.
So something more like assert(Z - A - B = 15)
Everything else looks great, approved after that
Also, if the fees are all in one-denom, then we should definitely have tests that the multi-denom case works as we expect |
@colin-axner and @crodriguezvega, I will open a separate issue and PR for docs, since this PR is time sensitive and should not be blocked on documentation nits |
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.
Migration logic looks good! still have my point about tests. happy to defer to team on this
bump: #5571 (review)
@AdityaSripal I think the tests have a healthy mix of hard-coded (like defaultFees) and computed values. If all values were hard-coded, it'd have been a nightmare to update tests. Also, the current state of tests reflects the state of tests before the PR. I think such a refactor should be a separate issue if others agree to 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.
Code looks great, making my way through the tests. Figured I share this initial comment on the fee Total()
func
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.
Awesome work @srdtrk! I think I've finished looking through all the tests. Migration code looks great. We should wire up an upgrade handler and add an e2e test in a follow up.
I share the same feeling as @AdityaSripal wrt to hardcoding expected values in tests, might make them easier to parse!
// check if the refund acc has been refunded the timeoutFee & recvFee | ||
expectedRefundAccBal := refundAccBal.Add(defaultTimeoutFee[0]).Add(defaultRecvFee[0]).Add(defaultTimeoutFee[0]).Add(defaultRecvFee[0]) | ||
// check if the refund acc has been refunded the recvFee | ||
expectedRefundAccBal := refundAccBal.Add(defaultRecvFee[0]).Add(defaultRecvFee[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.
should this be adding the recv fee twice? or should it add the recv fee + ack 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.
It should be recv_fee
twice, this is because, in this test case, only the forward relayer address is invalid, therefore only the recv_fee
is refunded. The reason it is added twice is that, packetFee is paid twice in line 153
sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(0))), | ||
}, | ||
{ | ||
"success: multiple denoms", |
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 could add another test or two maybe we some different mutli denom variants too
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 an example where there's 3 different denoms and one of the fees doesn't contain it? something along those lines
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 added another test case. Can you 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.
Approving to not block merge. As @srdtrk says, we can come to consensus on tests later and apply uniformly
* feat: initial implementation * test: fixed keeper tests * test: fixed types tests * test: all tests passing * test: fixed fee callbacks test * feat: implemented migration * test: added migration tests * docs: updated godocs * imp: review items * imp: review items * imp: review items * docs: updated godocs * test: added multiple denoms test case for total * specify what the migration that fails does in error message --------- Co-authored-by: Carlos Rodriguez <carlos@interchain.io> (cherry picked from commit 6fc8159)
* feat: initial implementation * test: fixed keeper tests * test: fixed types tests * test: all tests passing * test: fixed fee callbacks test * feat: implemented migration * test: added migration tests * docs: updated godocs * imp: review items * imp: review items * imp: review items * docs: updated godocs * test: added multiple denoms test case for total * specify what the migration that fails does in error message --------- Co-authored-by: Carlos Rodriguez <carlos@interchain.io> (cherry picked from commit 6fc8159) Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>
}, | ||
}, | ||
{ | ||
"success: many fees with multiple denoms in escrow", |
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 nice to have a test case for different incentivized packets. If I understand correctly, this does only a single iteration. If I have the following diffs (removing iteration), the tests pass:
diff --git a/modules/apps/29-fee/keeper/migrations.go b/modules/apps/29-fee/keeper/migrations.go
index 3eae34f7e..5d5701e8f 100644
--- a/modules/apps/29-fee/keeper/migrations.go
+++ b/modules/apps/29-fee/keeper/migrations.go
@@ -27,19 +27,17 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error {
iterator := storetypes.KVStorePrefixIterator(store, []byte(types.FeesInEscrowPrefix))
defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() })
- for ; iterator.Valid(); iterator.Next() {
- feesInEscrow := m.keeper.MustUnmarshalFees(iterator.Value())
+ feesInEscrow := m.keeper.MustUnmarshalFees(iterator.Value())
- for _, packetFee := range feesInEscrow.PacketFees {
- refundCoins := legacyTotal(packetFee.Fee).Sub(packetFee.Fee.Total()...)
+ for _, packetFee := range feesInEscrow.PacketFees {
+ refundCoins := legacyTotal(packetFee.Fee).Sub(packetFee.Fee.Total()...)
- refundAddr, err := sdk.AccAddressFromBech32(packetFee.RefundAddress)
- if err != nil {
- return err
- }
-
- m.keeper.distributeFee(ctx, refundAddr, refundAddr, refundCoins)
+ refundAddr, err := sdk.AccAddressFromBech32(packetFee.RefundAddress)
+ if err != nil {
+ return err
}
+
+ m.keeper.distributeFee(ctx, refundAddr, refundAddr, refundCoins)
}
Description
closes: #5509
Commit Message / Changelog Entry
see the guidelines for commit messages. (view raw markdown for examples)
Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.
docs/
) or specification (x/<module>/spec/
).godoc
comments.Files changed
in the Github PR explorer.Codecov Report
in the comment section below once CI passes.