-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
auth: Don't recalculate mempool fees for every msg signer, misc. cleanup #2376
Conversation
This PR begins improving the godocs for the auth module, and begins cleaning up the Ante handler. Additionally we previously calculated if the fee was sufficient for the tx on every single signer. This is now refactored to be more efficient, and have a better logical flow. No changelog entry as this is new to this release.
4139680
to
68ee2eb
Compare
Codecov Report
@@ Coverage Diff @@
## develop #2376 +/- ##
===========================================
- Coverage 63.54% 63.53% -0.02%
===========================================
Files 120 120
Lines 7236 7250 +14
===========================================
+ Hits 4598 4606 +8
- Misses 2326 2333 +7
+ Partials 312 311 -1 |
// first sig pays the fees | ||
// Can this function be moved outside of the loop? | ||
if i == 0 && !fee.Amount.IsZero() { | ||
newCtx.GasMeter().ConsumeGas(deductFeesCost, "deductFees") |
There was a 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 removed charging gas for deducting fees, because that's silly lol
I just realized the diff for this is kind of hard to review, because I re-ordered things to be in more of (what I consider) to be a logical ordering. To ease reviewing this, I'll try commenting where everything that was deleted was moved to |
@@ -36,13 +33,17 @@ func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler { | |||
return ctx, sdk.ErrInternal("tx must be StdTx").Result(), true | |||
} | |||
|
|||
// set the gas meter | |||
if simulate { | |||
newCtx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved to setGasMeter method.
@@ -66,64 +67,48 @@ func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler { | |||
if err != nil { | |||
return newCtx, err.Result(), true | |||
} | |||
|
|||
sigs := stdTx.GetSignatures() // When simulating, this would just be a 0-length slice. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simply renamed to stdSigs to distinguish from it being the actual cryptographic signature as was previously implied.
// charge gas for the memo | ||
newCtx.GasMeter().ConsumeGas(memoCostPerByte*sdk.Gas(len(stdTx.GetMemo())), "memo") | ||
|
||
// Get the sign bytes (requires all account & sequence numbers and the fee) | ||
sequences := make([]int64, len(sigs)) | ||
accNums := make([]int64, len(sigs)) |
There was a 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 need for these was removed by getting the accounts directly with getSignerAccounts, and getSignBytesList
|
||
// first sig pays the fees | ||
// Can this function be moved outside of the loop? | ||
if i == 0 && !fee.Amount.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.
This code was moved outside of the for loop (right above it!)
x/auth/ante.go
Outdated
fck.addCollectedFees(newCtx, fee.Amount) | ||
for i := 0; i < len(stdSigs); i++ { | ||
// check signature, return account with incremented nonce | ||
res = processSig(newCtx, signerAccs[i], stdSigs[i], signBytesList[i], simulate) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored to have this take in the account for clarity. Additionally, it now has sequence / account number done separately in validateAccNumAndSequence
. This means if theres an invalid accnum / seq num, that we don't any of the more expensive signature verifications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK from me. Looks very good indeed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ValarDragon -- just a minor remark, otherwise LGTM.
signerAcc, res := processSig(newCtx, am, signerAddr, sig, signBytes, simulate) | ||
// first sig pays the fees | ||
if !stdTx.Fee.Amount.IsZero() { | ||
signerAccs[0], res = deductFees(signerAccs[0], stdTx.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.
There is a FeePayer
method on a sdk.Tx
.
There was a 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 see it?
// Transactions objects must fulfill the Tx
type Tx interface {
// Gets the Msg.
GetMsgs() []Msg
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh its on StdTx. I don't think we should use that though, since we already have access to the signerAccs, and doesn't make sense to run that method to get it again. I'd be happy to just make feePayer := signerAccs[0]
for code clarity though.
I think we should just remove the feepayer method entirely, as its currently unused. If we want we can refactor this fee deduction as used here into its own method (I think that makes sense as well)
There was a 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 line of principle, it's not a bad idea to provide SDK clients with a convenience FeePayer
method. Having said that, it's clearly unused thus +1 for the removal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah just remove it as it's not part of the interface (and use feePayer
variable).
There was a 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 remove it, please mention it as a breaking change 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually using a feepayer variable looks weirder, since we need to update the entry in the array. I've removed the fee payer method though, and added an additional comment for clarity.
x/auth/ante.go
Outdated
} | ||
|
||
func getSignBytesList(chainID string, stdTx StdTx, stdSigs []StdSignature) ( | ||
signatureBytesList [][]byte) { |
There was a 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 we have this on the same line or move the arguments to the same line, took me a second to realize it was returning something?
x/auth/ante.go
Outdated
} else { | ||
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(stdTx.Fee.Gas)) | ||
// Ensure that the provided fees meet a minimum threshold for the validator, if this is a CheckTx. | ||
// This is for mempool purposes, and thus is only ran on check tx. |
There was a 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 local/subject mempool purposes,
only "run" on ...
x/auth/ante.go
Outdated
@@ -245,8 +241,9 @@ func consumeSignatureVerificationGas(meter sdk.GasMeter, pubkey crypto.PubKey) { | |||
} | |||
|
|||
func adjustFeesByGas(fees sdk.Coins, gas int64) sdk.Coins { | |||
gasCost := int64(float64(gas) * feeDeductionGasFactor) | |||
gasCost := int64(float64(gas) * gasPrice) |
There was a 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't use float64().
13f740f
to
344aab8
Compare
x/auth/ante.go
Outdated
@@ -245,8 +242,9 @@ func consumeSignatureVerificationGas(meter sdk.GasMeter, pubkey crypto.PubKey) { | |||
} | |||
|
|||
func adjustFeesByGas(fees sdk.Coins, gas int64) sdk.Coins { | |||
gasCost := int64(float64(gas) * feeDeductionGasFactor) | |||
gasCost := gas / gasPrice |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gasPrice is a misnomer, it's gasPerUnitCost.
Jae and I had a conversation about changing how we adjust fees by gas, to ensure it works well in the int64 range when we move to nano-atoms. I'll write a follow-up issue describing that conversation. I believe that is fairly independent of this PR, and that we should go ahead and merge this. |
Yeah @ValarDragon im Ok with that 👌 Be sure to reference this issue in the new one I guess. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK
This PR begins improving the godocs for the auth module, and begins cleaning
up the Ante handler to (imo) improve efficiency and be safer.
Additionally we previously calculated if the fee was sufficient for the mempool
on every single signer. This is now refactored to be only done once, thereby being more efficient,
and to have a better logical flow. No changelog entry as mempool is new to this release.
This PR does another thing. It moves all checks before verifying any signatures, so that if something was wrong we didn't waste unnecessary time.
For Admin Use: