Skip to content
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

Merged
merged 42 commits into from
Jan 9, 2024
Merged

Conversation

czarcas7ic
Copy link
Member

@czarcas7ic czarcas7ic commented Jan 4, 2024

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:

  1. Tx fees: Is now removed
  2. Taker Fees: Modified to coin array here
  3. Cyclic Arb: We dont modify this logic, because it is called once at time of initialization, and then compared to the cyclic arb profits that protorev tracks and the difference is taken. It is not called on its own after every action like the taker fee and tx fee trackers

Testing and Verifying

Ran the query in E2E after the upgrade and noted that:

  1. The count resets
  2. The block height changes to the upgrade height as expected

Screenshot 2024-01-05 at 1 09 20 PM

@czarcas7ic czarcas7ic added the V:state/breaking State machine breaking PR label Jan 4, 2024
@czarcas7ic czarcas7ic marked this pull request as ready for review January 5, 2024 20:38
Comment on lines 17 to 19
PropBufferBlocks float32 = 30
// number of blocks used as a calculation buffer (used to set actual voting period)
PropBufferBlocksVotePeriod float32 = 8
Copy link
Member Author

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 {
Copy link
Member Author

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() {
Copy link
Member Author

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.

@@ -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()) {
Copy link
Member Author

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.

Comment on lines +156 to +158
if err != nil {
ctx.Logger().Error("Error updating taker fee tracker for community pool by denom", "error", err)
}
Copy link
Member Author

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.

Comment on lines +45 to +50

// 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}
Copy link
Member Author

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.

@czarcas7ic czarcas7ic closed this Jan 5, 2024
@czarcas7ic czarcas7ic reopened this Jan 5, 2024
@czarcas7ic czarcas7ic marked this pull request as draft January 5, 2024 20:51
@github-actions github-actions bot added the C:x/gamm Changes, features and bugs related to the gamm module. label Jan 5, 2024
Comment on lines +83 to +86
poolManagerParams := s.App.PoolManagerKeeper.GetParams(ctx)
poolManagerParams.TakerFeeParams.DefaultTakerFee = sdk.MustNewDecFromStr("0.01")
s.App.PoolManagerKeeper.SetParams(ctx, poolManagerParams)

Copy link
Member Author

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.

Comment on lines 26 to 27
// For sake of simplicity, we restart the taker fee tracker accounting height.
keepers.PoolManagerKeeper.SetTakerFeeTrackerStartHeight(ctx, ctx.BlockHeight())
Copy link
Member

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?

Copy link
Member Author

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

@@ -127,3 +127,16 @@ func ConvertCoinArrayToCoins(coinArray []sdk.Coin) sdk.Coins {
}
return coins
}

func ConvertCoinsToCoinArray(coins sdk.Coins) []sdk.Coin {
Copy link
Member

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.

Copy link
Member Author

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done here ba0c68e

Comment on lines 249 to 264
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
}
Copy link
Member

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?

Copy link
Member Author

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?

Copy link
Member

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)

Copy link
Member Author

@czarcas7ic czarcas7ic Jan 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  1. Modified the key to use a separator for easier parsing of the denom from the key
  2. 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

a27e3c8
a582fa1
c3f306d
c665113

@czarcas7ic czarcas7ic closed this Jan 8, 2024
@czarcas7ic czarcas7ic reopened this Jan 8, 2024
Comment on lines 274 to 275
store := prefix.NewStore(ctx.KVStore(storeKey), storePrefix)
key := []byte(fmt.Sprintf("%s%s%s", storePrefix, "|", []byte(denom)))
Copy link
Member

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That LGTM

@czarcas7ic czarcas7ic merged commit 227c44c into main Jan 9, 2024
1 check passed
@czarcas7ic czarcas7ic deleted the adam/protorev-tracker-perf branch January 9, 2024 21:36
@github-actions github-actions bot mentioned this pull request Jan 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C:app-wiring Changes to the app folder C:x/epochs C:x/gamm Changes, features and bugs related to the gamm module. C:x/poolmanager C:x/txfees V:state/breaking State machine breaking PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants