Skip to content

Commit

Permalink
Get fresh hubble state
Browse files Browse the repository at this point in the history
  • Loading branch information
lumos42 committed May 12, 2024
1 parent 51f37e6 commit 832158d
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 39 deletions.
9 changes: 0 additions & 9 deletions plugin/evm/limit_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,6 @@ func NewLimitOrderProcesser(ctx *snow.Context, txPool *txpool.TxPool, shutdownCh
matchingPipeline := orderbook.NewMatchingPipeline(memoryDb, lotp, configService)
// if any of the following values are changed, the nodes will need to be restarted.
// This is also true for local testing. once contracts are deployed it's mandatory to restart the nodes
hState := &hu.HubbleState{
Assets: matchingPipeline.GetCollaterals(),
ActiveMarkets: matchingPipeline.GetActiveMarkets(),
MinAllowableMargin: configService.GetMinAllowableMargin(),
MaintenanceMargin: configService.GetMaintenanceMargin(),
TakerFee: configService.GetTakerFee(),
UpgradeVersion: hu.V2,
}
hu.SetHubbleState(hState)
hu.SetChainIdAndVerifyingSignedOrdersContract(backend.ChainConfig().ChainID.Int64(), signedObAddy.String())

filterSystem := filters.NewFilterSystem(backend, filters.Config{})
Expand Down
6 changes: 6 additions & 0 deletions plugin/evm/orderbook/config_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type IConfigService interface {
GetMarketAddressFromMarketID(marketId int64) common.Address
GetImpactMarginNotional(ammAddress common.Address) *big.Int
GetReduceOnlyAmounts(trader common.Address) []*big.Int

IsSettledAll() bool
}

type ConfigService struct {
Expand Down Expand Up @@ -152,3 +154,7 @@ func (cs *ConfigService) GetImpactMarginNotional(ammAddress common.Address) *big
func (cs *ConfigService) GetReduceOnlyAmounts(trader common.Address) []*big.Int {
return bibliophile.GetReduceOnlyAmounts(cs.getStateAtCurrentBlock(), trader)
}

func (cs *ConfigService) IsSettledAll() bool {
return bibliophile.IsSettledAll(cs.getStateAtCurrentBlock())
}
24 changes: 0 additions & 24 deletions plugin/evm/orderbook/hubbleutils/config.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,11 @@
package hubbleutils

import "math/big"

var (
ChainId int64
VerifyingContract string
hState *HubbleState
)

func SetChainIdAndVerifyingSignedOrdersContract(chainId int64, verifyingContract string) {
ChainId = chainId
VerifyingContract = verifyingContract
}

func SetHubbleState(_hState *HubbleState) {
hState = _hState
}

func GetHubbleState() *HubbleState {
assets := make([]Collateral, len(hState.Assets))
copy(assets, hState.Assets)

activeMarkets := make([]Market, len(hState.ActiveMarkets))
copy(activeMarkets, hState.ActiveMarkets)

return &HubbleState{
Assets: assets,
ActiveMarkets: activeMarkets,
MinAllowableMargin: new(big.Int).Set(hState.MinAllowableMargin),
MaintenanceMargin: new(big.Int).Set(hState.MaintenanceMargin),
TakerFee: new(big.Int).Set(hState.TakerFee),
UpgradeVersion: hState.UpgradeVersion,
}
}
1 change: 1 addition & 0 deletions plugin/evm/orderbook/hubbleutils/margin_math.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func GetNotionalPositionAndMargin(hState *HubbleState, userState *UserState, mar
return notionalPosition, Add(margin, unrealizedPnl)
}

// SUNSET: `hState.ActiveMarkets` in the hState passed contains settled markets too
func GetTotalNotionalPositionAndUnrealizedPnl(hState *HubbleState, userState *UserState, margin *big.Int, marginMode MarginMode) (*big.Int, *big.Int) {
notionalPosition := big.NewInt(0)
unrealizedPnl := big.NewInt(0)
Expand Down
1 change: 1 addition & 0 deletions plugin/evm/orderbook/liquidations.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func (liq LiquidablePosition) GetUnfilledSize() *big.Int {
}

func calcMarginFraction(trader *Trader, hState *hu.HubbleState) *big.Int {
// SUNSET: this function is only used in unit tests and a test API; no need to change it
userState := &hu.UserState{
Positions: translatePositions(trader.Positions),
Margins: getMargins(trader, len(hState.Assets)),
Expand Down
10 changes: 8 additions & 2 deletions plugin/evm/orderbook/matching_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (pipeline *MatchingPipeline) Run(blockNumber *big.Int) bool {

// reset ticker
pipeline.MatchingTicker.Reset(matchingTickerDuration)
// SUNSET: this is ok, we can skip matching, liquidation, settleFunding, commitSampleLiquidity when markets are settled
markets := pipeline.GetActiveMarkets()
log.Info("MatchingPipeline:Run", "blockNumber", blockNumber)

Expand Down Expand Up @@ -93,7 +94,7 @@ func (pipeline *MatchingPipeline) Run(blockNumber *big.Int) bool {
}

// fetch various hubble market params and run the matching engine
hState := hu.GetHubbleState()
hState := GetHubbleState(pipeline.configService)
hState.OraclePrices = hu.ArrayToMap(pipeline.configService.GetUnderlyingPrices())

// build trader map
Expand Down Expand Up @@ -123,6 +124,7 @@ func (pipeline *MatchingPipeline) GetOrderMatchingTransactions(blockNumber *big.
pipeline.mu.Lock()
defer pipeline.mu.Unlock()

// SUNSET: ok to skip when markets are settled
activeMarkets := pipeline.GetActiveMarkets()
log.Info("MatchingPipeline:GetOrderMatchingTransactions")

Expand All @@ -134,7 +136,7 @@ func (pipeline *MatchingPipeline) GetOrderMatchingTransactions(blockNumber *big.
pipeline.lotp.PurgeOrderBookTxs()

// fetch various hubble market params and run the matching engine
hState := hu.GetHubbleState()
hState := GetHubbleState(pipeline.configService)
hState.OraclePrices = hu.ArrayToMap(pipeline.configService.GetUnderlyingPrices())

marginMap := make(map[common.Address]*big.Int)
Expand Down Expand Up @@ -228,11 +230,15 @@ func (pipeline *MatchingPipeline) runLiquidations(liquidablePositions []Liquidab
log.Info("found positions to liquidate", "num", len(liquidablePositions))

// we need to retreive permissible bounds for liquidations in each market
// SUNSET: this is ok, we can skip liquidations when markets are settled
markets := pipeline.GetActiveMarkets()
type S struct {
Upperbound *big.Int
Lowerbound *big.Int
}
if len(markets) == 0 {
return
}
liquidationBounds := make([]S, len(markets))
for _, market := range markets {
upperbound, lowerbound := pipeline.configService.GetAcceptableBoundsForLiquidation(market)
Expand Down
7 changes: 5 additions & 2 deletions plugin/evm/orderbook/memory_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ func (db *InMemoryDatabase) Accept(acceptedBlockNumber, blockTimestamp uint64) {
defer db.mu.Unlock()

log.Info("Accept", "acceptedBlockNumber", acceptedBlockNumber, "blockTimestamp", blockTimestamp)
// SUNSET: this will work with 0 markets
count := db.configService.GetActiveMarketsCount()
for m := int64(0); m < count; m++ {
longOrders := db.getLongOrdersWithoutLock(Market(m), nil, nil, false)
Expand Down Expand Up @@ -590,7 +591,8 @@ func (db *InMemoryDatabase) UpdateFilledBaseAssetQuantity(quantity *big.Int, ord

// only update margin if the order is not reduce-only
if order.OrderType == Signed && !order.ReduceOnly {
minAllowableMargin := hu.GetHubbleState().MinAllowableMargin
hState := GetHubbleState(db.configService)
minAllowableMargin := hState.MinAllowableMargin
requiredMargin := hu.GetRequiredMargin(order.Price, quantity, minAllowableMargin, big.NewInt(0))
db.updateVirtualReservedMargin(order.Trader, hu.Neg(requiredMargin))

Expand Down Expand Up @@ -1335,7 +1337,7 @@ func (db *InMemoryDatabase) GetMarginAvailableForMakerbook(trader common.Address
return big.NewInt(0)
}

hState := hu.GetHubbleState()
hState := GetHubbleState(db.configService)
hState.OraclePrices = prices
userState := &hu.UserState{
Positions: translatePositions(_trader.Positions),
Expand All @@ -1353,6 +1355,7 @@ func (db *InMemoryDatabase) SampleImpactPrice() (impactBids, impactAsks, midPric
db.mu.RLock()
defer db.mu.RUnlock()

// SUNSET: code will not reach here when markets are settled
count := db.configService.GetActiveMarketsCount()
impactBids = make([]*big.Int, count)
impactAsks = make([]*big.Int, count)
Expand Down
4 changes: 4 additions & 0 deletions plugin/evm/orderbook/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,3 +347,7 @@ func (cs *MockConfigService) GetImpactMarginNotional(ammAddress common.Address)
func (cs *MockConfigService) GetReduceOnlyAmounts(trader common.Address) []*big.Int {
return []*big.Int{big.NewInt(0)}
}

func (cs *MockConfigService) IsSettledAll() bool {
return false
}
23 changes: 23 additions & 0 deletions plugin/evm/orderbook/state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package orderbook

import (
hu "github.com/ava-labs/subnet-evm/plugin/evm/orderbook/hubbleutils"
)

func GetHubbleState(configService IConfigService) *hu.HubbleState {
count := configService.GetActiveMarketsCount()
markets := make([]Market, count)
for i := int64(0); i < count; i++ {
markets[i] = Market(i)
}
hState := &hu.HubbleState{
Assets: configService.GetCollaterals(),
ActiveMarkets: markets,
MinAllowableMargin: configService.GetMinAllowableMargin(),
MaintenanceMargin: configService.GetMaintenanceMargin(),
TakerFee: configService.GetTakerFee(),
UpgradeVersion: hu.V2,
}

return hState
}
5 changes: 5 additions & 0 deletions plugin/evm/orderbook/trading_apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ func (api *TradingAPI) GetMarginAndPositions(ctx context.Context, trader string)
return response, fmt.Errorf("trader not found")
}

// SUNSET: need to fetch total market count here, not active markets(cuz we're fetching pending funding)
count := api.configService.GetActiveMarketsCount()
markets := make([]Market, count)
for i := int64(0); i < count; i++ {
Expand Down Expand Up @@ -336,6 +337,10 @@ func (api *TradingAPI) StreamMarketTrades(ctx context.Context, market Market, bl

// @todo cache api.configService values to avoid db lookups on every order placement
func (api *TradingAPI) PlaceOrder(order *hu.SignedOrder) (common.Hash, bool, error) {
if api.configService.IsSettledAll() {
return common.Hash{}, false, errors.New("all markets are settled now")
}

orderId, err := order.Hash()
if err != nil {
return common.Hash{}, false, fmt.Errorf("failed to hash order: %s", err)
Expand Down
4 changes: 2 additions & 2 deletions precompile/contracts/bibliophile/clearing_house.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func marketsStorageSlot() *big.Int {
}

func GetActiveMarketsCount(stateDB contract.StateDB) int64 {
if isSettledAll(stateDB) {
if IsSettledAll(stateDB) {
return 0
}
return GetMarketsCountRaw(stateDB)
Expand All @@ -50,7 +50,7 @@ func GetMarketsCountRaw(stateDB contract.StateDB) int64 {
return new(big.Int).SetBytes(rawVal.Bytes()).Int64()
}

func isSettledAll(stateDB contract.StateDB) bool {
func IsSettledAll(stateDB contract.StateDB) bool {
return stateDB.GetState(common.HexToAddress(CLEARING_HOUSE_GENESIS_ADDRESS), common.BigToHash(big.NewInt(SETTLED_ALL_SLOT))).Big().Sign() == 1
}

Expand Down

0 comments on commit 832158d

Please sign in to comment.