Skip to content

Commit

Permalink
client/core: store both cancel Matches
Browse files Browse the repository at this point in the history
  • Loading branch information
chappjc committed Jul 29, 2020
1 parent db23b03 commit 6711919
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 43 deletions.
2 changes: 1 addition & 1 deletion client/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ func (dc *dexConnection) runMatches(tradeMatches map[order.OrderID]*serverMatche
// reporting.
//
// DRAFT NOTE: Right now, the matches are just checked and notifications sent,
// but it may be a good place to trigger a FindRedemption if the conditions
// but it may be a good place to trigger a FindRedemption if the conditions
// warrant.
func (dc *dexConnection) compareServerMatches(matches map[order.OrderID]*serverMatches) {
for _, match := range matches {
Expand Down
105 changes: 63 additions & 42 deletions client/core/trade.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ 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 @@ -330,6 +331,13 @@ 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 @@ -339,49 +347,12 @@ 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
}

// Contract txn asset: buy means quote, sell means base. NOTE:
// msgjson.Match could instead have just FeeRateSwap for the recipient,
// but the other fee rate this way could be of value for auditing the
// counter party's contract txn.
feeRateSwap := msgMatch.FeeRateQuote
if trade.Sell {
feeRateSwap = msgMatch.FeeRateBase
}

match := &matchTracker{
id: mid,
prefix: t.Prefix(),
trade: trade,
MetaMatch: db.MetaMatch{
MetaData: &db.MatchMetaData{
Status: order.NewlyMatched,
Proof: db.MatchProof{
Auth: db.MatchAuth{
MatchSig: msgMatch.Sig,
MatchStamp: msgMatch.ServerTime,
},
},
DEX: t.dc.acct.host,
Base: t.Base(),
Quote: t.Quote(),
},
Match: &order.UserMatch{
OrderID: oid,
MatchID: mid,
Quantity: msgMatch.Quantity,
Rate: msgMatch.Rate,
Address: msgMatch.Address,
Status: order.MatchStatus(msgMatch.Status),
Side: order.MatchSide(msgMatch.Side),
FeeRateSwap: feeRateSwap,
},
},
}

var qty uint64
if t.Type() == order.MarketOrderType && !trade.Sell {
qty = calc.BaseToQuote(msgMatch.Rate, msgMatch.Quantity)
Expand All @@ -390,8 +361,9 @@ func (t *trackedTrade) negotiate(msgMatches []*msgjson.Match) error {
}
newFill += qty

log.Infof("Starting negotiation for match %v for order %v with feeRateSwap = %v, quantity = %v",
mid, oid, feeRateSwap, qty)
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
newTrackers = append(newTrackers, match)
}

Expand All @@ -403,6 +375,10 @@ 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)
if err != nil {
return fmt.Errorf("failed to update match in db: %w", err)
}
}
for _, match := range newTrackers {
t.matches[match.id] = match
Expand Down Expand Up @@ -484,11 +460,52 @@ func (t *trackedTrade) metaOrder() *db.MetaOrder {
}
}

func (t *trackedTrade) makeMetaMatch(msgMatch *msgjson.Match) *db.MetaMatch {
// Contract txn asset: buy means quote, sell means base. NOTE: msgjson.Match
// could instead have just FeeRateSwap for the recipient, but the other fee
// rate could be of value for auditing the counter party's contract txn.
feeRateSwap := msgMatch.FeeRateQuote
if t.Trade().Sell {
feeRateSwap = msgMatch.FeeRateBase
}

var oid order.OrderID
copy(oid[:], msgMatch.OrderID)
var mid order.MatchID
copy(mid[:], msgMatch.MatchID)
return &db.MetaMatch{
MetaData: &db.MatchMetaData{
Status: order.MatchStatus(msgMatch.Status),
Proof: db.MatchProof{
Auth: db.MatchAuth{
MatchSig: msgMatch.Sig,
MatchStamp: msgMatch.ServerTime,
},
},
DEX: t.dc.acct.host,
Base: t.Base(),
Quote: t.Quote(),
},
Match: &order.UserMatch{
OrderID: oid,
MatchID: mid,
Quantity: msgMatch.Quantity,
Rate: msgMatch.Rate,
Address: msgMatch.Address,
Status: order.MatchStatus(msgMatch.Status),
Side: order.MatchSide(msgMatch.Side),
FeeRateSwap: feeRateSwap,
},
}
}

// processCancelMatch should be called with the message for the match on a
// cancel order.
func (t *trackedTrade) processCancelMatch(msgMatch *msgjson.Match) error {
var oid order.OrderID
copy(oid[:], msgMatch.OrderID)
var mid order.MatchID
copy(mid[:], msgMatch.MatchID)
t.mtx.Lock()
defer t.mtx.Unlock()
if t.cancel == nil {
Expand All @@ -497,8 +514,12 @@ func (t *trackedTrade) processCancelMatch(msgMatch *msgjson.Match) error {
if oid != t.cancel.ID() {
return fmt.Errorf("negotiate called for wrong order. %s != %s", oid, t.cancel.ID())
}
log.Infof("Taker notification for cancel order %v received. Match id = %s", oid, msgMatch.MatchID)
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)
}
return nil
}

Expand Down

0 comments on commit 6711919

Please sign in to comment.