Skip to content

Commit

Permalink
instantiate hState once
Browse files Browse the repository at this point in the history
  • Loading branch information
atvanguard committed Feb 15, 2024
1 parent 1436ba3 commit 903f37c
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 62 deletions.
23 changes: 22 additions & 1 deletion plugin/evm/limit_order.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,20 @@ func NewLimitOrderProcesser(ctx *snow.Context, txPool *txpool.TxPool, shutdownCh
lotp := orderbook.NewLimitOrderTxProcessor(txPool, memoryDb, backend, validatorPrivateKey)
signedObAddy := configService.GetSignedOrderbookContract()
contractEventProcessor := orderbook.NewContractEventsProcessor(memoryDb, signedObAddy)
hu.SetChainIdAndVerifyingSignedOrdersContract(backend.ChainConfig().ChainID.Int64(), signedObAddy.String())

matchingPipeline := orderbook.NewMatchingPipeline(memoryDb, lotp, configService)
// if any of the following values are changed, the nodes will need to be restarted
hState := &hu.HubbleState{
Assets: matchingPipeline.GetCollaterals(),
ActiveMarkets: matchingPipeline.GetActiveMarkets(),
MinAllowableMargin: configService.GetMinAllowableMargin(),
MaintenanceMargin: configService.GetMaintenanceMargin(),
TakerFee: configService.GetTakerFee(),
UpgradeVersion: configService.GetUpgradeVersion(),
}
hu.SetHubbleState(hState)
hu.SetChainIdAndVerifyingSignedOrdersContract(backend.ChainConfig().ChainID.Int64(), signedObAddy.String())

filterSystem := filters.NewFilterSystem(backend, filters.Config{})
filterAPI := filters.NewFilterAPI(filterSystem)

Expand Down Expand Up @@ -169,6 +181,12 @@ func (lop *limitOrderProcesser) RunMatchingPipeline() {
}, orderbook.RunMatchingPipelinePanicMessage, orderbook.RunMatchingPipelinePanicsCounter)
}

func (lop *limitOrderProcesser) RunSanitaryPipeline() {
executeFuncAndRecoverPanic(func() {
lop.matchingPipeline.RunSanitization()
}, orderbook.RunSanitaryPipelinePanicMessage, orderbook.RunSanitaryPipelinePanicsCounter)
}

