From 9b326515c87ec2b7986820fbcc642c6419110f0f Mon Sep 17 00:00:00 2001 From: Jonathan Chappelow Date: Wed, 29 Jul 2020 19:17:52 -0500 Subject: [PATCH] storing both cancel Matches a little differently --- client/core/trade.go | 59 +++++++++++++++++++++----------------------- client/db/types.go | 6 +++++ 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/client/core/trade.go b/client/core/trade.go index f306b594ac..d1d61d829e 100644 --- a/client/core/trade.go +++ b/client/core/trade.go @@ -40,13 +40,6 @@ type matchTracker struct { id order.MatchID } -// The status is part of both the UserMatch and the MatchMetaData used to -// update the DB. Set them both together. -func (match *matchTracker) setStatus(status order.MatchStatus) { - match.Match.Status = status - match.MetaData.Status = status -} - // parts is a getter for pointers to commonly used struct fields in the // matchTracker. func (match *matchTracker) parts() (*order.UserMatch, *db.MatchMetaData, *db.MatchProof, *db.MatchAuth) { @@ -316,7 +309,6 @@ func (t *trackedTrade) negotiate(msgMatches []*msgjson.Match) error { defer t.mtx.Unlock() var newFill uint64 var cancelMatch *msgjson.Match - var cancelMetaMatch *db.MetaMatch newTrackers := make([]*matchTracker, 0, len(msgMatches)) for _, msgMatch := range msgMatches { if len(msgMatch.MatchID) != order.MatchIDSize { @@ -331,13 +323,6 @@ func (t *trackedTrade) negotiate(msgMatches []*msgjson.Match) error { return fmt.Errorf("negotiate called for wrong order. %s != %s", oid, t.ID()) } - match := &matchTracker{ - id: mid, - prefix: t.Prefix(), - trade: trade, - MetaMatch: *t.makeMetaMatch(msgMatch), - } - // First check if this is a match with a cancel order, in which case the // counterparty Address field would be empty. If the user placed a // cancel order, that order will be recorded in t.cancel on cancel order @@ -347,12 +332,17 @@ func (t *trackedTrade) negotiate(msgMatches []*msgjson.Match) error { log.Infof("Maker notification for cancel order received for order %s. match id = %s", oid, msgMatch.MatchID) cancelMatch = msgMatch - match.setStatus(order.MatchComplete) - cancelMetaMatch = &match.MetaMatch newFill += msgMatch.Quantity // should push this trade to 100% filled continue } + match := &matchTracker{ + id: mid, + prefix: t.Prefix(), + trade: trade, + MetaMatch: *t.makeMetaMatch(msgMatch), + } + var qty uint64 if t.Type() == order.MarketOrderType && !trade.Sell { qty = calc.BaseToQuote(msgMatch.Rate, msgMatch.Quantity) @@ -363,7 +353,7 @@ func (t *trackedTrade) negotiate(msgMatches []*msgjson.Match) error { log.Infof("Starting negotiation for match %v for order %v with swap fee rate = %v, quantity = %v", mid, oid, match.MetaMatch.Match.FeeRateSwap, qty) - match.setStatus(order.NewlyMatched) // these must be new matches + match.SetStatus(order.NewlyMatched) // these must be new matches newTrackers = append(newTrackers, match) } @@ -375,7 +365,17 @@ func (t *trackedTrade) negotiate(msgMatches []*msgjson.Match) error { // Set the order status for both orders. t.metaData.Status = order.OrderStatusCanceled t.db.UpdateOrderStatus(t.cancel.ID(), order.OrderStatusExecuted) - err := t.db.UpdateMatch(cancelMetaMatch) + // Store a completed maker cancel match in the DB. + makerCancelMeta := t.makeMetaMatch(cancelMatch) + makerCancelMeta.SetStatus(order.MatchComplete) + err := t.db.UpdateMatch(makerCancelMeta) + if err != nil { + return fmt.Errorf("failed to update match in db: %w", err) + } + // Store a completed taker cancel match too. + takerCancelMeta := t.makeMetaMatch(t.cancel.matches.taker) + takerCancelMeta.SetStatus(order.MatchComplete) + err = t.db.UpdateMatch(takerCancelMeta) if err != nil { return fmt.Errorf("failed to update match in db: %w", err) } @@ -516,10 +516,7 @@ func (t *trackedTrade) processCancelMatch(msgMatch *msgjson.Match) error { } log.Infof("Taker notification for cancel order %v received. Match id = %s", oid, mid) t.cancel.matches.taker = msgMatch - err := t.db.UpdateMatch(t.makeMetaMatch(msgMatch)) - if err != nil { - return fmt.Errorf("failed to update match in db: %w", err) - } + // Store this match at the same time as the maker side in negotiate. return nil } @@ -1048,10 +1045,10 @@ func (t *trackedTrade) finalizeSwapAction(match *matchTracker, coinID, contract proof.Script = contract if match.Match.Side == order.Taker { proof.TakerSwap = coinID - match.setStatus(order.TakerSwapCast) + match.SetStatus(order.TakerSwapCast) } else { proof.MakerSwap = coinID - match.setStatus(order.MakerSwapCast) + match.SetStatus(order.MakerSwapCast) } if len(ack.Sig) != 0 { auth.InitSig = ack.Sig @@ -1145,10 +1142,10 @@ func (t *trackedTrade) finalizeRedeemAction(match *matchTracker, coinID []byte) auth.RedeemStamp = encode.UnixMilliU(time.Now()) } if match.Match.Side == order.Taker { - match.setStatus(order.MatchComplete) + match.SetStatus(order.MatchComplete) proof.TakerRedeem = coinID } else { - match.setStatus(order.MakerRedeemed) + match.SetStatus(order.MakerRedeemed) proof.MakerRedeem = coinID } if err := t.db.UpdateMatch(&match.MetaMatch); err != nil { @@ -1315,13 +1312,13 @@ func (t *trackedTrade) processAudit(msgID uint64, audit *msgjson.Audit) error { if !bytes.Equal(proof.SecretHash, auditInfo.SecretHash()) { return errs.add("secret hash mismatch. expected %x, got %x", proof.SecretHash, auditInfo.SecretHash()) } - match.setStatus(order.TakerSwapCast) + match.SetStatus(order.TakerSwapCast) proof.TakerSwap = []byte(audit.CoinID) // counterparty = taker, their locktime = 24 hours. reqLockTime = encode.DropMilliseconds(matchTime.Add(t.lockTimeTaker)) } else { proof.SecretHash = auditInfo.SecretHash() - match.setStatus(order.MakerSwapCast) + match.SetStatus(order.MakerSwapCast) proof.MakerSwap = []byte(audit.CoinID) } @@ -1382,7 +1379,7 @@ func (t *trackedTrade) processRedemption(msgID uint64, redemption *msgjson.Redem // You are the maker, this is the taker's redeem. log.Debugf("Notified of taker's redemption (%s: %v) for order %v...", redeemAsset.Symbol, coinIDString(redeemAsset.ID, redemption.CoinID), t.ID()) - match.setStatus(order.MatchComplete) + match.SetStatus(order.MatchComplete) proof.TakerRedeem = []byte(redemption.CoinID) err := t.db.UpdateMatch(&match.MetaMatch) if err != nil { @@ -1406,7 +1403,7 @@ func (t *trackedTrade) processRedemption(msgID uint64, redemption *msgjson.Redem log.Infof("Notified of maker's redemption (%s: %v) and validated secret for order %v...", redeemAsset.Symbol, coinIDString(redeemAsset.ID, redemption.CoinID), t.ID()) - match.setStatus(order.MakerRedeemed) + match.SetStatus(order.MakerRedeemed) proof.MakerRedeem = []byte(redemption.CoinID) proof.Secret = redemption.Secret err = t.db.UpdateMatch(&match.MetaMatch) diff --git a/client/db/types.go b/client/db/types.go index d8a46d3bb0..47c63971df 100644 --- a/client/db/types.go +++ b/client/db/types.go @@ -193,6 +193,12 @@ type MetaMatch struct { Match *order.UserMatch } +// SetStatus sets the match status in both the UserMatch and the MatchMetaData. +func (m *MetaMatch) SetStatus(status order.MatchStatus) { + m.MetaData.Status = status + m.Match.Status = status +} + // ID is a unique ID for the match-order pair. func (m *MetaMatch) ID() []byte { return hashKey(append(m.Match.MatchID[:], m.Match.OrderID[:]...))