Skip to content

Commit

Permalink
Refactor perpetual upgrade handlers in v5.0.0 (#1442) (#1444)
Browse files Browse the repository at this point in the history
(cherry picked from commit e2359f3)

Co-authored-by: Teddy Ding <teddy@dydx.exchange>
  • Loading branch information
mergify[bot] and teddyding authored Apr 30, 2024
1 parent 42ad83c commit b126ab1
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 78 deletions.
139 changes: 62 additions & 77 deletions protocol/app/upgrades/v5.0.0/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"

"github.com/dydxprotocol/v4-chain/protocol/dtypes"
clobtypes "github.com/dydxprotocol/v4-chain/protocol/x/clob/types"
perptypes "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals/types"
satypes "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/types"
Expand All @@ -19,20 +20,68 @@ import (
"github.com/dydxprotocol/v4-chain/protocol/lib"
)

// Set all existing perpetuals to cross market type
// perpetuals upgrade handler for v5.0.0
// - 1. Set all perpetuals to cross market type
// - 2. Initialize perpetual open interest to current OI
func perpetualsUpgrade(
ctx sdk.Context,
perpetualsKeeper perptypes.PerpetualsKeeper,
subaccountsKeeper satypes.SubaccountsKeeper,
) {
// Set all perpetuals to cross market type
perpOIMap := make(map[uint32]*big.Int)

// Iterate through all subaccounts and perp positions for each subaccount.
// Aggregate open interest for each perpetual market.
subaccounts := subaccountsKeeper.GetAllSubaccount(ctx)
for _, sa := range subaccounts {
for _, perpPosition := range sa.PerpetualPositions {
if perpPosition.Quantums.BigInt().Sign() <= 0 {
// Only record positive positions for total open interest.
// Total negative position size should be equal to total positive position size.
continue
}
if openInterest, exists := perpOIMap[perpPosition.PerpetualId]; exists {
// Already seen this perpetual. Add to open interest.
openInterest.Add(
openInterest,
perpPosition.Quantums.BigInt(),
)
} else {
// Haven't seen this pereptual. Initialize open interest.
perpOIMap[perpPosition.PerpetualId] = new(big.Int).Set(
perpPosition.Quantums.BigInt(),
)
}
}
}

perpetuals := perpetualsKeeper.GetAllPerpetuals(ctx)
for _, p := range perpetuals {
_, err := perpetualsKeeper.SetPerpetualMarketType(
ctx, p.GetId(),
perptypes.PerpetualMarketType_PERPETUAL_MARKET_TYPE_CROSS)
for _, perp := range perpetuals {
// 1. Set all perpetuals to cross market type
perp.Params.MarketType = perptypes.PerpetualMarketType_PERPETUAL_MARKET_TYPE_CROSS

// 2. Initialize perpetual open interest to current OI
perpOpenInterst := big.NewInt(0)
if oi, exists := perpOIMap[perp.GetId()]; exists {
perpOpenInterst.Set(oi)
}
perp.OpenInterest = dtypes.NewIntFromBigInt(perpOpenInterst)
err := perpetualsKeeper.ValidateAndSetPerpetual(
ctx,
perp,
)
if err != nil {
panic(fmt.Sprintf("failed to set perpetual market type for perpetual %d: %s", p.GetId(), err))
panic(fmt.Sprintf(
"failed to modify open interest for perpetual, openInterest = %v, perpetual = %+v",
perpOpenInterst,
perp,
))
}
ctx.Logger().Info(fmt.Sprintf(
"Successfully migrated perpetual %d: %+v",
perp.GetId(),
perp,
))
}
}

Expand Down Expand Up @@ -98,8 +147,10 @@ func blockRateLimitConfigUpdate(
panic(fmt.Sprintf("failed to update the block rate limit configuration: %s", err))
}
ctx.Logger().Info(
"Successfully upgraded block rate limit configuration to: %+v\n",
clobKeeper.GetBlockRateLimitConfiguration(ctx),
fmt.Sprintf(
"Successfully upgraded block rate limit configuration to: %+v\n",
clobKeeper.GetBlockRateLimitConfiguration(ctx),
),
)
}

Expand Down Expand Up @@ -238,69 +289,6 @@ func voteExtensionsUpgrade(
)
}

