diff --git a/plugin/evm/limit_order.go b/plugin/evm/limit_order.go index 81733cad5d..3c0d34afba 100644 --- a/plugin/evm/limit_order.go +++ b/plugin/evm/limit_order.go @@ -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) @@ -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) } @@ -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 diff --git a/plugin/evm/orderbook/config_service.go b/plugin/evm/orderbook/config_service.go index efc0f6c285..ee71a82471 100644 --- a/plugin/evm/orderbook/config_service.go +++ b/plugin/evm/orderbook/config_service.go @@ -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 @@ -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()) } diff --git a/plugin/evm/orderbook/errors.go b/plugin/evm/orderbook/errors.go index 1ea1b3e877..df7f92a021 100644 --- a/plugin/evm/orderbook/errors.go +++ b/plugin/evm/orderbook/errors.go @@ -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" ) diff --git a/plugin/evm/orderbook/hubbleutils/config.go b/plugin/evm/orderbook/hubbleutils/config.go new file mode 100644 index 0000000000..5d5c885716 --- /dev/null +++ b/plugin/evm/orderbook/hubbleutils/config.go @@ -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 +} diff --git a/plugin/evm/orderbook/hubbleutils/signed_orders.go b/plugin/evm/orderbook/hubbleutils/signed_orders.go index 4c1dd0f343..b93ff51708 100644 --- a/plugin/evm/orderbook/hubbleutils/signed_orders.go +++ b/plugin/evm/orderbook/hubbleutils/signed_orders.go @@ -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 { diff --git a/plugin/evm/orderbook/liquidations_test.go b/plugin/evm/orderbook/liquidations_test.go index 3b49bbb1ed..2ed27836dc 100644 --- a/plugin/evm/orderbook/liquidations_test.go +++ b/plugin/evm/orderbook/liquidations_test.go @@ -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)) @@ -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)) @@ -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 @@ -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 @@ -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)) diff --git a/plugin/evm/orderbook/matching_pipeline.go b/plugin/evm/orderbook/matching_pipeline.go index d4071138cb..13cf5016c1 100644 --- a/plugin/evm/orderbook/matching_pipeline.go +++ b/plugin/evm/orderbook/matching_pipeline.go @@ -15,6 +15,7 @@ import ( const ( // ticker frequency for calling signalTxsReady matchingTickerDuration = 5 * time.Second + sanitaryTickerDuration = 1 * time.Second ) type MatchingPipeline struct { @@ -23,6 +24,7 @@ type MatchingPipeline struct { lotp LimitOrderTxProcessor configService IConfigService MatchingTicker *time.Ticker + SanitaryTicker *time.Ticker } func NewMatchingPipeline( @@ -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() @@ -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) @@ -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) @@ -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 diff --git a/plugin/evm/orderbook/matching_pipeline_test.go b/plugin/evm/orderbook/matching_pipeline_test.go index 512fbd718c..c6ee86396f 100644 --- a/plugin/evm/orderbook/matching_pipeline_test.go +++ b/plugin/evm/orderbook/matching_pipeline_test.go @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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}}} diff --git a/plugin/evm/orderbook/memory_database.go b/plugin/evm/orderbook/memory_database.go index 380ff92333..3ff20ec5fb 100644 --- a/plugin/evm/orderbook/memory_database.go +++ b/plugin/evm/orderbook/memory_database.go @@ -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)) } @@ -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)) @@ -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) } } @@ -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, diff --git a/plugin/evm/orderbook/memory_database_test.go b/plugin/evm/orderbook/memory_database_test.go index 2a73a77a91..fa0b4d337e 100644 --- a/plugin/evm/orderbook/memory_database_test.go +++ b/plugin/evm/orderbook/memory_database_test.go @@ -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) @@ -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) diff --git a/plugin/evm/orderbook/metrics.go b/plugin/evm/orderbook/metrics.go index f1f7ca8261..cc42690f72 100644 --- a/plugin/evm/orderbook/metrics.go +++ b/plugin/evm/orderbook/metrics.go @@ -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) diff --git a/plugin/evm/orderbook/mocks.go b/plugin/evm/orderbook/mocks.go index a79e606d67..1230e250d0 100644 --- a/plugin/evm/orderbook/mocks.go +++ b/plugin/evm/orderbook/mocks.go @@ -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) } diff --git a/plugin/evm/orderbook/service.go b/plugin/evm/orderbook/service.go index e3c7dbac5e..4da6c95a4b 100644 --- a/plugin/evm/orderbook/service.go +++ b/plugin/evm/orderbook/service.go @@ -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) diff --git a/plugin/evm/orderbook/trading_apis.go b/plugin/evm/orderbook/trading_apis.go index 1185d6dcc5..50e2b57d04 100644 --- a/plugin/evm/orderbook/trading_apis.go +++ b/plugin/evm/orderbook/trading_apis.go @@ -345,7 +345,7 @@ func (api *TradingAPI) PlaceOrder(order *hu.SignedOrder) (common.Hash, error) { requiredMargin := big.NewInt(0) if !order.ReduceOnly { // P2. Margin is available for non-reduce only orders - minAllowableMargin := api.configService.getMinAllowableMargin() + minAllowableMargin := api.configService.GetMinAllowableMargin() // even tho order might be matched at a different price, we reserve margin at the price the order was placed at to keep it simple requiredMargin = hu.GetRequiredMargin(order.Price, hu.Abs(order.BaseAssetQuantity), minAllowableMargin, big.NewInt(0)) if fields.AvailableMargin.Cmp(requiredMargin) == -1 {