From 79de152083e72ab00d073c924b27edac757dd2a1 Mon Sep 17 00:00:00 2001 From: Shubham Date: Fri, 1 Sep 2023 14:49:07 +0530 Subject: [PATCH] SDK changes and review fixes (#105) --- .../orderbook/contract_events_processor.go | 11 +++++---- plugin/evm/orderbook/service.go | 2 ++ plugin/evm/orderbook/trading_apis.go | 2 ++ plugin/evm/orderbook/tx_processor.go | 23 ++++++++++++++----- utils/string.go | 10 ++++++++ 5 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 utils/string.go diff --git a/plugin/evm/orderbook/contract_events_processor.go b/plugin/evm/orderbook/contract_events_processor.go index f2cb20afc4..35b3070755 100644 --- a/plugin/evm/orderbook/contract_events_processor.go +++ b/plugin/evm/orderbook/contract_events_processor.go @@ -255,7 +255,7 @@ func (cep *ContractEventsProcessor) handleOrderBookEvent(event *types.Log) { BlockNumber: big.NewInt(int64(event.BlockNumber)), OrderType: LimitOrderType, } - log.Info("LimitOrder/OrderAccepted", "order", limitOrder, "number", event.BlockNumber, "timestamp", timestamp) + log.Info("LimitOrder/OrderAccepted", "order", limitOrder, "timestamp", timestamp) cep.database.Add(&limitOrder) } else { log.Info("LimitOrder/OrderAccepted removed", "args", args, "orderId", orderId.String(), "number", event.BlockNumber) @@ -477,12 +477,13 @@ func (cep *ContractEventsProcessor) handleClearingHouseEvent(event *types.Log) { // event NotifyNextPISample(uint nextSampleTime); case cep.clearingHouseABI.Events["NotifyNextPISample"].ID: - err := cep.clearingHouseABI.UnpackIntoMap(args, "SamplePI", event.Data) + err := cep.clearingHouseABI.UnpackIntoMap(args, "NotifyNextPISample", event.Data) if err != nil { - log.Error("error in clearingHouseABI.UnpackIntoMap", "method", "SamplePI", "err", err) + log.Error("error in clearingHouseABI.UnpackIntoMap", "method", "NotifyNextPISample", "err", err) return } nextSampleTime := args["nextSampleTime"].(*big.Int) + log.Info("NotifyNextPISample", "nextSampleTime", nextSampleTime) cep.database.UpdateNextSamplePITime(nextSampleTime.Uint64()) } } @@ -725,9 +726,9 @@ func (cep *ContractEventsProcessor) updateMetrics(logs []*types.Log) { } switch event_.Name { - case "OrderPlaced": + case "OrderPlaced", "OrderAccepted": orderPlacedCount++ - case "OrderCancelled": + case "OrderCancelled", "OrderCancelAccepted": orderCancelledCount++ } } diff --git a/plugin/evm/orderbook/service.go b/plugin/evm/orderbook/service.go index 71cf466a7e..b128ba1849 100644 --- a/plugin/evm/orderbook/service.go +++ b/plugin/evm/orderbook/service.go @@ -57,6 +57,7 @@ type OrderForOpenOrders struct { Salt string OrderId string ReduceOnly bool + PostOnly bool OrderType string } @@ -178,6 +179,7 @@ func (api *OrderBookAPI) GetOpenOrders(ctx context.Context, trader string, marke Salt: order.Salt.String(), OrderId: order.Id.String(), ReduceOnly: order.ReduceOnly, + PostOnly: order.isPostOnly(), OrderType: order.OrderType.String(), }) } diff --git a/plugin/evm/orderbook/trading_apis.go b/plugin/evm/orderbook/trading_apis.go index c7fa51a0fb..a3c3c95781 100644 --- a/plugin/evm/orderbook/trading_apis.go +++ b/plugin/evm/orderbook/trading_apis.go @@ -58,6 +58,7 @@ type OrderStatusResponse struct { OrigQty string `json:"origQty"` // "0.40" Price string `json:"price"` // "0" ReduceOnly bool `json:"reduceOnly"` // false + PostOnly bool `json:"postOnly"` // false PositionSide string `json:"positionSide"` // "SHORT" Status string `json:"status"` // "NEW" Symbol int64 `json:"symbol"` // "BTCUSDT" @@ -147,6 +148,7 @@ func (api *TradingAPI) GetOrderStatus(ctx context.Context, orderId common.Hash) OrigQty: utils.BigIntToDecimal(limitOrder.BaseAssetQuantity, 18, 8), Price: utils.BigIntToDecimal(limitOrder.Price, 6, 8), ReduceOnly: limitOrder.ReduceOnly, + PostOnly: limitOrder.isPostOnly(), PositionSide: positionSide, Status: status, Symbol: int64(limitOrder.Market), diff --git a/plugin/evm/orderbook/tx_processor.go b/plugin/evm/orderbook/tx_processor.go index 737d5ee89c..1c4fed7b6e 100644 --- a/plugin/evm/orderbook/tx_processor.go +++ b/plugin/evm/orderbook/tx_processor.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/subnet-evm/eth" "github.com/ava-labs/subnet-evm/metrics" "github.com/ava-labs/subnet-evm/plugin/evm/orderbook/abis" + "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -268,6 +269,11 @@ func getAddressFromPrivateKey(key string) (common.Address, error) { return address, nil } +func formatReceiptForLogging(receipt *types.Receipt) string { + return fmt.Sprintf("Receipt{Status: %d, CumulativeGasUsed: %d, GasUsed: %d, EffectiveGasPrice: %d, BlockNumber: %d}", + receipt.Status, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.EffectiveGasPrice, receipt.BlockNumber) +} + func (lotp *limitOrderTxProcessor) UpdateMetrics(block *types.Block) { // defer func(start time.Time) { log.Info("limitOrderTxProcessor.UpdateMetrics", "time", time.Since(start)) }(time.Now()) @@ -314,13 +320,11 @@ func (lotp *limitOrderTxProcessor) UpdateMetrics(block *types.Block) { orderBookTransactionsSuccessTotalCounter.Inc(1) } - if contractAddress != nil && lotp.orderBookContractAddress == *contractAddress { + if contractAddress != nil && (lotp.orderBookContractAddress == *contractAddress || lotp.clearingHouseContractAddress == *contractAddress) { note := "success" if receipt.Status == 0 { - log.Error("orderbook tx failed", "method", method.Name, "tx", tx.Hash().String(), - "receipt.Status", receipt.Status, "receipt.CumulativeGasUsed", receipt.CumulativeGasUsed, - "receipt.GasUsed", receipt.GasUsed, "receipt.EffectiveGasPrice", receipt.EffectiveGasPrice, - "receipt.BlockNumber", receipt.BlockNumber) + log.Error("this validator's tx failed", "method", method.Name, "tx", tx.Hash().String(), + "receipt", formatReceiptForLogging(receipt), "from", from.String()) note = "failure" } counterName := fmt.Sprintf("orderbooktxs/%s/%s", method.Name, note) @@ -328,7 +332,6 @@ func (lotp *limitOrderTxProcessor) UpdateMetrics(block *types.Block) { } } - // measure the gas usage irrespective of whether the tx is from this validator or not if contractAddress != nil { var contractName string switch *contractAddress { @@ -342,9 +345,17 @@ func (lotp *limitOrderTxProcessor) UpdateMetrics(block *types.Block) { continue } + // measure the gas usage irrespective of whether the tx is from this validator or not gasUsageMetric := fmt.Sprintf("orderbooktxs/%s/%s/gas", contractName, method.Name) sampler := metrics.ResettingSample(metrics.NewExpDecaySample(1028, 0.015)) metrics.GetOrRegisterHistogram(gasUsageMetric, nil, sampler).Update(int64(receipt.GasUsed)) + + // log the failure for validator txs irrespective of whether the tx is from this validator or not + // this will help us identify tx failures that are not due to a hubble's validator + validatorMethods := []string{"liquidateAndExecuteOrder", "executeMatchedOrders", "settleFunding", "samplePI", "cancelOrdersWithLowMargin"} + if receipt.Status == 0 && utils.ContainsString(validatorMethods, method.Name) { + log.Error("validator tx failed", "method", method.Name, "contractName", contractName, "tx", tx.Hash().String(), "from", from.String(), "receipt", formatReceiptForLogging(receipt)) + } } } } diff --git a/utils/string.go b/utils/string.go new file mode 100644 index 0000000000..dc0ee92f22 --- /dev/null +++ b/utils/string.go @@ -0,0 +1,10 @@ +package utils + +func ContainsString(list []string, item string) bool { + for _, i := range list { + if i == item { + return true + } + } + return false +}