Skip to content

Commit

Permalink
pg: fix shallow copy and avoid buffer reuse in (*dbCoins).Scan
Browse files Browse the repository at this point in the history
SelectActiveOrderCoinIDs -> SelectOrderCoinIDs
Restrict SelectOrderCoinIDs to market and limit orders (no cancel).
  • Loading branch information
chappjc committed Dec 11, 2019
1 parent 081f05f commit e94de6c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
8 changes: 6 additions & 2 deletions server/db/driver/pg/internal/orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@ const (
// account ID.
SelectUserOrders = `SELECT * FROM %s WHERE account_id = $1;`

SelectActiveOrderCoinIDs = `SELECT oid, sell, coins
FROM %s -- the active orders table for the market;`
// SelectOrderCoinIDs retrieves the order id, sell flag, and coins for all
// orders in a table with one of the given statuses. Note that this includes
// all order statuses.
SelectOrderCoinIDs = `SELECT oid, sell, coins
FROM %s
WHERE type = ANY($1);`

// UpdateOrderStatus sets the status of an order with the given order ID.
UpdateOrderStatus = `UPDATE %s SET status = $1 WHERE oid = $2;`
Expand Down
20 changes: 16 additions & 4 deletions server/db/driver/pg/orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"decred.org/dcrdex/server/account"
"decred.org/dcrdex/server/db"
"decred.org/dcrdex/server/db/driver/pg/internal"
"github.com/lib/pq"
)

// Wrap the CoinID slice to implement custom Scanner and Valuer.
Expand Down Expand Up @@ -57,7 +58,13 @@ func (coins *dbCoins) Scan(src interface{}) error {
if len(b) < cLen+1 {
return fmt.Errorf("too many bytes indicated")
}
c = append(c, b[1:cLen+1])

// Deep copy the coin ID (a slice) since the backing buffer may be
// reused.
bc := make([]byte, cLen)
copy(bc, b[1:cLen+1])
c = append(c, bc)

b = b[cLen+1:]
}

Expand Down Expand Up @@ -208,10 +215,15 @@ func (a *Archiver) ActiveOrderCoins(base, quote uint32) (baseCoins, quoteCoins m
}

tableName := fullOrderTableName(a.dbName, marketSchema, true) // active (true)
stmt := fmt.Sprintf(internal.SelectActiveOrderCoinIDs, tableName)
stmt := fmt.Sprintf(internal.SelectOrderCoinIDs, tableName)

orderTypes := []int64{
int64(order.MarketOrderType),
int64(order.LimitOrderType),
} // i.e. NOT cancel

var rows *sql.Rows
rows, err = a.db.Query(stmt)
rows, err = a.db.Query(stmt, pq.Int64Array(orderTypes))
switch err {
case sql.ErrNoRows:
err = nil
Expand All @@ -230,7 +242,7 @@ func (a *Archiver) ActiveOrderCoins(base, quote uint32) (baseCoins, quoteCoins m
var sell bool
err = rows.Scan(&oid, &sell, &coins)
if err != nil {
return
return nil, nil, err
}

// Sell orders lock base asset coins.
Expand Down

0 comments on commit e94de6c

Please sign in to comment.