// Initialize open interest for perpetuals
func initializePerpOpenInterest(
ctx sdk.Context,
perpetualsKeeper perptypes.PerpetualsKeeper,
subaccountsKeeper satypes.SubaccountsKeeper,
) {
perpOIMap := make(map[uint32]*big.Int)

subaccounts := subaccountsKeeper.GetAllSubaccount(ctx)

// Iterate through all subaccounts and perp positions for each subaccount.
// Aggregate open interest for each perpetual market.
for _, sa := range subaccounts {
for _, perpPosition := range sa.PerpetualPositions {
if perpPosition.Quantums.BigInt().Sign() <= 0 {
// Only record positive positions for total open interest.
// Total negative position size should be equal to total positive position size.
continue
}
if openInterest, exists := perpOIMap[perpPosition.PerpetualId]; exists {
// Already seen this perpetual. Add to open interest.
openInterest.Add(
openInterest,
perpPosition.Quantums.BigInt(),
)
} else {
// Haven't seen this pereptual. Initialize open interest.
perpOIMap[perpPosition.PerpetualId] = new(big.Int).Set(
perpPosition.Quantums.BigInt(),
)
}
}
}

allPerps := perpetualsKeeper.GetAllPerpetuals(ctx)
for _, perp := range allPerps {
if perp.OpenInterest.BigInt().Sign() != 0 {
panic(fmt.Sprintf("perpetual %d has non-zero OI (%v) before upgrade", perp.GetId(), perp.OpenInterest))
}
if openInterest, exists := perpOIMap[perp.GetId()]; exists {
err := perpetualsKeeper.ModifyOpenInterest(
ctx,
perp.GetId(),
openInterest, // by default perpetual.OI = 0, so use the total open interest as delta
)
if err != nil {
panic(fmt.Sprintf(
"failed to modify open interest for perpetual, openInterest = %v, perpetual = %+v",
openInterest,
perp,
))
}
ctx.Logger().Info(fmt.Sprintf(
"Successfully initialized open interest for perpetual %d = %v",
perp.GetId(),
openInterest,
))
} else {
ctx.Logger().Info(fmt.Sprintf("Perpetual %d has zero open interest at the time of upgrade", perp.GetId()))
}
}
}

