Skip to content

Commit

Permalink
Joe review updates
Browse files Browse the repository at this point in the history
  • Loading branch information
martonp committed Nov 27, 2023
1 parent 92301e7 commit b96b239
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 33 deletions.
5 changes: 5 additions & 0 deletions client/asset/btc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ func (op *Output) String() string {
return op.Pt.String()
}

// TxID is the ID of the transaction used to create the coin.
func (op *Output) TxID() string {
return op.txHash().String()
}

// txHash returns the pointer of the wire.OutPoint's Hash.
func (op *Output) txHash() *chainhash.Hash {
return &op.Pt.TxHash
Expand Down
4 changes: 4 additions & 0 deletions client/asset/eth/fundingcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ func (c *tokenFundingCoin) ID() dex.Bytes {
return []byte(c.addr.String())
}

func (c *tokenFundingCoin) TxID() string {
return ""
}

// ID creates a byte slice that can be decoded with DecodeCoinID.
func (c *tokenFundingCoin) RecoveryID() dex.Bytes {
b := make([]byte, tokenFundingCoinIDSize)
Expand Down
9 changes: 4 additions & 5 deletions client/asset/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,9 @@ type Wallet interface {
// payment. This method need not be supported by all assets. Those assets
// which do no support DEX registration fees will return an ErrUnsupported.
RegFeeConfirmations(ctx context.Context, coinID dex.Bytes) (confs uint32, err error)
// TransactionConfirmations gets the number of confirmations for the specified
// transaction.
// TransactionConfirmations gets the number of confirmations for the
// specified transaction. If the wallet does not know about the
// transaction, asset.CoinNotFoundError is returned.
TransactionConfirmations(ctx context.Context, txID string) (confs uint32, err error)
// Send sends the exact value to the specified address. This is different
// from Withdraw, which subtracts the tx fees from the amount sent.
Expand Down Expand Up @@ -1220,9 +1221,7 @@ type Coin interface {
String() string
// Value is the available quantity, in atoms/satoshi.
Value() uint64
}

type TxCoin interface {
// TxID is the ID of the transaction that created the coin.
TxID() string
}

Expand Down
7 changes: 1 addition & 6 deletions client/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -5508,12 +5508,7 @@ func (c *Core) Send(pw []byte, assetID uint32, value uint64, address string, sub

c.updateAssetBalance(assetID)

txCoin, is := coin.(asset.TxCoin)
if !is {
return "", nil, fmt.Errorf("Send successful, but returned coin is not a TxCoin")
}

return txCoin.TxID(), coin, nil
return coin.TxID(), coin, nil
}

// TransactionConfirmations returns the number of confirmations of
Expand Down
2 changes: 1 addition & 1 deletion client/mm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type CEXConfig struct {
APISecret string `json:"apiSecret"`
}

// BotCEXCfg is the specifies the CEX that a bot uses and the initial balances
// BotCEXCfg specifies the CEX that a bot uses and the initial balances
// that should be allocated to the bot on that CEX.
type BotCEXCfg struct {
Name string `json:"name"`
Expand Down
27 changes: 17 additions & 10 deletions client/mm/libxc/binance.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,12 +446,12 @@ func (bnc *binance) Trade(ctx context.Context, baseID, quoteID uint32, sell bool

baseCfg, err := bncAssetCfg(baseID)
if err != nil {
return "", fmt.Errorf("error getting asset cfg for %d", baseID)
return "", fmt.Errorf("error getting asset cfg for %d: %w", baseID, err)
}

quoteCfg, err := bncAssetCfg(quoteID)
if err != nil {
return "", fmt.Errorf("error getting asset cfg for %d", quoteID)
return "", fmt.Errorf("error getting asset cfg for %d: %w", quoteID, err)
}

slug := baseCfg.coin + quoteCfg.coin
Expand Down Expand Up @@ -511,6 +511,9 @@ func (bnc *binance) assetPrecision(coin string) (int, error) {
return 0, fmt.Errorf("asset %s not found", coin)
}

// Withdraw withdraws funds from the CEX to a certain address. onComplete
// is called with the actual amount withdrawn (amt - fees) and the
// transaction ID of the withdrawal.
func (bnc *binance) Withdraw(ctx context.Context, assetID uint32, qty uint64, address string, onComplete func(uint64, string)) error {
assetCfg, err := bncAssetCfg(assetID)
if err != nil {
Expand Down Expand Up @@ -559,6 +562,7 @@ func (bnc *binance) Withdraw(ctx context.Context, assetID uint32, qty uint64, ad
for _, s := range withdrawHistoryResponse {
if s.ID == withdrawResp.ID {
status = s
break
}
}
if status == nil {
Expand Down Expand Up @@ -591,6 +595,7 @@ func (bnc *binance) Withdraw(ctx context.Context, assetID uint32, qty uint64, ad
return nil
}

// GetDepositAddress returns a deposit address for an asset.
func (bnc *binance) GetDepositAddress(ctx context.Context, assetID uint32) (string, error) {
assetCfg, err := bncAssetCfg(assetID)
if err != nil {
Expand All @@ -612,6 +617,8 @@ func (bnc *binance) GetDepositAddress(ctx context.Context, assetID uint32) (stri
return resp.Address, nil
}

// ConfirmDeposit is an async function that calls onConfirm when the status of
// a deposit has been confirmed.
func (bnc *binance) ConfirmDeposit(ctx context.Context, txID string, onConfirm func(bool, uint64)) {
const (
pendingStatus = 0
Expand Down Expand Up @@ -714,12 +721,12 @@ func (bnc *binance) SubscribeTradeUpdates() (<-chan *TradeUpdate, func(), int) {
func (bnc *binance) CancelTrade(ctx context.Context, baseID, quoteID uint32, tradeID string) error {
baseCfg, err := bncAssetCfg(baseID)
if err != nil {
return fmt.Errorf("error getting asset cfg for %d", baseID)
return fmt.Errorf("error getting asset cfg for %d: %w", baseID, err)
}

quoteCfg, err := bncAssetCfg(quoteID)
if err != nil {
return fmt.Errorf("error getting asset cfg for %d", quoteID)
return fmt.Errorf("error getting asset cfg for %d: %w", quoteID, err)
}

slug := baseCfg.coin + quoteCfg.coin
Expand Down Expand Up @@ -1331,12 +1338,12 @@ func (bnc *binance) startMarketDataStream(ctx context.Context, baseSymbol, quote
func (bnc *binance) UnsubscribeMarket(baseID, quoteID uint32) (err error) {
baseCfg, err := bncAssetCfg(baseID)
if err != nil {
return fmt.Errorf("error getting asset cfg for %d", baseID)
return fmt.Errorf("error getting asset cfg for %d: %w", baseID, err)
}

quoteCfg, err := bncAssetCfg(quoteID)
if err != nil {
return fmt.Errorf("error getting asset cfg for %d", quoteID)
return fmt.Errorf("error getting asset cfg for %d: %w", quoteID, err)
}

bnc.stopMarketDataStream(strings.ToLower(baseCfg.coin + quoteCfg.coin))
Expand All @@ -1348,12 +1355,12 @@ func (bnc *binance) UnsubscribeMarket(baseID, quoteID uint32) (err error) {
func (bnc *binance) SubscribeMarket(ctx context.Context, baseID, quoteID uint32) error {
baseCfg, err := bncAssetCfg(baseID)
if err != nil {
return fmt.Errorf("error getting asset cfg for %d", baseID)
return fmt.Errorf("error getting asset cfg for %d: %w", baseID, err)
}

quoteCfg, err := bncAssetCfg(quoteID)
if err != nil {
return fmt.Errorf("error getting asset cfg for %d", quoteID)
return fmt.Errorf("error getting asset cfg for %d: %w", quoteID, err)
}

return bnc.startMarketDataStream(ctx, baseCfg.coin, quoteCfg.coin)
Expand All @@ -1368,12 +1375,12 @@ func (bnc *binance) VWAP(baseID, quoteID uint32, sell bool, qty uint64) (avgPric

baseCfg, err := bncAssetCfg(baseID)
if err != nil {
return fail(fmt.Errorf("error getting asset cfg for %d", baseID))
return fail(fmt.Errorf("error getting asset cfg for %d: %w", baseID, err))
}

quoteCfg, err := bncAssetCfg(quoteID)
if err != nil {
return fail(fmt.Errorf("error getting asset cfg for %d", quoteID))
return fail(fmt.Errorf("error getting asset cfg for %d: %w", quoteID, err))
}

slug := strings.ToLower(baseCfg.coin + quoteCfg.coin)
Expand Down
7 changes: 5 additions & 2 deletions client/mm/mm_arb_market_maker.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ type ArbMarketMakingPlacement struct {
// placement. This rate is .007 BTC/DCR. Therefore it will place a sell order
// at .00707 BTC/DCR (.007 BTC/DCR * 1.01).
type ArbMarketMakerConfig struct {
CEXName string `json:"cexName"`
BuyPlacements []*ArbMarketMakingPlacement `json:"buyPlacements"`
SellPlacements []*ArbMarketMakingPlacement `json:"sellPlacements"`
Profit float64 `json:"profit"`
Expand Down Expand Up @@ -570,7 +569,11 @@ func (a *arbMarketMaker) run() {
}
a.book = book

a.updateFeeRates()
err = a.updateFeeRates()
if err != nil {
a.log.Errorf("Failed to get fees: %v", err)
return
}

err = a.cex.SubscribeMarket(a.ctx, a.base, a.quote)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions client/mm/sample-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
"quoteBalanceType": 0,
"baseBalance": 100,
"quoteBalance": 100,
"cexCfg": {
"name": "Binance",
"baseBalanceType": 0,
"quoteBalanceType": 0,
"baseBalance": 100,
"quoteBalance": 100
},
"arbMarketMakerConfig": {
"cexName": "Binance",
"buyPlacements": [
Expand Down
28 changes: 19 additions & 9 deletions client/mm/wrapped_cex.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ type wrappedCEX struct {

var _ cex = (*wrappedCEX)(nil)

// Balance returns the balance of the bot on the CEX.
func (w *wrappedCEX) Balance(assetID uint32) (*libxc.ExchangeBalance, error) {
return &libxc.ExchangeBalance{
Available: w.mm.botCEXBalance(w.botID, assetID),
}, nil
}

// Deposit deposits funds to the CEX. The deposited funds will be removed from
// the bot's wallet balance and allocated to the bot's CEX balance.
func (w *wrappedCEX) Deposit(ctx context.Context, assetID uint32, amount uint64, onConfirm func()) error {
balance := w.mm.botBalance(w.botID, assetID)
if balance < amount {
Expand Down Expand Up @@ -94,6 +97,8 @@ func (w *wrappedCEX) Deposit(ctx context.Context, assetID uint32, amount uint64,
return nil
}

// Withdraw withdraws funds from the CEX. The withdrawn funds will be removed
// from the bot's CEX balance and added to the bot's wallet balance.
func (w *wrappedCEX) Withdraw(ctx context.Context, assetID uint32, amount uint64, onConfirm func()) error {
symbol := dex.BipIDSymbol(assetID)

Expand All @@ -110,26 +115,27 @@ func (w *wrappedCEX) Withdraw(ctx context.Context, assetID uint32, amount uint64
conf := func(withdrawnAmt uint64, txID string) {
go func() {
checkTransaction := func() bool {
_, err := w.mm.core.TransactionConfirmations(assetID, txID)
if err == nil {
// Assign to balance to the bot as long as the wallet
// knows about the transaction.
confs, err := w.mm.core.TransactionConfirmations(assetID, txID)
if err != nil {
if !errors.Is(err, asset.CoinNotFoundError) {
w.log.Errorf("error checking transaction confirmations: %v", err)
}
return false
}
if confs > 0 {
w.mm.modifyBotBalance(w.botID, []*balanceMod{{balanceModIncrease, assetID, balTypeAvailable, withdrawnAmt}})
onConfirm()
return true
}
if !errors.Is(err, asset.CoinNotFoundError) {
w.log.Errorf("error checking transaction confirmations: %v", err)
}
return false
}

if checkTransaction() {
return
}

ticker := time.NewTicker(time.Second * 20)
giveUp := time.NewTimer(time.Minute * 10)
ticker := time.NewTicker(time.Minute * 1)
giveUp := time.NewTimer(2 * time.Hour)
defer ticker.Stop()
defer giveUp.Stop()
for {
Expand Down Expand Up @@ -198,6 +204,8 @@ func (w *wrappedCEX) handleTradeUpdate(update *libxc.TradeUpdate) {
delete(w.trades, update.TradeID)
}

// SubscibeTradeUpdates subscribes to trade updates for the bot's trades on the
// CEX. This should be called before making any trades, and only once.
func (w *wrappedCEX) SubscribeTradeUpdates() (<-chan *libxc.TradeUpdate, func()) {
w.subscriptionIDMtx.Lock()
defer w.subscriptionIDMtx.Unlock()
Expand Down Expand Up @@ -230,6 +238,8 @@ func (w *wrappedCEX) SubscribeTradeUpdates() (<-chan *libxc.TradeUpdate, func())
return forwardUpdates, forwardUnsubscribe
}

// Trade executes a trade on the CEX. The trade will be executed using the
// bot's CEX balance.
func (w *wrappedCEX) Trade(ctx context.Context, baseID, quoteID uint32, sell bool, rate, qty uint64) (string, error) {
var fromAssetID, toAssetID uint32
var fromAssetQty uint64
Expand Down

0 comments on commit b96b239

Please sign in to comment.