-
Notifications
You must be signed in to change notification settings - Fork 814
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
Refactor dex EndBlock to optimize store access #763
Conversation
), | ||
) | ||
minPrice = sdk.MinDec(minPrice, orderbook.Longs.Entries[longPtr].GetPrice()) | ||
maxPrice = sdk.MaxDec(maxPrice, orderbook.Longs.Entries[longPtr].GetPrice()) | ||
minPrice = sdk.MinDec(minPrice, longEntry.GetPrice()) // tony: need to revisit whether it's intended to use long entry price here. Keeping it as-is so that test expectations are met |
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.
@LCyson is it intentional here to use long entry price to get minPrice? not sure how minPrice is used with TriggeredOrder
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.
hm yea likely an issue here, minPrice should be the lowest short
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 leave it as it is for now, we already remove support for TRIGGER ORDER correct
return | ||
} | ||
|
||
func (k Keeper) GetTopNLongBooksForPairStarting(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, n int, startExclusive sdk.Dec) (list []types.OrderBookEntry) { |
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 add comment here - function description + parameters description
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.
added
defer iterator.Close() | ||
|
||
// Fast-forward | ||
// TODO: add iterator interface that allows starting at a certain subkey under prefix |
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 todo is to add a O(logn) access method to replace the current O(n) way we're doing this 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.
yeah
x/dex/utils/dec.go
Outdated
) | ||
|
||
func DecToBigEndian(d sdk.Dec) (res []byte) { | ||
// if d.IsNegative() { |
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.
remove comments
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
func DecToBigEndian(d sdk.Dec) (res []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.
is there a lib we can leverage, feel less error-prune in that way
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.
not really since Dec
is a cosmos struct, and cosmos doesn't have an encoding for Dec that preserves numerical ordering
) | ||
|
||
var DECS = []sdk.Dec{ | ||
sdk.MustNewDecFromStr("90.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.
can we add an overflow dec test case 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.
how to define an overflow dec? I thought dec is supposed to be immune to overflow
), | ||
) | ||
minPrice = sdk.MinDec(minPrice, orderbook.Longs.Entries[longPtr].GetPrice()) | ||
maxPrice = sdk.MaxDec(maxPrice, orderbook.Longs.Entries[longPtr].GetPrice()) | ||
minPrice = sdk.MinDec(minPrice, longEntry.GetPrice()) // tony: need to revisit whether it's intended to use long entry price here. Keeping it as-is so that test expectations are met |
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.
hm yea likely an issue here, minPrice should be the lowest short
@@ -3,49 +3,145 @@ package types | |||
import ( |
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 add unit tests for new functions in this file
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.
added
x/dex/types/unit.go
Outdated
Unit_NANO: sdk.NewDec(1_000_000_000), | ||
} | ||
|
||
func ConvertDecToStandard(unit Unit, dec sdk.Dec) sdk.Dec { |
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 this is only used by test package can we move this to unit_test
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 deleted it since it doesn't seem to be used anywhere
c.CachedEntries = append(c.CachedEntries, loaded...) | ||
} | ||
|
||
func (c *CachedSortedOrderBookEntries) SettleQuantity(ctx sdk.Context, quantity sdk.Dec) (res []ToSettle, settled sdk.Dec) { |
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.
ditto - add comment
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.
added
} else { | ||
newFirstAllocationIdx = idx | ||
if settled.Equal(quantity) { | ||
break |
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 should remove allocations[newFirstAllocationIdx] when all its quantity gets settled here right
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 the case where the order is fully settled before applying the current allocation. In other words the order book entry isn't exhausted yet - it still at least has this current allocation left
x/dex/types/orders.go
Outdated
Entries []OrderBookEntry | ||
DirtyEntries *datastructures.TypedSyncMap[string, OrderBookEntry] | ||
CachedEntries []OrderBookEntry | ||
currentPtr int |
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 init this in the new() function
f5c7cba
to
26eb3d0
Compare
for key, v := range keyToVal { | ||
store.Delete([]byte(key)) | ||
var val types.LongBook | ||
dexkeeper.Cdc.MustUnmarshal(v, &val) | ||
newKey := append(types.PairPrefix(val.Entry.PriceDenom, val.Entry.AssetDenom), keeper.GetKeyForPrice(val.Price)...) | ||
store.Set(newKey, v) | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
for key, v := range keyToVal { | ||
store.Delete([]byte(key)) | ||
var val types.ShortBook | ||
dexkeeper.Cdc.MustUnmarshal(v, &val) | ||
newKey := append(types.PairPrefix(val.Entry.PriceDenom, val.Entry.AssetDenom), keeper.GetKeyForPrice(val.Price)...) | ||
store.Set(newKey, v) | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map
), | ||
) | ||
minPrice = sdk.MinDec(minPrice, orderbook.Longs.Entries[longPtr].GetPrice()) | ||
maxPrice = sdk.MaxDec(maxPrice, orderbook.Longs.Entries[longPtr].GetPrice()) | ||
minPrice = sdk.MinDec(minPrice, longEntry.GetPrice()) // tony: need to revisit whether it's intended to use long entry price here. Keeping it as-is so that test expectations are met |
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 leave it as it is for now, we already remove support for TRIGGER ORDER correct
6d3edc7
to
ff7d17b
Compare
6a284ac
to
2514a53
Compare
@@ -292,23 +297,22 @@ | |||
iterCounter := len(validContractsInfo) | |||
endBlockerStartTime := time.Now() | |||
for len(validContractsInfo) > 0 { | |||
newValidContractsInfo, newOutOfRentContractsInfo, ctx, ok := contract.EndBlockerAtomic(ctx, &am.keeper, validContractsInfo, am.tracingInfo) | |||
newValidContractsInfo, newOutOfRentContractsInfo, failedContractToReasons, ctx, ok := contract.EndBlockerAtomic(ctx, &am.keeper, validContractsInfo, am.tracingInfo) |
Check warning
Code scanning / CodeQL
Panic in BeginBock or EndBlock consensus methods
telemetry.IncrCounter(float32(1), am.Name(), "total_unregistered_contracts") | ||
} | ||
validContractsInfo = am.getAllContractInfo(ctx) // reload contract info to get updated dependencies due to unregister above | ||
|
||
if len(failedContractToReasons) != 0 { | ||
dexutils.GetMemState(ctx.Context()).ClearContractToDependencies() |
Check warning
Code scanning / CodeQL
Panic in BeginBock or EndBlock consensus methods
3478d22
to
5267383
Compare
|
||
for longPtr >= 0 && shortPtr < len(orderbook.Shorts.Entries) && orderbook.Longs.Entries[longPtr].GetPrice().GTE(orderbook.Shorts.Entries[shortPtr].GetPrice()) { | ||
for longEntry, shortEntry := orderbook.Longs.Next(ctx), orderbook.Shorts.Next(ctx); longEntry != nil && shortEntry != nil && longEntry.GetPrice().GTE(shortEntry.GetPrice()); longEntry, shortEntry = orderbook.Longs.Next(ctx), orderbook.Shorts.Next(ctx) { |
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.
nit, can we split this into multiple lines or have a helper method? It's pretty hard to read
Describe your changes and provide context
dex
EndBlock would always load all order book entries before processing, even if there is no or very few incoming orders to match against. This PR changes it so that entries are only loaded as needed. The core logic changes are in:types/orders.go
exchange/limit_order.go
exchange/market_order.go
Migrations are needed due to order book entry key encoding changes, which are necessary to make order book entries sorted in store. There is also a new parameter added.
Testing performed to validate your change
unit test