Skip to content

Commit

Permalink
server: scoring, cancels limits
Browse files Browse the repository at this point in the history
server: freecancels option

server: max user cancels per epoch

banscore

auth: add SwapSuccess and Inaction, revert Penalize changes

auth,db: load user ban score from db
  • Loading branch information
chappjc committed Oct 5, 2020
1 parent 3e00c50 commit 73d04b4
Show file tree
Hide file tree
Showing 34 changed files with 1,267 additions and 165 deletions.
12 changes: 6 additions & 6 deletions client/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -2585,8 +2585,8 @@ func (c *Core) authDEX(dc *dexConnection) error {
}

// Set the account as authenticated.
log.Debugf("Authenticated connection to %s, %d active orders, %d active matches",
dc.acct.host, len(result.ActiveOrderStatuses), len(result.ActiveMatches))
log.Debugf("Authenticated connection to %s, %d active orders, %d active matches, score %d",
dc.acct.host, len(result.ActiveOrderStatuses), len(result.ActiveMatches), result.Score)
dc.acct.auth()

// Associate the matches with known trades.
Expand Down Expand Up @@ -3506,10 +3506,10 @@ func handlePenaltyMsg(c *Core, dc *dexConnection, msg *msgjson.Message) error {
if err != nil {
return newError(signatureErr, "handlePenaltyMsg: DEX signature validation error: %v", err)
}
t := encode.UnixTimeMilli(int64(note.Penalty.Time) * 1000)
d := time.Duration(note.Penalty.Duration)
details := fmt.Sprintf("Penalty from DEX at %s\nlast broken rule: %s\ntime: %v\nduration: %v\ndetails: %q\n",
dc.acct.host, note.Penalty.Rule, t, d, note.Penalty.Details)
t := encode.UnixTimeMilli(int64(note.Penalty.Time))
// d := time.Duration(note.Penalty.Duration) * time.Millisecond
details := fmt.Sprintf("Penalty from DEX at %s\nlast broken rule: %s\ntime: %v\ndetails:\n\"%s\"\n",
dc.acct.host, note.Penalty.Rule, t, note.Penalty.Details)
n := db.NewNotification("penalty", dc.acct.host, details, db.WarningLevel)
c.notify(&n)
return nil
Expand Down
40 changes: 22 additions & 18 deletions dex/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ package dex

import (
"fmt"
"math"
"strings"
)

// MarketInfo specifies a market that the Archiver must support.
type MarketInfo struct {
Name string
Base uint32
Quote uint32
LotSize uint64
EpochDuration uint64 // msec
MarketBuyBuffer float64
Name string
Base uint32
Quote uint32
LotSize uint64
EpochDuration uint64 // msec
MarketBuyBuffer float64
MaxUserCancelsPerEpoch uint32
}

func marketName(base, quote string) string {
Expand Down Expand Up @@ -50,12 +52,13 @@ func NewMarketInfo(base, quote uint32, lotSize, epochDuration uint64, marketBuyB
return nil, err
}
return &MarketInfo{
Name: name,
Base: base,
Quote: quote,
LotSize: lotSize,
EpochDuration: epochDuration,
MarketBuyBuffer: marketBuyBuffer,
Name: name,
Base: base,
Quote: quote,
LotSize: lotSize,
EpochDuration: epochDuration,
MarketBuyBuffer: marketBuyBuffer,
MaxUserCancelsPerEpoch: math.MaxUint32,
}, nil
}

Expand All @@ -76,11 +79,12 @@ func NewMarketInfoFromSymbols(base, quote string, lotSize, epochDuration uint64,
}

return &MarketInfo{
Name: marketName(base, quote),
Base: baseID,
Quote: quoteID,
LotSize: lotSize,
EpochDuration: epochDuration,
MarketBuyBuffer: marketBuyBuffer,
Name: marketName(base, quote),
Base: baseID,
Quote: quoteID,
LotSize: lotSize,
EpochDuration: epochDuration,
MarketBuyBuffer: marketBuyBuffer,
MaxUserCancelsPerEpoch: math.MaxUint32,
}, nil
}
1 change: 1 addition & 0 deletions dex/msgjson/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ type ConnectResult struct {
Sig Bytes `json:"sig"`
ActiveOrderStatuses []*OrderStatus `json:"activeorderstatuses"`
ActiveMatches []*Match `json:"activematches"`
Score int32 `json:"score"`
}

// PenaltyNote is the payload of a Penalty notification.
Expand Down
36 changes: 22 additions & 14 deletions dex/order/match.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"database/sql/driver"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"time"

Expand All @@ -31,27 +32,35 @@ func (id MatchID) Bytes() []byte {
}

