diff --git a/tomox/mongodb.go b/tomox/mongodb.go index 3d21904c8c46..e5a8b3367482 100644 --- a/tomox/mongodb.go +++ b/tomox/mongodb.go @@ -256,7 +256,9 @@ func (db *MongoDatabase) CommitOrder(cacheKey string, o *OrderItem) error { defer sc.Close() // Store the key - o.Key = cacheKey + if len(o.Key) == 0 { + o.Key = cacheKey + } query := bson.M{"key": cacheKey} diff --git a/tomox/orderbook.go b/tomox/orderbook.go index 77478b70f4d9..f2a044cee9f4 100755 --- a/tomox/orderbook.go +++ b/tomox/orderbook.go @@ -413,7 +413,8 @@ func (orderBook *OrderBook) processOrderList(side string, orderList *OrderList, } transactionRecord := make(map[string]string) - transactionRecord["orderHash"] = hex.EncodeToString(headOrder.Item.Hash.Bytes()) + transactionRecord["takerOrderHash"] = hex.EncodeToString(order.Hash.Bytes()) + transactionRecord["makerOrderHash"] = hex.EncodeToString(headOrder.Item.Hash.Bytes()) transactionRecord["timestamp"] = strconv.FormatUint(orderBook.Timestamp, 10) transactionRecord["quantity"] = tradedQuantity.String() transactionRecord["exAddr"] = headOrder.Item.ExchangeAddress.String() diff --git a/tomox/tomox.go b/tomox/tomox.go index 990f02865a2d..fc7e47875031 100644 --- a/tomox/tomox.go +++ b/tomox/tomox.go @@ -966,10 +966,21 @@ func (tomox *TomoX) removeOrderPending(orderHash common.Hash) error { } switch data.(type) { case *OrderItem: - if err := tomox.db.Delete(key, false); err != nil { - log.Error("Fail to delete order pending", "err", err) - return err + if !tomox.IsSDKNode() { + if err := tomox.db.Delete(key, false); err != nil { + log.Error("Fail to delete order pending", "err", err) + return err + } + } else { + order := data.(*OrderItem) + // update order.key: remove pending prefix + order.Key = hex.EncodeToString(orderHash.Bytes()) + order.Status = sdktypes.OrderStatusOpen + if err := tomox.db.Put(key, order, false); err != nil { + return err + } } + default: return fmt.Errorf("Order is corrupted") } @@ -1291,36 +1302,73 @@ func (tomox *TomoX) SyncDataToSDKNode(txDataMatch *TxDataMatch, txHash common.Ha tradeSDK.BaseToken = order.BaseToken tradeSDK.QuoteToken = order.QuoteToken tradeSDK.Status = sdktypes.TradeStatusSuccess - tradeSDK.Maker = order.UserAddress - tradeSDK.MakerOrderHash = order.Hash + tradeSDK.Taker = order.UserAddress + tradeSDK.TakerOrderHash = order.Hash if u, ok := trade["uAddr"]; ok { tradeSDK.Taker = common.Address{} tradeSDK.Taker.SetString(u) } - tradeSDK.TakerOrderHash = order.Hash //FIXME: will update txMatch to include TakerOrderHash = headOrder.Item.Hash + makerOrderHash, err := hex.DecodeString(trade["makerOrderHash"]) + if err != nil { + return fmt.Errorf("SDKNode: failed to decode makerOrderHash. HashString: %s", trade["makerOrderHash"]) + } + tradeSDK.MakerOrderHash = common.BytesToHash(makerOrderHash) + tradeSDK.Maker = common.StringToAddress(trade["uAddr"]) tradeSDK.TxHash = txHash tradeSDK.Hash = tradeSDK.ComputeHash() log.Debug("TRADE history", "order", order, "trade", tradeSDK) if err := db.Put(EmptyKey(), tradeSDK, false); err != nil { return fmt.Errorf("SDKNode: failed to store tradeSDK %s", err.Error()) } - - // remove from orders - orderHashBytes, err := hex.DecodeString(trade["orderHash"]) - if err != nil { - return fmt.Errorf("SDKNode: failed to decode orderKey. Key: %s", trade["orderHash"]) + filledAmount, ok := new(big.Int).SetString(trade["quantity"], 10) + if !ok { + return fmt.Errorf("failed to get tradedQuantity. QuantityString: %s", trade["quantity"]) } - log.Debug("SDKNode: try to remove matched order from orders collection", "orderHash", trade["orderHash"]) - if err := db.Delete(orderHashBytes, false); err != nil { - return fmt.Errorf("SDKNode: failed to remove matched order from orders collection %s", trade["orderHash"]) + // update order status of relating orders + if err := tomox.updateStatusOfMatchedOrder(trade["makerOrderHash"], filledAmount); err != nil { + return err + } + if err := tomox.updateStatusOfMatchedOrder(trade["takerOrderHash"],filledAmount); err != nil { + return err } } + // in case of remaining order in orderTree, the status of order should be partial_filled if orderInBook != nil { - log.Debug("store orderInBook", "order", orderInBook) - if err = db.Put(orderInBook.Hash.Bytes(), orderInBook, false); err != nil { - return fmt.Errorf("SDKNode: failed to store orderInBook to sdkNode %s", err.Error()) + key := orderInBook.Hash.Bytes() + data, err := tomox.db.Get(key, &OrderItem{}, false) + if data == nil || err != nil { + return fmt.Errorf("SDKNode: failed to get order. Key: %s", hex.EncodeToString(key)) + } + order := data.(*OrderItem) + if order.Status == sdktypes.OrderStatusFilled { + // if order already matched but still exist in orderbook, then update status to OrderStatusPartialFilled + order.Status = sdktypes.OrderStatusPartialFilled + if err = db.Put(key, order, false); err != nil { + return fmt.Errorf("SDKNode: failed to update status to %s %s", sdktypes.OrderStatusPartialFilled, err.Error()) + } } } return nil } + +func (tomox *TomoX) updateStatusOfMatchedOrder(hashString string, filledAmount *big.Int) error { + db := tomox.GetDB() + orderHashBytes, err := hex.DecodeString(hashString) + if err != nil { + return fmt.Errorf("SDKNode: failed to decode orderKey. Key: %s", hashString) + } + val, err := db.Get(orderHashBytes, &OrderItem{}, false) + if err != nil || val == nil { + return fmt.Errorf("SDKNode: failed to get order. Key: %s", hashString) + } + matchedOrder := val.(*OrderItem) + matchedOrder.Status = sdktypes.OrderStatusFilled + updatedFillAmount := new(big.Int) + updatedFillAmount.Add(matchedOrder.FilledAmount, filledAmount) + matchedOrder.FilledAmount = updatedFillAmount + if err = db.Put(matchedOrder.Hash.Bytes(), matchedOrder, false); err != nil { + return fmt.Errorf("SDKNode: failed to update matchedOrder to sdkNode %s", err.Error()) + } + return nil +}