// Initialize vault module parameters.
func initializeVaultModuleParams(
ctx sdk.Context,
Expand Down Expand Up @@ -331,11 +319,8 @@ func CreateUpgradeHandler(
clobKeeper.MigratePruneableOrders(sdkCtx)
sdkCtx.Logger().Info("Successfully migrated pruneable orders")

// Set all perpetuals to cross market type
perpetualsUpgrade(sdkCtx, perpetualsKeeper)

// Initialize open interest for all perpetuals
initializePerpOpenInterest(sdkCtx, perpetualsKeeper, subaccountsKeeper)
// Set all perpetuals to cross market type and initialize open interest
perpetualsUpgrade(sdkCtx, perpetualsKeeper, subaccountsKeeper)

// Set block rate limit configuration
blockRateLimitConfigUpdate(sdkCtx, clobKeeper)
Expand Down
94 changes: 93 additions & 1 deletion protocol/app/upgrades/v5.0.0/upgrade_container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (

const (
AliceBobBTCQuantums = 1_000_000
CarlDaveBTCQuantums = 2_000_000
CarlDaveETHQuantums = 4_000_000
)

func TestStateUpgrade(t *testing.T) {
Expand Down Expand Up @@ -119,6 +121,94 @@ func placeOrders(node *containertest.Node, t *testing.T) {
},
constants.BobAccAddress.String(),
))
require.NoError(t, containertest.BroadcastTx(
node,
&clobtypes.MsgPlaceOrder{
Order: clobtypes.Order{
OrderId: clobtypes.OrderId{
ClientId: 0,
SubaccountId: satypes.SubaccountId{
Owner: constants.CarlAccAddress.String(),
Number: 0,
},
ClobPairId: 0,
},
Side: clobtypes.Order_SIDE_BUY,
Quantums: CarlDaveBTCQuantums,
Subticks: 5_000_000,
GoodTilOneof: &clobtypes.Order_GoodTilBlock{
GoodTilBlock: 20,
},
},
},
constants.CarlAccAddress.String(),
))
require.NoError(t, containertest.BroadcastTx(
node,
&clobtypes.MsgPlaceOrder{
Order: clobtypes.Order{
OrderId: clobtypes.OrderId{
ClientId: 0,
SubaccountId: satypes.SubaccountId{
Owner: constants.DaveAccAddress.String(),
Number: 0,
},
ClobPairId: 0,
},
Side: clobtypes.Order_SIDE_SELL,
Quantums: CarlDaveBTCQuantums,
Subticks: 5_000_000,
GoodTilOneof: &clobtypes.Order_GoodTilBlock{
GoodTilBlock: 20,
},
},
},
constants.DaveAccAddress.String(),
))
require.NoError(t, containertest.BroadcastTx(
node,
&clobtypes.MsgPlaceOrder{
Order: clobtypes.Order{
OrderId: clobtypes.OrderId{
ClientId: 0,
SubaccountId: satypes.SubaccountId{
Owner: constants.CarlAccAddress.String(),
Number: 0,
},
ClobPairId: 1,
},
Side: clobtypes.Order_SIDE_BUY,
Quantums: CarlDaveETHQuantums,
Subticks: 5_000_000,
GoodTilOneof: &clobtypes.Order_GoodTilBlock{
GoodTilBlock: 20,
},
},
},
constants.CarlAccAddress.String(),
))
require.NoError(t, containertest.BroadcastTx(
node,
&clobtypes.MsgPlaceOrder{
Order: clobtypes.Order{
OrderId: clobtypes.OrderId{
ClientId: 0,
SubaccountId: satypes.SubaccountId{
Owner: constants.DaveAccAddress.String(),
Number: 0,
},
ClobPairId: 1,
},
Side: clobtypes.Order_SIDE_SELL,
Quantums: CarlDaveETHQuantums,
Subticks: 5_000_000,
GoodTilOneof: &clobtypes.Order_GoodTilBlock{
GoodTilBlock: 20,
},
},
},
constants.DaveAccAddress.String(),
))
err := node.Wait(2)
require.NoError(t, err)
}
Expand Down Expand Up @@ -186,7 +276,9 @@ func postUpgradePerpetualOIs(node *containertest.Node, t *testing.T) {
for _, perp := range allPerpsResp.Perpetual {
expectedOI := 0
if perp.Params.Id == 0 {
expectedOI = AliceBobBTCQuantums
expectedOI = AliceBobBTCQuantums + CarlDaveBTCQuantums
} else if perp.Params.Id == 1 {
expectedOI = CarlDaveETHQuantums
}
assert.Equalf(t,
dtypes.NewInt(int64(expectedOI)),
Expand Down
18 changes: 18 additions & 0 deletions protocol/mocks/PerpetualsKeeper.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions protocol/testing/containertest/preupgrade_genesis.json
Original file line number Diff line number Diff line change
Expand Up @@ -2158,6 +2158,34 @@
},
"margin_enabled": true
},
{
"asset_positions": [
{
"asset_id": 0,
"index": 0,
"quantums": "100000000000000000"
}
],
"id": {
"number": 0,
"owner": "dydx1fjg6zp6vv8t9wvy4lps03r5l4g7tkjw9wvmh70"
},
"margin_enabled": true
},
{
"asset_positions": [
{
"asset_id": 0,
"index": 0,
"quantums": "100000000000000000"
}
],
"id": {
"number": 0,
"owner": "dydx1wau5mja7j7zdavtfq9lu7ejef05hm6ffenlcsn"
},
"margin_enabled": true
},
{
"asset_positions": [
{
Expand Down
4 changes: 4 additions & 0 deletions protocol/x/perpetuals/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ type PerpetualsKeeper interface {
) []Perpetual
GetAllLiquidityTiers(ctx sdk.Context) (list []LiquidityTier)
SendOIUpdatesToIndexer(ctx sdk.Context)
ValidateAndSetPerpetual(
ctx sdk.Context,
perpetual Perpetual,
) error
}

// OpenInterestDelta represents a (perpId, openInterestDelta) tuple.
Expand Down

0 comments on commit b126ab1

Please sign in to comment.