// Value implements the sql/driver.Valuer interface.
func (mid MatchID) Value() (driver.Value, error) {
return mid[:], nil // []byte
func (id MatchID) Value() (driver.Value, error) {
return id[:], nil // []byte
}

// Scan implements the sql.Scanner interface.
func (mid *MatchID) Scan(src interface{}) error {
switch src := src.(type) {
case []byte:
copy(mid[:], src)
return nil
//case string:
// case nil:
// *oid = nil
// return nil
func (id *MatchID) Scan(src interface{}) error {
idB, ok := src.([]byte)
if !ok {
return fmt.Errorf("cannot convert %T to OrderID", src)
}

return fmt.Errorf("cannot convert %T to OrderID", src)
copy(id[:], idB)
return nil
}

var zeroMatchID MatchID

// DecodeMatchID checks a string as being both hex and the right length and
// returns its bytes encoded as an order.MatchID.
func DecodeMatchID(matchIDStr string) (MatchID, error) {
var matchID MatchID
if len(matchIDStr) != MatchIDSize*2 {
return matchID, errors.New("match id has incorrect length")
}
if _, err := hex.Decode(matchID[:], []byte(matchIDStr)); err != nil {
return matchID, fmt.Errorf("could not decode match id: %v", err)
}
return matchID, nil
}

// MatchStatus represents the current negotiation step for a match.
type MatchStatus uint8

Expand All @@ -76,7 +85,6 @@ const (
// their redemption transaction. The DEX has validated the redemption and
// sent the details to the maker.
MatchComplete // 4
//MatchRefunded // 5?
)

// String satisfies fmt.Stringer.
Expand Down
4 changes: 2 additions & 2 deletions dex/order/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ const (

// OrderStatusRevoked is DEX-revoked orders that were not canceled by
// matching with the client's cancel order but by DEX policy. This includes
// standing limit orders that were matched, but have failed to swap.
// (neither executed nor canceled).
// standing limit orders that were matched but have failed to swap (neither
// executed nor canceled), and preimage misses.
OrderStatusRevoked
)

Expand Down
29 changes: 29 additions & 0 deletions server/admin/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"decred.org/dcrdex/dex/encode"
"decred.org/dcrdex/dex/msgjson"
"decred.org/dcrdex/dex/order"
"decred.org/dcrdex/server/account"
"github.com/go-chi/chi"
)
Expand Down Expand Up @@ -314,6 +315,34 @@ func (s *Server) apiUnban(w http.ResponseWriter, r *http.Request) {
writeJSON(w, res)
}

// apiForgiveMatchFail is the handler for the '/account/{accountID}/forgive_match/{matchID}' API request.
func (s *Server) apiForgiveMatchFail(w http.ResponseWriter, r *http.Request) {
acctIDStr := chi.URLParam(r, accountIDKey)
acctID, err := decodeAcctID(acctIDStr)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
matchIDStr := chi.URLParam(r, matchIDKey)
matchID, err := order.DecodeMatchID(matchIDStr)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
forgiven, unbanned, err := s.core.ForgiveMatchFail(acctID, matchID)
if err != nil {
http.Error(w, fmt.Sprintf("failed to forgive failed match %v for account %v: %v", matchID, acctID, err), http.StatusInternalServerError)
return
}
res := ForgiveResult{
AccountID: acctIDStr,
Forgiven: forgiven,
Unbanned: unbanned,
ForgiveTime: APITime{time.Now()},
}
writeJSON(w, res)
}

func toNote(r *http.Request) (*msgjson.Message, int, error) {
body, err := ioutil.ReadAll(r.Body)
r.Body.Close()
Expand Down
5 changes: 4 additions & 1 deletion server/admin/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"time"

"decred.org/dcrdex/dex/msgjson"
"decred.org/dcrdex/dex/order"
"decred.org/dcrdex/server/account"
"decred.org/dcrdex/server/db"
"decred.org/dcrdex/server/market"
Expand All @@ -34,8 +35,8 @@ const (

marketNameKey = "market"
accountIDKey = "account"
matchIDKey = "match"
ruleToken = "rule"
messageToken = "message"
timeoutToken = "timeout"
)

Expand All @@ -57,6 +58,7 @@ type SvrCore interface {
ResumeMarket(name string, asSoonAs time.Time) (startEpoch int64, startTime time.Time, err error)
Penalize(aid account.AccountID, rule account.Rule, details string) error
Unban(aid account.AccountID) error
ForgiveMatchFail(aid account.AccountID, mid order.MatchID) (forgiven, unbanned bool, err error)
}

// Server is a multi-client https server.
Expand Down Expand Up @@ -137,6 +139,7 @@ func NewServer(cfg *SrvConfig) (*Server, error) {
rm.Get("/", s.apiAccountInfo)
rm.Get("/ban", s.apiBan)
rm.Get("/unban", s.apiUnban)
rm.Get("/forgive_match/{"+matchIDKey+"}", s.apiForgiveMatchFail)
rm.Post("/notify", s.apiNotify)
})
r.Post("/notifyall", s.apiNotifyAll)
Expand Down
4 changes: 4 additions & 0 deletions server/admin/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"decred.org/dcrdex/dex"
"decred.org/dcrdex/dex/encode"
"decred.org/dcrdex/dex/msgjson"
"decred.org/dcrdex/dex/order"
"decred.org/dcrdex/server/account"
"decred.org/dcrdex/server/db"
"decred.org/dcrdex/server/market"
Expand Down Expand Up @@ -166,6 +167,9 @@ func (c *TCore) Penalize(_ account.AccountID, _ account.Rule, _ string) error {
func (c *TCore) Unban(_ account.AccountID) error {
return c.unbanErr
}
func (c *TCore) ForgiveMatchFail(_ account.AccountID, _ order.MatchID) (bool, bool, error) {
return false, false, nil // TODO: tests
}
func (c *TCore) Notify(_ account.AccountID, _ *msgjson.Message) {}
func (c *TCore) NotifyAll(_ *msgjson.Message) {}

Expand Down
8 changes: 8 additions & 0 deletions server/admin/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,11 @@ type UnbanResult struct {
AccountID string `json:"accountid"`
UnbanTime APITime `json:"unbantime"`
}

// ForgiveResult holds the result of a forgive_match.
type ForgiveResult struct {
AccountID string `json:"accountid"`
Forgiven bool `json:"forgiven"`
Unbanned bool `json:"unbanned"`
ForgiveTime APITime `json:"forgivetime"`
}

0 comments on commit 73d04b4

Please sign in to comment.