Skip to content

Commit

Permalink
storing both cancel Matches a little differently
Browse files Browse the repository at this point in the history
  • Loading branch information
chappjc committed Jul 30, 2020
1 parent 6711919 commit 9b32651
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 31 deletions.
59 changes: 28 additions & 31 deletions client/core/trade.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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)
}

Expand All @@ -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)
}
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}

Expand Down Expand Up @@ -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 {
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions client/db/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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[:]...))
Expand Down

0 comments on commit 9b32651

Please sign in to comment.