Skip to content

Commit

Permalink
mm/core: Fix multi trade funding error (#3099)
Browse files Browse the repository at this point in the history
When the wallet is not able to fund all the orders requested, it resulted
in a panic in the mm code, because a nil MultiTradeResult was returned.
This also fixes the UI to properly display unknown errors in the epoch
report.
  • Loading branch information
martonp authored Nov 27, 2024
1 parent 3a211e7 commit 73ffbe6
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 14 deletions.
2 changes: 1 addition & 1 deletion client/asset/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ type Wallet interface {
// FundMultiOrder funds multiple orders at once. The return values will
// be in the same order as the passed orders. If less values are returned
// than the number of orders, then the orders at the end of the list were
// not about to be funded.
// not able to be funded.
FundMultiOrder(ord *MultiOrder, maxLock uint64) (coins []Coins, redeemScripts [][]dex.Bytes, fundingFees uint64, err error)
// MaxFundingFees returns the max fees that could be paid for funding a swap.
MaxFundingFees(numTrades uint32, feeRate uint64, options map[string]string) uint64
Expand Down
22 changes: 14 additions & 8 deletions client/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -5759,23 +5759,29 @@ type MultiTradeResult struct {
// MultiTrade is used to place multiple standing limit orders on the same
// side of the same market simultaneously.
func (c *Core) MultiTrade(pw []byte, form *MultiTradeForm) []*MultiTradeResult {
results := make([]*MultiTradeResult, len(form.Placements))
results := make([]*MultiTradeResult, 0, len(form.Placements))

reqs, err := c.prepareMultiTradeRequests(pw, form)
if err != nil {
for i := range results {
results[i] = &MultiTradeResult{Error: err}
for range form.Placements {
results = append(results, &MultiTradeResult{Error: err})
}
return results
}

for i, req := range reqs {
var corder *Order
corder, err = c.sendTradeRequest(req)
for i := range form.Placements {
if i >= len(reqs) {
results = append(results, &MultiTradeResult{Error: errors.New("wallet unable to fund order")})
continue
}

req := reqs[i]
corder, err := c.sendTradeRequest(req)
if err != nil {
results[i] = &MultiTradeResult{Error: err}
results = append(results, &MultiTradeResult{Error: err})
continue
}
results[i] = &MultiTradeResult{Order: corder}
results = append(results, &MultiTradeResult{Order: corder})
}

return results
Expand Down
13 changes: 10 additions & 3 deletions client/mm/exchange_adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3630,11 +3630,14 @@ func (u *unifiedExchangeAdaptor) tradingLimitNotReached(epochNum uint64) bool {
if err == nil && !tradingLimitReached {
return
}

var unknownErr string
if err != nil {
unknownErr = err.Error()
}
u.updateEpochReport(&EpochReport{
PreOrderProblems: &BotProblems{
UserLimitTooLow: tradingLimitReached,
UnknownError: err,
UnknownError: unknownErr,
},
EpochNum: epochNum,
})
Expand Down Expand Up @@ -3707,6 +3710,10 @@ func (u *unifiedExchangeAdaptor) checkBotHealth(epochNum uint64) (healthy bool)
if healthy {
return
}
var unknownErr string
if err != nil {
unknownErr = err.Error()
}
problems := &BotProblems{
NoWalletPeers: map[uint32]bool{
u.baseID: baseAssetNoPeers,
Expand All @@ -3717,7 +3724,7 @@ func (u *unifiedExchangeAdaptor) checkBotHealth(epochNum uint64) (healthy bool)
u.quoteID: quoteAssetNotSynced,
},
AccountSuspended: accountSuspended,
UnknownError: err,
UnknownError: unknownErr,
}
u.updateEpochReport(&EpochReport{
PreOrderProblems: problems,
Expand Down
2 changes: 1 addition & 1 deletion client/mm/mm.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ type BotProblems struct {
// CausesSelfMatch is true if the order would cause a self match.
CausesSelfMatch bool `json:"causesSelfMatch"`
// UnknownError is set if an error occurred that was not one of the above.
UnknownError error `json:"unknownError"`
UnknownError string `json:"unknownError"`
}

// EpochReport contains a report of a bot's activity during an epoch.
Expand Down
2 changes: 1 addition & 1 deletion client/mm/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,5 @@ func updateBotProblemsBasedOnError(problems *BotProblems, err error) {
return
}

problems.UnknownError = err
problems.UnknownError = err.Error()
}
4 changes: 4 additions & 0 deletions client/webserver/site/src/js/mmutil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,10 @@ function botProblemMessages (problems: BotProblems | undefined, cexName: string,
msgs.push(intl.prep(intl.ID_CAUSES_SELF_MATCH))
}

if (problems.unknownError) {
msgs.push(problems.unknownError)
}

return msgs
}

Expand Down

0 comments on commit 73ffbe6

Please sign in to comment.