func (lop *limitOrderProcesser) GetOrderBookAPI() *orderbook.OrderBookAPI {
return orderbook.NewOrderBookAPI(lop.memoryDb, lop.backend, lop.configService)
}
Expand Down Expand Up @@ -319,6 +337,9 @@ func (lop *limitOrderProcesser) runMatchingTimer() {
case <-lop.matchingPipeline.MatchingTicker.C:
lop.RunMatchingPipeline()

case <-lop.matchingPipeline.SanitaryTicker.C:
lop.RunSanitaryPipeline()

case <-lop.shutdownChan:
lop.matchingPipeline.MatchingTicker.Stop()
return
Expand Down
8 changes: 4 additions & 4 deletions plugin/evm/orderbook/config_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
type IConfigService interface {
getMaxLiquidationRatio(market Market) *big.Int
getLiquidationSpreadThreshold(market Market) *big.Int
getMinAllowableMargin() *big.Int
getMaintenanceMargin() *big.Int
GetMinAllowableMargin() *big.Int
GetMaintenanceMargin() *big.Int
getMinSizeRequirement(market Market) *big.Int
GetPriceMultiplier(market Market) *big.Int
GetActiveMarketsCount() int64
Expand Down Expand Up @@ -64,11 +64,11 @@ func (cs *ConfigService) getMaxLiquidationRatio(market Market) *big.Int {
return bibliophile.GetMaxLiquidationRatio(cs.getStateAtCurrentBlock(), int64(market))
}

func (cs *ConfigService) getMinAllowableMargin() *big.Int {
func (cs *ConfigService) GetMinAllowableMargin() *big.Int {
return bibliophile.GetMinAllowableMargin(cs.getStateAtCurrentBlock())
}

func (cs *ConfigService) getMaintenanceMargin() *big.Int {
func (cs *ConfigService) GetMaintenanceMargin() *big.Int {
return bibliophile.GetMaintenanceMargin(cs.getStateAtCurrentBlock())
}

Expand Down
1 change: 1 addition & 0 deletions plugin/evm/orderbook/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ const (
HandleChainAcceptedLogsPanicMessage = "panic while processing chainAcceptedLogs"
HandleHubbleFeedLogsPanicMessage = "panic while processing hubbleFeedLogs"
RunMatchingPipelinePanicMessage = "panic while running matching pipeline"
RunSanitaryPipelinePanicMessage = "panic while running sanitary pipeline"
)
16 changes: 16 additions & 0 deletions plugin/evm/orderbook/hubbleutils/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package hubbleutils

var (
ChainId int64
VerifyingContract string
HState *HubbleState
)

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

func SetHubbleState(hState *HubbleState) {
HState = hState
}
10 changes: 0 additions & 10 deletions plugin/evm/orderbook/hubbleutils/signed_orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,6 @@ type SignedOrder struct {
Sig []byte `json:"sig"`
}

var (
ChainId int64
VerifyingContract string
)

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

func (order *SignedOrder) EncodeToABIWithoutType() ([]byte, error) {
signedOrderType, err := getOrderType("signed")
if err != nil {
Expand Down
18 changes: 9 additions & 9 deletions plugin/evm/orderbook/liquidations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestGetLiquidableTraders(t *testing.T) {
Assets: assets,
OraclePrices: map[Market]*big.Int{market: hu.Mul1e6(big.NewInt(110))},
ActiveMarkets: []hu.Market{market},
MinAllowableMargin: db.configService.getMinAllowableMargin(),
MinAllowableMargin: db.configService.GetMinAllowableMargin(),
}
liquidablePositions, _, _ := db.GetNaughtyTraders(hState)
assert.Equal(t, 0, len(liquidablePositions))
Expand All @@ -43,8 +43,8 @@ func TestGetLiquidableTraders(t *testing.T) {
OraclePrices: map[Market]*big.Int{market: hu.Mul1e6(big.NewInt(110))},
MidPrices: map[Market]*big.Int{market: hu.Mul1e6(big.NewInt(100))},
ActiveMarkets: []hu.Market{market},
MaintenanceMargin: db.configService.getMaintenanceMargin(),
MinAllowableMargin: db.configService.getMinAllowableMargin(),
MaintenanceMargin: db.configService.GetMaintenanceMargin(),
MinAllowableMargin: db.configService.GetMinAllowableMargin(),
}
liquidablePositions, _, _ := db.GetNaughtyTraders(hState)
assert.Equal(t, 0, len(liquidablePositions))
Expand Down Expand Up @@ -77,8 +77,8 @@ func TestGetLiquidableTraders(t *testing.T) {
OraclePrices: map[Market]*big.Int{market: hu.Mul1e6(big.NewInt(50))},
MidPrices: map[Market]*big.Int{market: hu.Mul1e6(big.NewInt(49))},
ActiveMarkets: []hu.Market{market},
MinAllowableMargin: db.configService.getMinAllowableMargin(),
MaintenanceMargin: db.configService.getMaintenanceMargin(),
MinAllowableMargin: db.configService.GetMinAllowableMargin(),
MaintenanceMargin: db.configService.GetMaintenanceMargin(),
UpgradeVersion: hu.V2,
}
oraclePrices := hState.OraclePrices
Expand Down Expand Up @@ -136,8 +136,8 @@ func TestGetLiquidableTraders(t *testing.T) {
OraclePrices: map[Market]*big.Int{market: hu.Mul1e6(big.NewInt(142))},
MidPrices: map[Market]*big.Int{market: hu.Mul1e6(big.NewInt(143))},
ActiveMarkets: []hu.Market{market},
MinAllowableMargin: db.configService.getMinAllowableMargin(),
MaintenanceMargin: db.configService.getMaintenanceMargin(),
MinAllowableMargin: db.configService.GetMinAllowableMargin(),
MaintenanceMargin: db.configService.GetMaintenanceMargin(),
}
oraclePrices := hState.OraclePrices

Expand Down Expand Up @@ -273,8 +273,8 @@ func getPosition(market Market, openNotional *big.Int, size *big.Int, unrealized

func getDatabase() *InMemoryDatabase {
configService := NewMockConfigService()
configService.Mock.On("getMaintenanceMargin").Return(big.NewInt(1e5))
configService.Mock.On("getMinAllowableMargin").Return(big.NewInt(2e5))
configService.Mock.On("GetMaintenanceMargin").Return(big.NewInt(1e5))
configService.Mock.On("GetMinAllowableMargin").Return(big.NewInt(2e5))
configService.Mock.On("getMaxLiquidationRatio").Return(big.NewInt(1e6))
configService.Mock.On("getMinSizeRequirement").Return(big.NewInt(1e16))

Expand Down
25 changes: 11 additions & 14 deletions plugin/evm/orderbook/matching_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
const (
// ticker frequency for calling signalTxsReady
matchingTickerDuration = 5 * time.Second
sanitaryTickerDuration = 1 * time.Second
)

type MatchingPipeline struct {
Expand All @@ -23,6 +24,7 @@ type MatchingPipeline struct {
lotp LimitOrderTxProcessor
configService IConfigService
MatchingTicker *time.Ticker
SanitaryTicker *time.Ticker
}

func NewMatchingPipeline(
Expand All @@ -35,9 +37,14 @@ func NewMatchingPipeline(
lotp: lotp,
configService: configService,
MatchingTicker: time.NewTicker(matchingTickerDuration),
SanitaryTicker: time.NewTicker(sanitaryTickerDuration),
}
}

func (pipeline *MatchingPipeline) RunSanitization() {
pipeline.db.RemoveExpiredSignedOrders()
}

func (pipeline *MatchingPipeline) Run(blockNumber *big.Int) bool {
pipeline.mu.Lock()
defer pipeline.mu.Unlock()
Expand All @@ -54,9 +61,6 @@ func (pipeline *MatchingPipeline) Run(blockNumber *big.Int) bool {
// start fresh and purge all local transactions
pipeline.lotp.PurgeOrderBookTxs()

// remove expired signed orders
pipeline.db.RemoveExpiredSignedOrders()

if isFundingPaymentTime(pipeline.db.GetNextFundingTime()) {
log.Info("MatchingPipeline:isFundingPaymentTime")
err := executeFundingPayment(pipeline.lotp)
Expand All @@ -75,16 +79,9 @@ func (pipeline *MatchingPipeline) Run(blockNumber *big.Int) bool {
}

// fetch the underlying price and run the matching engine
hState := &hu.HubbleState{
Assets: pipeline.GetCollaterals(),
OraclePrices: pipeline.GetUnderlyingPrices(),
MidPrices: pipeline.GetMidPrices(),
ActiveMarkets: markets,
MinAllowableMargin: pipeline.configService.getMinAllowableMargin(),
MaintenanceMargin: pipeline.configService.getMaintenanceMargin(),
TakerFee: pipeline.configService.GetTakerFee(),
UpgradeVersion: pipeline.configService.GetUpgradeVersion(),
}
hState := hu.HState
hState.OraclePrices = pipeline.GetUnderlyingPrices()
hState.MidPrices = pipeline.GetMidPrices()

// build trader map
liquidablePositions, ordersToCancel, marginMap := pipeline.db.GetNaughtyTraders(hState)
Expand Down Expand Up @@ -208,7 +205,7 @@ func (pipeline *MatchingPipeline) runLiquidations(liquidablePositions []Liquidab
liquidationBounds[market] = S{Upperbound: upperbound, Lowerbound: lowerbound}
}

minAllowableMargin := pipeline.configService.getMinAllowableMargin()
minAllowableMargin := pipeline.configService.GetMinAllowableMargin()
takerFee := pipeline.configService.GetTakerFee()
for _, liquidable := range liquidablePositions {
market := liquidable.Market
Expand Down
12 changes: 6 additions & 6 deletions plugin/evm/orderbook/matching_pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestRunLiquidations(t *testing.T) {
orderMap := map[Market]*Orders{market: {longOrders, shortOrders}}

cs.On("GetAcceptableBoundsForLiquidation", market).Return(liqUpperBound, liqLowerBound)
cs.On("getMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetTakerFee").Return(big.NewInt(1e5))
pipeline.runLiquidations([]LiquidablePosition{getLiquidablePos(traderAddress, LONG, 7)}, orderMap, underlyingPrices, map[common.Address]*big.Int{})
assert.Equal(t, longOrders, orderMap[market].longOrders)
Expand All @@ -56,7 +56,7 @@ func TestRunLiquidations(t *testing.T) {
shortOrder := getShortOrder()
expectedFillAmount := utils.BigIntMinAbs(longOrder.BaseAssetQuantity, liquidablePositions[0].Size)
cs.On("GetAcceptableBoundsForLiquidation", market).Return(liqUpperBound, liqLowerBound)
cs.On("getMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetTakerFee").Return(big.NewInt(1e5))
lotp.On("ExecuteLiquidation", traderAddress, longOrder, expectedFillAmount).Return(nil)

Expand All @@ -80,7 +80,7 @@ func TestRunLiquidations(t *testing.T) {

expectedFillAmount := utils.BigIntMinAbs(longOrder.BaseAssetQuantity, liquidablePositions[0].Size)
cs.On("GetAcceptableBoundsForLiquidation", market).Return(liqUpperBound, liqLowerBound)
cs.On("getMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetTakerFee").Return(big.NewInt(1e5))
lotp.On("ExecuteLiquidation", traderAddress, longOrder, expectedFillAmount).Return(nil)

Expand All @@ -106,7 +106,7 @@ func TestRunLiquidations(t *testing.T) {
orderMap := map[Market]*Orders{market: {[]Order{longOrder0, longOrder1}, []Order{shortOrder0, shortOrder1}}}

cs.On("GetAcceptableBoundsForLiquidation", market).Return(liqUpperBound, liqLowerBound)
cs.On("getMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetTakerFee").Return(big.NewInt(1e5))
lotp.On("ExecuteLiquidation", traderAddress, orderMap[market].longOrders[0], big.NewInt(5)).Return(nil)
lotp.On("ExecuteLiquidation", traderAddress, orderMap[market].longOrders[1], big.NewInt(2)).Return(nil)
Expand Down Expand Up @@ -153,7 +153,7 @@ func TestRunLiquidations(t *testing.T) {
orderMap := map[Market]*Orders{market: {longOrders, shortOrders}}

cs.On("GetAcceptableBoundsForLiquidation", market).Return(liqUpperBound, liqLowerBound)
cs.On("getMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetTakerFee").Return(big.NewInt(1e5))
pipeline.runLiquidations(liquidablePositions, orderMap, underlyingPrices, map[common.Address]*big.Int{})
assert.Equal(t, longOrders, orderMap[market].longOrders)
Expand All @@ -168,7 +168,7 @@ func TestRunLiquidations(t *testing.T) {
expectedFillAmount := utils.BigIntMinAbs(shortOrder.BaseAssetQuantity, liquidablePositions[0].Size)
lotp.On("ExecuteLiquidation", traderAddress, shortOrder, expectedFillAmount).Return(nil)
cs.On("GetAcceptableBoundsForLiquidation", market).Return(liqUpperBound, liqLowerBound)
cs.On("getMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetMinAllowableMargin").Return(big.NewInt(1e5))
cs.On("GetTakerFee").Return(big.NewInt(1e5))

orderMap := map[Market]*Orders{market: {[]Order{longOrder}, []Order{shortOrder}}}
Expand Down
24 changes: 14 additions & 10 deletions plugin/evm/orderbook/memory_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ func (db *InMemoryDatabase) deleteOrderWithoutLock(orderId common.Hash) {
delete(db.Orders, orderId)

if order.OrderType == Signed && !order.ReduceOnly {
minAllowableMargin := db.configService.getMinAllowableMargin()
minAllowableMargin := db.configService.GetMinAllowableMargin()
requiredMargin := hu.GetRequiredMargin(order.Price, hu.Abs(order.GetUnFilledBaseAssetQuantity()), minAllowableMargin, big.NewInt(0))
db.updateVirtualReservedMargin(order.Trader, hu.Neg(requiredMargin))
}
Expand Down Expand Up @@ -616,7 +616,7 @@ 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 := db.configService.getMinAllowableMargin()
minAllowableMargin := db.configService.GetMinAllowableMargin()
requiredMargin := hu.GetRequiredMargin(order.Price, quantity, minAllowableMargin, big.NewInt(0))
db.updateVirtualReservedMargin(order.Trader, hu.Neg(requiredMargin))

Expand Down Expand Up @@ -1118,7 +1118,7 @@ func (db *InMemoryDatabase) determineOrdersToCancel(addr common.Address, trader
ordersToCancel[addr] = append(ordersToCancel[addr], order)
foundCancellableOrders = true
orderNotional := big.NewInt(0).Abs(hu.Div1e18(hu.Mul(order.GetUnFilledBaseAssetQuantity(), order.Price))) // | size * current price |
marginReleased := hu.Div1e6(hu.Mul(orderNotional, db.configService.getMinAllowableMargin()))
marginReleased := hu.Div1e6(hu.Mul(orderNotional, db.configService.GetMinAllowableMargin()))
_availableMargin.Add(_availableMargin, marginReleased)
}
}
Expand Down Expand Up @@ -1324,15 +1324,19 @@ func (db *InMemoryDatabase) GetOrderValidationFields(orderId common.Hash, order
}

availableMargin := big.NewInt(0)
if db.TraderMap[trader] != nil {
// backwards compatibility
if db.TraderMap[trader].Margin.Available == nil {
db.TraderMap[trader].Margin.Available = big.NewInt(0)
_trader := db.TraderMap[trader]
if _trader != nil {
hState := hu.HState
userState := &hu.UserState{
Positions: translatePositions(_trader.Positions),
Margins: getMargins(_trader, len(hState.Assets)),
PendingFunding: getTotalFunding(_trader, hState.ActiveMarkets),
ReservedMargin: new(big.Int).Set(_trader.Margin.Reserved),
}
if db.TraderMap[trader].Margin.VirtualReserved == nil {
db.TraderMap[trader].Margin.VirtualReserved = big.NewInt(0)
if _trader.Margin.VirtualReserved == nil {
_trader.Margin.VirtualReserved = big.NewInt(0)
}
availableMargin = hu.Sub(db.TraderMap[trader].Margin.Available /* as fresh as the last matching engine run */, db.TraderMap[trader].Margin.VirtualReserved)
availableMargin = hu.Sub(hu.GetAvailableMargin(hState, userState), _trader.Margin.VirtualReserved)
}
return OrderValidationFields{
Exists: false,
Expand Down
6 changes: 3 additions & 3 deletions plugin/evm/orderbook/memory_database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ func TestGetCancellableOrders(t *testing.T) {
inMemoryDatabase := getDatabase()
getReservedMargin := func(order Order) *big.Int {
notional := big.NewInt(0).Abs(big.NewInt(0).Div(big.NewInt(0).Mul(order.BaseAssetQuantity, order.Price), hu.ONE_E_18))
return hu.Div1e6(big.NewInt(0).Mul(notional, inMemoryDatabase.configService.getMinAllowableMargin()))
return hu.Div1e6(big.NewInt(0).Mul(notional, inMemoryDatabase.configService.GetMinAllowableMargin()))
}

blockNumber1 := big.NewInt(2)
Expand Down Expand Up @@ -418,8 +418,8 @@ func TestGetCancellableOrders(t *testing.T) {
OraclePrices: priceMap,
MidPrices: inMemoryDatabase.GetLastPrices(),
ActiveMarkets: []Market{market},
MinAllowableMargin: inMemoryDatabase.configService.getMinAllowableMargin(),
MaintenanceMargin: inMemoryDatabase.configService.getMaintenanceMargin(),
MinAllowableMargin: inMemoryDatabase.configService.GetMinAllowableMargin(),
MaintenanceMargin: inMemoryDatabase.configService.GetMaintenanceMargin(),
UpgradeVersion: hu.V2,
}
marginFraction := calcMarginFraction(_trader, hState)
Expand Down
1 change: 1 addition & 0 deletions plugin/evm/orderbook/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var (
// panics are recovered but monitored
AllPanicsCounter = metrics.NewRegisteredCounter("all_panics", nil)
RunMatchingPipelinePanicsCounter = metrics.NewRegisteredCounter("matching_pipeline_panics", nil)
RunSanitaryPipelinePanicsCounter = metrics.NewRegisteredCounter("sanitary_pipeline_panics", nil)
HandleHubbleFeedLogsPanicsCounter = metrics.NewRegisteredCounter("handle_hubble_feed_logs_panics", nil)
HandleChainAcceptedLogsPanicsCounter = metrics.NewRegisteredCounter("handle_chain_accepted_logs_panics", nil)
HandleChainAcceptedEventPanicsCounter = metrics.NewRegisteredCounter("handle_chain_accepted_event_panics", nil)
Expand Down
4 changes: 2 additions & 2 deletions plugin/evm/orderbook/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,12 @@ func (mcs *MockConfigService) getMaxLiquidationRatio(market Market) *big.Int {
return args.Get(0).(*big.Int)
}

func (mcs *MockConfigService) getMinAllowableMargin() *big.Int {
func (mcs *MockConfigService) GetMinAllowableMargin() *big.Int {
args := mcs.Called()
return args.Get(0).(*big.Int)
}

func (mcs *MockConfigService) getMaintenanceMargin() *big.Int {
func (mcs *MockConfigService) GetMaintenanceMargin() *big.Int {
args := mcs.Called()
return args.Get(0).(*big.Int)
}
Expand Down
4 changes: 2 additions & 2 deletions plugin/evm/orderbook/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ func (api *OrderBookAPI) GetDebugData(ctx context.Context, trader string) GetDeb
OraclePrices: oraclePrices,
MidPrices: midPrices,
ActiveMarkets: markets,
MinAllowableMargin: api.configService.getMinAllowableMargin(),
MaintenanceMargin: api.configService.getMaintenanceMargin(),
MinAllowableMargin: api.configService.GetMinAllowableMargin(),
MaintenanceMargin: api.configService.GetMaintenanceMargin(),
}
marginFraction := calcMarginFraction(&trader, hState)
availableMargin := getAvailableMargin(&trader, hState)
Expand Down
Loading

0 comments on commit 903f37c

Please sign in to comment.