Skip to content

Commit

Permalink
Create the exchange module (#1661)
Browse files Browse the repository at this point in the history
* [1658]: get/set store stuff for the settlement flat fees.

* [1658]: Rename the key prefix makers to start with Get to set them apart from the full key makers a bit more.

* [1658]: Create a generic iterator and use that for the GetParams func.

* [1658]; Switch to a record separator byte to separate the price and fee denoms in the key. Create a suffix maker and parser for those keys too.

* [1658]: Most of the settlement ratio stuff.

* [1658]: Refactor IsAcceptableBuyerSettlementFee into ValidateBuyerSettlementFee to return more info about why a fee is insufficient.

* [1658]: Create keeper.getStore and use that everywhere. Write flat and ratio fee entry updaters.

* [1658]: The rest of the market store stuff: inactive bool, user-settle bool, permissions, and required attributes.

* [1658]: Add a last market id store entry and write CreateMarket(...).

* [1658]: Normalize the required attributes when storing them.

* [1658]: Fill out GovCreateMarket.

* [1658]: Add the endpoint comments to the msg server funcs.

* [1658]: Add a market id field to the update fees message and a last market id field to genesis.

* [1658]: Get rid of NewGenesisState since it doesn't do anything helpful. Make sure MsgGovManageFeesRequest has a market id.

* [1658]: Implement GovManageFees.

* [1658]: Create a GetMarket function.

* [1658]: Create a known market id set of entries in the store.

* [1658]: Break out a lot of the keeper funcs into versions that can take in a store.

* [1658]: Add some empty suffix/value tests to ParseKeySuffixSettlementRatio ParseFeeRatioStoreValue tests.

* [1659]: Refactor ParseFeeRatioStoreValue due to nakedret linter error.

* [1658]: Take care of the keys unit test TODOs I recently added.

* [1658]: Create IsBidOrder and IsAskOrder functions.

* [1658]: Refactor order state store plans; move the type byte into the value.

* [1658]: get/set/delete orders. Tweak some keys stuff related to order indexing.

* [1658]: Create index key parsers.

* [1658]: Create the index iterators.

* [1658]: Add the name keeper to the keeper and create CanCreateAsk and CanCreateBid.

* [1658]: Add some extra explanation to the req attrs fields.

* [1658]: Populate the create ask, create bid and cancel order messages.

* [1658]: Impliment Msg funcs for create ask, create bid, and cancel order. Fix AskOrder.Validate() and BidOrder.Validate() to not panic if the Price is a zero-value coin.

* [1658]: Create a ratio.ApplyToLoosely that doesn't require even divisibility.

* [1658]: Create GetHoldAmount methods on the Order, AskOrder, and BidOrder structs.

* [1658]: Add a way to collect fees for a market and the exchange.

* [1658]: Implement CreateAsk, CreateBid, and CancelOrder.

* [1658]: Fill in the MsgMarketWithdrawRequest message.

* [1658]: Msg methods for MsgMarketWithdrawRequest.

* [1658]: Implement MarketWithdraw.

* [1658]: Put an authority check short-circuit into hasPermission. Create IsAuthority keeper method for bette readability.

* [1658]: Get rid of hasPermission(store, ...) and just use HasPermission(ctx, ...) instead. Make some order keeper stuff private.

* [1658]: Make some of the order keeper stuff public again. Change CreateAskOrder and CreateBidOrder to take in the components instead of msg. Also make them validate the ask/bid order since it's now a public keeper function again which might be used by other modules.

* [1658]: Change QueryIsValidMarket into QueryValidateCreateMarket and add QueryValidateManageFees. Also add the market id to the QueryMarketInfoRequest url and get rid of the /info and /details parts of the url.

* [1658]: Fix 'an bid' in a couple places.

* [1658]: Fill in content of MsgMarketManageReqAttrsRequest.

* [1658]: Refactor ValidateReqAttrs to only take in a single list.

* [1658]: Implement the Msg methods for MsgMarketManageReqAttrsRequest.

* [1658]: Create a generic intersection function and use that for string, coin, and fee ratio slices.

* [1658]: Repurpose contains to work on any with a provided equals function and use that for intersection. Create containsString that uses the new contains func for strings. Make intersection private and make public non-generic versions. Use strings.EqualFold for attribute intersection. Remove some colons from error messages that were right before quoted values.

* [1658]: Unit tests on MsgMarketManageReqAttrsRequest.ValidateBasic().

* [1658]: Add the missing market_id field to MsgMarketManageReqAttrsRequest.

* [1658]: Update MsgMarketManageReqAttrsRequest validation to make sure the market id isn't zero. Fix some other unit tests that broke a while back when I took out some colons from the error messages.

* [1658]: Make containsString public.

* [1658]: Implement MarketManageReqAttrs.

* [1658]: Add the admin and market_id fields to the market management protos. Change the administrator field in MsgMarketManageReqAttrsRequest and MsgMarketWithdrawRequest to admin.

* [1658]: Implement GetSigners and the admin and market id validation pieces to the rest of the market management messages.

* [1658]: Fill in the fields of MsgMarketManagePermissionsRequest.

* [1658]: Implement MarketManagePermissions.

* [1658]: Create the rest of the Can... funcs for checking permissions.

* [1658]: Finish MsgMarketManagePermissionsRequest.ValidateBasic().

* [1658]: Fill in the MsgMarketUpdateDetailsRequest MsgMarketUpdateEnabledRequest and MsgMarketUpdateUserSettleRequest message fields.

* [1658]: Implement ValidateBasic() for MsgMarketUpdateDetailsRequest MsgMarketUpdateEnabledRequest and MsgMarketUpdateUserSettleRequest.

* [1658]: Add the gogoproto equal function to MarketDetails.

* [1658]: Implement MarketUpdateDetails MarketUpdateEnabled and MarketUpdateUserSettle.

* [1658]: Tweak some line spacing in tx.proto.

* [1658]: Rename the owner field in MsgCancelOrderRequest to signer.

* [1658]: add fields to MsgFillBidsRequest.

* [1658]: Implment Msg methods for MsgFillBidsRequest.

* [1658]: Implement FillBids.

* [1658]: Fill in the MsgFillAsksRequest fields.

* [1658]: Implement ValidateBasic and GetSigners for MsgFillAsksRequest.

* [1658]: Change total_price to a single Coin entry since validating settlement fees against a price with multiple denoms is a pain.

* [1658]: Implement FillAsks.

* [1658]: Add missing comment on AccessGrant.Contains.

* [1658]: Fix the GetPrice unit test to look for the correct panic message.

* [1658]: Add fields to the MsgMarketSettleRequest message.

* [1658]: MsgMarketSettleRequest.ValidateBasic().

* [1658]: Fix a TODO comment.

* [1658]: Remove the EventCreateMarketSubmitted since I got rid of the endpoint that submits the gov prop.

* [1658]: Split the EventMarketUserSettleUpdated into an Enabled and Disabled event similar to active.

* [1658]: Constructors and test updates for recent event changes.

* [1658]: Rename the EventMarketWithdraw.AmountWithdrawn to just Amount.

* [1658]: Correct a test that wasn't testing the right thing.

* [1658]: Wrap errors returned by the msg service endpoints. Emit events.

* [1658]: Fix some event field comments.

* [1658]: extract getAskOrders and getBidOrders out of FillAsks and FillBids.

* [1658]: Fill in the MarketSettle endpoint. Still need to do the actual settlement piece, though.

* [1658]: Some pre-settlement validation.

* [1658]: Start work on a Fulfillment struct.

* [1658]: Use a generic IndexedAddrAmts instead of two separate types for inputs and outputs.

* [1659]: Normalize the attributes when updating them.

* [1658]: Create ValidateName and ValidateNameSegment for better error messages.

* [1658]: Remove the name keeper, and don't worry about attribute length validation (only standard name validation).

* [1658]: Create a helpers.go with some of the generic helpr funcs (that were already in a few places). Iron out most of ask order fulfillment.

* [1658]: Move the fulfillment stuff to its own file and create the bid order fulfillment thingy.

* [1658]: Don't generate getters for Order, AskOrder, and BidOrder messages.

* [1658]: Create SubOrderI and OrderI interfaces and implement all the methods for AskOrder, BidOrder, and Order.

* [1658]: Make it so GetOrderType doesn't panic, but instead always returns a string of some sort since we use it a TON in error messages.

* [1658]: Lots of work on fulfillment transfer identification and validation.

* [1658]: Make BidOrder.Assets a Coin (instead of Coins).

* [1658]: Split out some of the create order validation for easier use elsewhere.

* [1658]: Tweak partial expected error messages.

* [1658]: Make AskOrder assets a single Coin too.

* [1658]: Get most of the fulfillment stuff finally coded. Still need to handle resulting partial order though.

* [1659]: Set the partial order and emit events during settlement.

* [1658]: Have BuildSettlementTransfers take in a Fulfillments instead of two slices of OrderFulfillment.

* [1658]: Add unit test for DefaultGenesisState.

* [1658]: Add todos for funcs to unit test.

* [1658]: Unit tests on the HasUpdates funcs.

* [1658]: In fulfillment.go: Make some things public that were private. Add some struct and field comments. Tweak GetFulfillmentAssetsAmt to be a little more generic.

* [1658]: Refine the fulfillment stuff to simplify Finalize and put most of the validation in Validate. Standardize on unfilled/filled naming and use applied/left only for price as they're being applied. Split out the price field to separate applied/left and filled/unfilled for easier validation.

* [1658]: Unit tests on the rest of the helper funcs.

* [1658]: Unit tests on the indexedAddrAmts stuff.

* [1658]: Unit tests on the OrderI funcs of OrderFulfillment.

* [1658]: Unit tests on GetAsset/PriceTransfer.

* [1658]: Unit tests on BuildSettlementTransfers.

* [1658]: Unit tests on the OrderFulfillment Apply and ApplyLeftoverPrice methods.

* [1658]: Don't use intermediate variables in GetFulfillmentAssetsAmt, and rename partialFulfillments variable (from partialFulfillment) in BuildFulfillments since it's a list.

* [1658]: Add the order id to the error message for non SubOrderI types.

* [1658]: Unit tests on GetFulfillmentAssetsAmt and NewPartialFulfillment.

* [1658]: Fix a calc in Finalize.

* [1658]: Most of the unit tests on Finalize.

* [1658]: The last of the Finalize unit tests.

* [1658]: Create newUnknownOrder and use that instead of doing it the hard way everywhere.

* [1658]: Tweak OrderFulfillment.Validate: Check the sub-order first. Reorder the checks so they're grouped better. Make sure price left is not the order price. Make sure fees left does not have any negatives. Panic if the switch is missing an order type case.

* [1658]: Further refinements to OrderFulfillment.Validate as I work through unit tests.

* [1658]: Unit tests on OrderFulfillment.Validate.

* [1658]: Update Fulfill: add context to the order type mismatch error. Add asset denom check.

* [1658]: Unit tests on Fulfill.

* [1658]: Tweak some error messages in BuildFulfillments. Also make sure bids are bids and asks are asks.

* [1658]: Unit tests on BuildFulfillments.

* [1658]: Create a unit test for 2 asks 1 bid with amounts just off that currently fails, but should probablly be allowed.

* [1658]: Create shells of InitGenesis and ExportGenesis.

* [1658]: Lint fix and some TODOs for uint parsers.

* [1658]: Implement InitGenesis and ExportGenesis. Move NormalizeReqAttrs out of the keeper. Make GetMarket less reliant on the existence of the account.

* [1658]: Check sizes of orders for when we're reading them.

* [1658]: Create the query server with stubs and wire it into the module.

* [1658]: Have uint16FromBz, uint32FromBz, and uint64FromBz return a bool instead of panicking.

* [1658]: Fix some query server todos.

* [1658]: Populate the QueryOrderFeeCalc messages.

* [1658]: Make the QueryOrderFeeCalcResponse []Coin insted of Coins since they're not supposed to be viewed as a whole.

* [1658]: Implement QueryOrderFeeCalc.

* [1658]: Remove the QuerySettlementFeeCalc since I took out the fee amount from the settlement tx message.

* [1658]: Change QueryGetAddressOrders to QueryGetOwnerOrders. Add a QueryGetAssetOrders. Fill in query messages for the order queries.

* [1658]: Implement QueryGetOrder.

* [1658]: Implement QueryGetMarketOrders.

* [1658]: Implement QueryGetOwnerOrders.

* [1658]: Add an order_type field to the QueryGetAssetOrdersRequest and add todos to do the same for the other indexed order queries.

* [1658]: Implement QueryGetAssetOrders and QueryGetAllOrders.

* [1658]: Refactor the Market to order and address to order indexes to include the order type byte.

* Revert "[1658]: Refactor the Market to order and address to order indexes to include the order type byte."

This reverts commit 1cb40db.

* [1658]: Change the asset-to-order index to match the others with the type byte in the value.

* [1658]: Extract the pagination stuff to a new GetPageOfOrdersFromIndex func (from inside QueryGetAssetOrders).

* [1658]: Add the order type field to QueryGetMarketOrders and QueryGetOwnerOrders.

* [1658]: Allow the MarketOrders, AddressOrders, and AssetOrders queries to be limited to a minimum order id.

* [1658]: Rename QueryMarketInfo to QueryGetMarket. Add QueryGetAllMarkets. Fill in the fields for both of those.

* [1658]: Implement QueryGetMarket and QueryGetAllMarkets.

* [1658]: Fill in and implement QueryParams.

* [1658]: Fill in the fields of the ValidateCreateMarket and ValidateManageFees query messages. Create a QueryValidateMarket query.

* [1658]: Implement QueryValidateCreateMarket and QueryValidateMarket.

* [1658]: Implement QueryValidateManageFees.

* [1658]: Pull ratio price denoms check out into its own function. In QueryValidateManageFees, update the fees and then validate the market too.

* [1658]: Reorganize keeper/market.go and tweak a few of the function names for consistency. Also fix a couple permission checks that were checking the wrong permission.

* [1658]: Make the marketID the 2nd arg for consistency in CollectFee and CollectFees.

* [1658]: Reorganize keeper/orders.go. In SettleOrders, release the holds on the orders before doing the transfers, and put the hold back on the partial if there is one.

* [1658]: Store the last order id and use it for getting the next order id to use. Prior to this, an id could be reused if an order were created then filled before the next order was created. And while our stuff could handle that okay, external systems probably want that to be unique.

* [1658]: Create emitEvent and emitEvents that just logs any errors instead of returning them.

* [1658]: Begin the overhaul of fulfillment. Create a Distribution struct and add two to the fulfillment and create a couple methods for adding to them.

* [1658]: Major work on the fulfillment overhaul. Allocation done, just need to create the transfers.

* [1658]: Move GetAssetTransfer and GetPriceTransfer out of the way and create a new GetAssetTransfer.

* [1658]: Finish BuildSettlement (at least until I find problems as I write unit tests).

* [1658]: Wire the keeper's SettleOrders method to use the new BuildSettlement func.

* [1658]: Stub out all the new test funcs needed.

* [1658]: Unit tests on NewOrderFulfillments, assetCoin, and priceCoin.

* [1658]: Unit tests on GetFulfillmentPriceAmt.

* [1658]: Unit tests on sumAssetsAndPrice and sumPriceLeft.

* [1658]: Unit tests on the DistributeAssets and DistributePrice stuff.

* [1658]: Unit tests on the CopyChange funcs and Order.Split. Also fixed a bit in Order.Split.

* [1658]: Unit tests on OrderFulfillment.SplitOrder

* [1658]: Unit tests and fixes for OrderFulfillment.Validate, getAssetTransfer and getPriceTransfer.

* [1658]: Unit tests on validateCanSettle.

* [1658]: Fix allocateAssets giving the wrong thing to DistributeAssets.

* [1658]: Unit tests on allocateAssets and splitPartial.

* [1658]: Fix buildTransfers to not double up the transfers.

* [1658]: Add some fields to EventOrderFilled and EventOrderPartiallyFilled.

* [1658]: Create a FilledOrder struct to represent what's been filled in an order. Use those in the Settlement and for the events that are emitted. Populate the filled order and partially filled order in the settlement at the end of it all.

* [1658]: Unit tests on splitOrderFulfillments.

* [1658]: Unit tests on populateFilled.

* [1658]: Unit tests on setFeesToPay.

* [1658]: Unit tests on validateFulfillments.

* [1658]: Unit tests on buildTransfers.

* [1658]: Unit tests on allocatePrice.

* [1658]: Remove duplicate total price check.

* [1658]: Unit tests on BuildSettlement.

* [1658]: Clean up the now-unneeded order fulfillment stuff. Make the OrderFulfillment type private since it's only used as an intermediate object during processing.

* [1658]: Unit tests on ParseIndexKeySuffixOrderID.

* [1658]: Stub out the remaining module pieces.

* [1658]: Bypass the quarantine module when doing transfers.

* [1658]: During InitGenesis, make sure that there's holds on all the order funds already.

* [1658]: Use DoTransfer in FillBids (instead of InputOutputCoins directoy) as I intended.

* [1658]: Add the exchange module to the app.

* [1658]: Create ValidateAuthority and use that instead of IsAuthority and wrongAuthErr. Get rid of wrongAuthErr.

* [1658]: Tweak IsAuthority to be case insensitive, and ValidateAuthority to wrap the addresses in quotes.

* [1658]: Create the mock keepers and create the beginnings of the keeper tests.

* [1658]: Change DoTransfer to return an error instead of panic when an address is bad. Tweak CalculateExchangeSplit to use QuoRemInt. Tweak variable names and error messages in CollectFee and CollectFees.

* [1658]: Unit tests on DoTransfer, CalculateExchangeSplit, CollectFee, and CollectFees.

* [1658]: Lint fixes.

* [1658]: Fully generate the proto stuff.

* [1658]: Add the bare beginnings of the spec doc.

* [1658]: Create TODOs for all the keeper unit tests.

* Some small tweaks from initial code review.

* [1658]: Move some of the generic unit test helper functions into helpers_test.go.

* [1658]: Prevent an admin from revoking their own ability to manage permissions.

* [1658]: Reorg the module.go file a bit.

* [1658]: Add a changelog entry.

* [1658]: Don't allow a single star wildcard in required attributes since that's exactly the same as having an empty list.

* [1658]: Fix a few comments.

* [1658]: Add a last_order_id field to the genesis state.

* [1658]: Create stringerJoin to clean up some of the unit test helper funcs.

* [1658]: Tweak to assertEqualOrderFulfillmentSlices to the string comparison better.

* [1658]: Fix a call to feeCoins in TestBuildSettlement that was missing it's tracer.

* [1658]: Create stringerLines and use it to clean up some more unit test stuff.

* [1658]: Delete some unwanted empty lines.

* [1658]: Provide suggested sizes when making maps.

* [1658]: Flatten a for loop in UpdatePermissions a little bit.

* [1658]: Fix the field comments in MsgMarketManageReqAttrsRequest.

* [1658]: Double check that the market details are valid in CreateMarket since it's a public keeper function.

* [1658]: Allow an admin to revoke their permission to manage permissions.

* [1658]: Add an external id field to the orders and create a tx for setting it and query for looking up orders using them.

* [1658]: Add the market id to severl order-related events.

* [1658]: Move the sumAssetsAndPrice calls and validation to before the orders loop in both FillAsks and FillBids.

* [1658]: Make IndexedAddrAmts public.

* [1658]: Extract a closeSettlement method from the end of SettleOrders, and in FillAsks and FillBids, create a settlement and use that function. Use IndexedAddrAmts for identifying inputs and outputs in FillBids and FillAsks.

* [1658]: In IndexedAddrAmts.Add, if the coins to add is zero, don't do anything.

* [1658]: Increase the maximmum external id length to allow for 32 byte bech32 addresses.

* [1658]: Remove the 'Query' from the name of all the query endpoints.

* [1658]: Add the hold queries to the stargate whitelist.

* [1658]: Add all the exchange queries to the stargate whitelist.

* [1658]: Fix the market keeper to set an empty byte slice instead of nil (which the store doesn't allow).

* [1658]: Fix getBuyerSettlementFeeRatiosForPriceDenom to return an error if there are no ratios found but the market does have ratios.

* [1658]: Add the fee to an error in validateFlatFee. Fix validateSellerSettlementFlatFee to use the correct key maker.

* [1658]: Refactor validateAskPrice to clean it up a bit.

* [1658]: In validateBuyerSettlementFee, when a fee is required but one isn't provided, have the error include the required options.

* [1658]: in validateBuyerSettlementFee, only include errors for a type that isn't satisfied.

* [1658]: Create ParseFeeRatio.

* [1658]: Set the exchange params to the defaults in the upgrade.
  • Loading branch information
SpicyLemon authored Oct 18, 2023
1 parent df2d286 commit abf94a0
Show file tree
Hide file tree
Showing 73 changed files with 60,396 additions and 59 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* Create the `x/exchange` module which facilitates the buying and selling of assets [#1658](https://github.com/provenance-io/provenance/issues/1658).
Assets and funds remain in their owner's account (with a hold on them) until the order is settled (or cancelled).
Market's are created to manage order matching and define fees.
The chain will receive a portion of the fees a market collects.
* Allow marker's transfer authority to prevent transfer of restricted coin with deny list on send [#1518](https://github.com/provenance-io/provenance/issues/1518).
* Add net asset value to markers [#1328](https://github.com/provenance-io/provenance/issues/1328).
* Add ICQHost and Oracle module to allow cross chain oracle queries [#1497](https://github.com/provenance-io/provenance/issues/1497).
Expand Down
19 changes: 18 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,13 @@ import (
attributekeeper "github.com/provenance-io/provenance/x/attribute/keeper"
attributetypes "github.com/provenance-io/provenance/x/attribute/types"
attributewasm "github.com/provenance-io/provenance/x/attribute/wasm"
"github.com/provenance-io/provenance/x/exchange"
exchangekeeper "github.com/provenance-io/provenance/x/exchange/keeper"
exchangemodule "github.com/provenance-io/provenance/x/exchange/module"
"github.com/provenance-io/provenance/x/hold"
holdkeeper "github.com/provenance-io/provenance/x/hold/keeper"
holdmodule "github.com/provenance-io/provenance/x/hold/module"
ibchooks "github.com/provenance-io/provenance/x/ibchooks"
"github.com/provenance-io/provenance/x/ibchooks"
ibchookskeeper "github.com/provenance-io/provenance/x/ibchooks/keeper"
ibchookstypes "github.com/provenance-io/provenance/x/ibchooks/types"
"github.com/provenance-io/provenance/x/marker"
Expand Down Expand Up @@ -226,6 +229,7 @@ var (
triggermodule.AppModuleBasic{},
oraclemodule.AppModuleBasic{},
holdmodule.AppModuleBasic{},
exchangemodule.AppModuleBasic{},
)

// module account permissions
Expand Down Expand Up @@ -317,6 +321,7 @@ type App struct {
AttributeKeeper attributekeeper.Keeper
NameKeeper namekeeper.Keeper
HoldKeeper holdkeeper.Keeper
ExchangeKeeper exchangekeeper.Keeper
WasmKeeper *wasm.Keeper
ContractKeeper *wasmkeeper.PermissionedKeeper

Expand Down Expand Up @@ -400,6 +405,7 @@ func New(
triggertypes.StoreKey,
oracletypes.StoreKey,
hold.StoreKey,
exchange.StoreKey,
)
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
Expand Down Expand Up @@ -569,6 +575,11 @@ func New(
appCodec, keys[hold.StoreKey], app.BankKeeper,
)

app.ExchangeKeeper = exchangekeeper.NewKeeper(
appCodec, keys[exchange.StoreKey], authtypes.FeeCollectorName,
app.AccountKeeper, app.AttributeKeeper, app.BankKeeper, app.HoldKeeper,
)

pioMessageRouter := MessageRouterFunc(func(msg sdk.Msg) baseapp.MsgServiceHandler {
return pioMsgFeesRouter.Handler(msg)
})
Expand Down Expand Up @@ -751,6 +762,7 @@ func New(
triggermodule.NewAppModule(appCodec, app.TriggerKeeper, app.AccountKeeper, app.BankKeeper),
oracleModule,
holdmodule.NewAppModule(appCodec, app.HoldKeeper),
exchangemodule.NewAppModule(appCodec, app.ExchangeKeeper),

// IBC
ibc.NewAppModule(app.IBCKeeper),
Expand Down Expand Up @@ -801,6 +813,7 @@ func New(
quarantine.ModuleName,
sanction.ModuleName,
hold.ModuleName,
exchange.ModuleName,
)

app.mm.SetOrderEndBlockers(
Expand Down Expand Up @@ -840,6 +853,7 @@ func New(
quarantine.ModuleName,
sanction.ModuleName,
hold.ModuleName,
exchange.ModuleName,
)

// NOTE: The genutils module must occur after staking so that pools are
Expand Down Expand Up @@ -871,6 +885,7 @@ func New(
metadatatypes.ModuleName,
msgfeestypes.ModuleName,
hold.ModuleName,
exchange.ModuleName, // must be after the hold module.

ibchost.ModuleName,
ibctransfertypes.ModuleName,
Expand Down Expand Up @@ -911,6 +926,7 @@ func New(
quarantine.ModuleName,
sanction.ModuleName,
hold.ModuleName,
exchange.ModuleName,

ibchookstypes.ModuleName,
icatypes.ModuleName,
Expand Down Expand Up @@ -961,6 +977,7 @@ func New(
triggermodule.NewAppModule(appCodec, app.TriggerKeeper, app.AccountKeeper, app.BankKeeper),
oraclemodule.NewAppModule(appCodec, app.OracleKeeper, app.AccountKeeper, app.BankKeeper, app.IBCKeeper.ChannelKeeper),
holdmodule.NewAppModule(appCodec, app.HoldKeeper),
exchangemodule.NewAppModule(appCodec, app.ExchangeKeeper),
provwasm.NewWrapper(appCodec, app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.NameKeeper),

// IBC
Expand Down
28 changes: 24 additions & 4 deletions app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (

attributekeeper "github.com/provenance-io/provenance/x/attribute/keeper"
attributetypes "github.com/provenance-io/provenance/x/attribute/types"
"github.com/provenance-io/provenance/x/exchange"
"github.com/provenance-io/provenance/x/hold"
ibchookstypes "github.com/provenance-io/provenance/x/ibchooks/types"
msgfeetypes "github.com/provenance-io/provenance/x/msgfees/types"
Expand Down Expand Up @@ -113,10 +114,11 @@ var upgrades = map[string]appUpgrade{
removeInactiveValidatorDelegations(ctx, app)
setupICQ(ctx, app)
updateMaxSupply(ctx, app)
setExchangeParams(ctx, app)

return vm, nil
},
Added: []string{icqtypes.ModuleName, oracletypes.ModuleName, ibchookstypes.ModuleName, hold.ModuleName},
Added: []string{icqtypes.ModuleName, oracletypes.ModuleName, ibchookstypes.ModuleName, hold.ModuleName, exchange.ModuleName},
},
"saffron": { // upgrade for v1.17.0,
Handler: func(ctx sdk.Context, app *App, vm module.VersionMap) (module.VersionMap, error) {
Expand All @@ -132,10 +134,11 @@ var upgrades = map[string]appUpgrade{
removeInactiveValidatorDelegations(ctx, app)
setupICQ(ctx, app)
updateMaxSupply(ctx, app)
setExchangeParams(ctx, app)

return vm, nil
},
Added: []string{icqtypes.ModuleName, oracletypes.ModuleName, ibchookstypes.ModuleName, hold.ModuleName},
Added: []string{icqtypes.ModuleName, oracletypes.ModuleName, ibchookstypes.ModuleName, hold.ModuleName, exchange.ModuleName},
},
// TODO - Add new upgrade definitions here.
}
Expand Down Expand Up @@ -324,14 +327,16 @@ func setAccountDataNameRecord(ctx sdk.Context, accountK attributetypes.AccountKe
return attributekeeper.EnsureModuleAccountAndAccountDataNameRecord(ctx, accountK, nameK)
}

// setupICQ sets the correct default values for ICQKeeper
// setupICQ sets the correct default values for ICQKeeper.
// TODO: Remove with the saffron handlers.
func setupICQ(ctx sdk.Context, app *App) {
ctx.Logger().Info("Updating ICQ params")
app.ICQKeeper.SetParams(ctx, icqtypes.NewParams(true, []string{"/provenance.oracle.v1.Query/Oracle"}))
ctx.Logger().Info("Done updating ICQ params")
}

// updateMaxSupply sets the value of max supply to the current value of MaxTotalSupply
// updateMaxSupply sets the value of max supply to the current value of MaxTotalSupply.
// TODO: Remove with the saffron handlers.
func updateMaxSupply(ctx sdk.Context, app *App) {
ctx.Logger().Info("Updating MaxSupply marker param")
params := app.MarkerKeeper.GetParams(ctx)
Expand All @@ -340,3 +345,18 @@ func updateMaxSupply(ctx sdk.Context, app *App) {
app.MarkerKeeper.SetParams(ctx, params)
ctx.Logger().Info("Done updating MaxSupply marker param")
}

// setExchangeParams sets exchange module's params to the defaults.
// TODO: Remove with the saffron handlers.
func setExchangeParams(ctx sdk.Context, app *App) {
ctx.Logger().Info("Ensuring exchange module params are set.")
params := app.ExchangeKeeper.GetParams(ctx)
if params != nil {
ctx.Logger().Info("Exchange module params are already defined.")
} else {
params = exchange.DefaultParams()
ctx.Logger().Info("Setting exchange module params to defaults.")
app.ExchangeKeeper.SetParams(ctx, params)
}
ctx.Logger().Info("Done ensuring exchange module params are set.")
}
78 changes: 78 additions & 0 deletions app/upgrades_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

"github.com/provenance-io/provenance/x/exchange"
msgfeetypes "github.com/provenance-io/provenance/x/msgfees/types"
)

Expand Down Expand Up @@ -426,6 +427,7 @@ func (s *UpgradeTestSuite) TestSaffronRC1() {
"INF Done updating ICQ params",
"INF Updating MaxSupply marker param",
"INF Done updating MaxSupply marker param",
"INF Ensuring exchange module params are set.",
}

s.AssertUpgradeHandlerLogs("saffron-rc1", expInLog, nil)
Expand All @@ -442,6 +444,7 @@ func (s *UpgradeTestSuite) TestSaffron() {
"INF Done updating ICQ params",
"INF Updating MaxSupply marker param",
"INF Done updating MaxSupply marker param",
"INF Ensuring exchange module params are set.",
}

s.AssertUpgradeHandlerLogs("saffron", expInLog, nil)
Expand Down Expand Up @@ -841,3 +844,78 @@ func (s *UpgradeTestSuite) TestSetAccountDataNameRecord() {
s.Require().NoError(err, "setAccountDataNameRecord")
s.AssertLogContents(logOutput, expInLog, nil, true, "setAccountDataNameRecord")
}

func (s *UpgradeTestSuite) TestSetExchangeParams() {
startMsg := "INF Ensuring exchange module params are set."
noopMsg := "INF Exchange module params are already defined."
updateMsg := "INF Setting exchange module params to defaults."
doneMsg := "INF Done ensuring exchange module params are set."

tests := []struct {
name string
existingParams *exchange.Params
expectedParams *exchange.Params
expInLog []string
}{
{
name: "no params set yet",
existingParams: nil,
expectedParams: exchange.DefaultParams(),
expInLog: []string{startMsg, updateMsg, doneMsg},
},
{
name: "params set with no splits and default zero",
existingParams: &exchange.Params{DefaultSplit: 0},
expectedParams: &exchange.Params{DefaultSplit: 0},
expInLog: []string{startMsg, noopMsg, doneMsg},
},
{
name: "params set with no splits and different default",
existingParams: &exchange.Params{DefaultSplit: exchange.DefaultDefaultSplit + 100},
expectedParams: &exchange.Params{DefaultSplit: exchange.DefaultDefaultSplit + 100},
expInLog: []string{startMsg, noopMsg, doneMsg},
},
{
name: "params set with some splits",
existingParams: &exchange.Params{
DefaultSplit: exchange.DefaultDefaultSplit + 100,
DenomSplits: []exchange.DenomSplit{
{Denom: "peach", Split: 3000},
{Denom: "plum", Split: 100},
},
},
expectedParams: &exchange.Params{
DefaultSplit: exchange.DefaultDefaultSplit + 100,
DenomSplits: []exchange.DenomSplit{
{Denom: "peach", Split: 3000},
{Denom: "plum", Split: 100},
},
},
expInLog: []string{startMsg, noopMsg, doneMsg},
},
}

for _, tc := range tests {
s.Run(tc.name, func() {
s.app.ExchangeKeeper.SetParams(s.ctx, tc.existingParams)

// Reset the log buffer and call the fun. Relog the output if it panics.
s.logBuffer.Reset()
testFunc := func() {
setExchangeParams(s.ctx, s.app)
}
didNotPanic := s.Assert().NotPanics(testFunc, "setExchangeParams")
logOutput := s.GetLogOutput("setExchangeParams")
if !didNotPanic {
return
}

// Make sure the log has the expected lines.
s.AssertLogContents(logOutput, tc.expInLog, nil, true, "setExchangeParams")

// Make sure the params are as expected now.
params := s.app.ExchangeKeeper.GetParams(s.ctx)
s.Assert().Equal(tc.expectedParams, params, "params after setExchangeParams")
})
}
}
2 changes: 1 addition & 1 deletion client/docs/statik/statik.go

Large diffs are not rendered by default.

23 changes: 19 additions & 4 deletions client/docs/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36409,8 +36409,8 @@ paths:
type: string
format: uint64
title: >-
maximum amount of supply to allow a marker to be created
with
Deprecated: Prefer to use `max_supply` instead. Maximum
amount of supply to allow a marker to be created with
enable_governance:
type: boolean
format: boolean
Expand All @@ -36425,6 +36425,11 @@ paths:

requests are only subject to platform coin validation
denom expression)
max_supply:
type: string
title: >-
maximum amount of supply to allow a marker to be created
with
description: >-
QueryParamsResponse is the response type for the Query/Params RPC
method.
Expand Down Expand Up @@ -83319,7 +83324,9 @@ definitions:
max_total_supply:
type: string
format: uint64
title: maximum amount of supply to allow a marker to be created with
title: >-
Deprecated: Prefer to use `max_supply` instead. Maximum amount of
supply to allow a marker to be created with
enable_governance:
type: boolean
format: boolean
Expand All @@ -83332,6 +83339,9 @@ definitions:

requests are only subject to platform coin validation denom
expression)
max_supply:
type: string
title: maximum amount of supply to allow a marker to be created with
description: Params defines the set of params for the account module.
provenance.marker.v1.QueryAccessResponse:
type: object
Expand Down Expand Up @@ -83950,7 +83960,9 @@ definitions:
max_total_supply:
type: string
format: uint64
title: maximum amount of supply to allow a marker to be created with
title: >-
Deprecated: Prefer to use `max_supply` instead. Maximum amount of
supply to allow a marker to be created with
enable_governance:
type: boolean
format: boolean
Expand All @@ -83963,6 +83975,9 @@ definitions:

requests are only subject to platform coin validation denom
expression)
max_supply:
type: string
title: maximum amount of supply to allow a marker to be created with
description: QueryParamsResponse is the response type for the Query/Params RPC method.
provenance.marker.v1.QuerySupplyResponse:
type: object
Expand Down
Loading

0 comments on commit abf94a0

Please sign in to comment.