-
Notifications
You must be signed in to change notification settings - Fork 602
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
chore(perf): protorev tracker coin array #7240
Conversation
PropBufferBlocks float32 = 30 | ||
// number of blocks used as a calculation buffer (used to set actual voting period) | ||
PropBufferBlocksVotePeriod float32 = 8 |
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 now run multiple blocks a second both pre and post upgrade. The 30 prop buffer blocks are needed to allow enough time to pass for the upgrade prop for the upgrade height to not be in the past.
Amount: newTakerFeeForStakersCoins, | ||
// GetTakerFeeTrackerForStakers returns the taker fee for stakers tracker for all denoms that has been | ||
// collected since the accounting height. | ||
func (k Keeper) GetTakerFeeTrackerForStakers(ctx sdk.Context) []sdk.Coin { |
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 Getters, Getters by Denom, and Update logic follows the same pattern that protorev uses for tracking profits by denom.
) | ||
|
||
func (s *KeeperTestSuite) TestGetSetTakerFeeTrackerForStakersAndCommunityPool() { | ||
func (s *KeeperTestSuite) TestGetTakerFeeTrackerForStakersAndCommunityPool() { |
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 remove Setter logic in this test. We now only have Get and Update, where update only increases and does not overwrite.
x/poolmanager/taker_fee.go
Outdated
@@ -144,33 +144,39 @@ func (k Keeper) chargeTakerFee(ctx sdk.Context, tokenIn sdk.Coin, tokenOutDenom | |||
takerFeeAmtRemaining := takerFeeCoin.Amount | |||
if takerFeeCoin.Denom == defaultTakerFeeDenom { | |||
// Community Pool: | |||
if poolManagerParams.TakerFeeParams.OsmoTakerFeeDistribution.CommunityPool.GT(osmomath.ZeroDec()) { | |||
if poolManagerParams.TakerFeeParams.OsmoTakerFeeDistribution.CommunityPool.GT(osmomath.ZeroDec()) && takerFeeAmtRemaining.GT(osmomath.ZeroInt()) { |
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.
Notice I added && takerFeeAmtRemaining.GT(osmomath.ZeroInt())
I noticed in some local tests that its possible for there to be zero taker fee amt when taker fee for denom is 0, despite the fee distribution percent being non zero. This doesn't really do anything bad, but does include a zero entry to the tracker. Again, not likely on prod and even if it did happen its a non issue, but was just not clean.
if err != nil { | ||
ctx.Logger().Error("Error updating taker fee tracker for community pool by denom", "error", err) | ||
} |
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.
Notice for all the logs here, I just print the error to logs. My mindset is, a bug in the tracker logic should not prevent all swap actions from happening.
|
||
// KeyTakerFeeStakersProtoRevArray defines key to store the taker fee for stakers tracker coin array. | ||
KeyTakerFeeStakersProtoRevArray = []byte{0x08} | ||
|
||
// KeyTakerFeeCommunityPoolProtoRevArray defines key to store the taker fee for community pool tracker coin array. | ||
KeyTakerFeeCommunityPoolProtoRevArray = []byte{0x09} |
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 could have probably used the old key, but decided on using a new one to just prevent any possible unforeseen bugs.
…ified dependencies locally
poolManagerParams := s.App.PoolManagerKeeper.GetParams(ctx) | ||
poolManagerParams.TakerFeeParams.DefaultTakerFee = sdk.MustNewDecFromStr("0.01") | ||
s.App.PoolManagerKeeper.SetParams(ctx, poolManagerParams) | ||
|
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.
These needed to be added due to the && that was added to the taker fee logic. This test before was going through the loop with a taker fee of 0%, so now if it isn't set we just skip this logic.
app/upgrades/v22/upgrades.go
Outdated
// For sake of simplicity, we restart the taker fee tracker accounting height. | ||
keepers.PoolManagerKeeper.SetTakerFeeTrackerStartHeight(ctx, ctx.BlockHeight()) |
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.
Shouldn't we be keeping continuinity? THis is going to be much harder for every integrator for the future if we don't, no?
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.
Implemented here f19b819
@ValarDragon would appreciate an ack on the implementation so it doesn't get swept under the rug when merging
osmoutils/coin_helper.go
Outdated
@@ -127,3 +127,16 @@ func ConvertCoinArrayToCoins(coinArray []sdk.Coin) sdk.Coins { | |||
} | |||
return coins | |||
} | |||
|
|||
func ConvertCoinsToCoinArray(coins sdk.Coins) []sdk.Coin { |
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.
Im pretty sure you can do a type cast for this, seeing as sdk.Coins
is just a type alias.
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.
You are correct, calling []sdk.Coin(coinsObject) works, will implement this instead
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.
Done here ba0c68e
osmoutils/store_helper.go
Outdated
func GetCoinByDenomFromPrefix(ctx sdk.Context, storeKey storetypes.StoreKey, storePrefix []byte, denom string) (sdk.Coin, error) { | ||
store := prefix.NewStore(ctx.KVStore(storeKey), storePrefix) | ||
key := append(storePrefix, []byte(denom)...) | ||
|
||
bz := store.Get(key) | ||
if len(bz) == 0 { | ||
return sdk.NewCoin(denom, osmomath.ZeroInt()), nil | ||
} | ||
|
||
coin := sdk.Coin{} | ||
if err := coin.Unmarshal(bz); err != nil { | ||
return sdk.NewCoin(denom, osmomath.ZeroInt()), err | ||
} | ||
|
||
return coin, nil | ||
} |
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.
Shouldn't we only marshal the amount, since the key contains the denom?
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.
@ValarDragon Is there performance improvement if we just unmarshal the amount and then from that create a coin to return?
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:
- less data written/read
- (and therefore gas)
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.
Two things:
- Modified the key to use a separator for easier parsing of the denom from the key
- Did not modify protorev's kvstore since we are not changing their store like we are the taker fee store. Otherwise I would need to recreate the store to store ints instead of coins, which feels out of scope of this PR
…ified dependencies locally
osmoutils/store_helper.go
Outdated
store := prefix.NewStore(ctx.KVStore(storeKey), storePrefix) | ||
key := []byte(fmt.Sprintf("%s%s%s", storePrefix, "|", []byte(denom))) |
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.
were double prefixing by the store prefix, resulting in the odd behavior
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 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.
That LGTM
Closes: #XXX
What is the purpose of the change
This is Part 2/2 in protorev tracking perf changes.
This PR utilizes a new key store and tracks by denom key, which prevents us from having to serialize every coin whenever taker fees are tracked.
Side note: There were three proto rev trackers:
Testing and Verifying
Ran the query in E2E after the upgrade and noted that: