Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
322 changes: 221 additions & 101 deletions client/asset/btc/btc.go

Large diffs are not rendered by default.

251 changes: 167 additions & 84 deletions client/asset/btc/btc_test.go

Large diffs are not rendered by default.

44 changes: 25 additions & 19 deletions client/asset/btc/livetest/livetest.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"decred.org/dcrdex/dex/config"
)

const tPW = "abc"

type WalletConstructor func(cfg *asset.WalletConfig, logger dex.Logger, network dex.Network) (asset.Wallet, error)

// Convert the BTC value to satoshi.
Expand All @@ -38,7 +40,8 @@ func toSatoshi(v float64) uint64 {
}

func tBackend(t *testing.T, ctx context.Context, newWallet WalletConstructor, symbol, conf, name string,
logger dex.Logger, blkFunc func(string, error)) (*btc.ExchangeWallet, *dex.ConnectionMaster) {
logger dex.Logger, blkFunc func(string, error), splitTx bool) (*btc.ExchangeWallet, *dex.ConnectionMaster) {

user, err := user.Current()
if err != nil {
t.Fatalf("error getting current user: %v", err)
Expand All @@ -49,6 +52,9 @@ func tBackend(t *testing.T, ctx context.Context, newWallet WalletConstructor, sy
t.Fatalf("error reading config options: %v", err)
}
settings["walletname"] = name
if splitTx {
settings["txsplit"] = "1"
}
walletCfg := &asset.WalletConfig{
Settings: settings,
TipChange: func(err error) {
Expand Down Expand Up @@ -109,7 +115,7 @@ func randBytes(l int) []byte {
return b
}

func Run(t *testing.T, newWallet WalletConstructor, address string, dexAsset *dex.Asset) {
func Run(t *testing.T, newWallet WalletConstructor, address string, dexAsset *dex.Asset, splitTx bool) {
tLogger := dex.StdOutLogger("TEST", dex.LevelTrace)
tCtx, shutdown := context.WithCancel(context.Background())
defer shutdown()
Expand All @@ -130,9 +136,9 @@ func Run(t *testing.T, newWallet WalletConstructor, address string, dexAsset *de
backends: make(map[string]*btc.ExchangeWallet),
connectionMasters: make(map[string]*dex.ConnectionMaster, 3),
}
rig.backends["alpha"], rig.connectionMasters["alpha"] = tBackend(t, tCtx, newWallet, dexAsset.Symbol, "alpha", "", tLogger, blkFunc)
rig.backends["beta"], rig.connectionMasters["beta"] = tBackend(t, tCtx, newWallet, dexAsset.Symbol, "beta", "", tLogger, blkFunc)
rig.backends["gamma"], rig.connectionMasters["gamma"] = tBackend(t, tCtx, newWallet, dexAsset.Symbol, "alpha", "gamma", tLogger, blkFunc)
rig.backends["alpha"], rig.connectionMasters["alpha"] = tBackend(t, tCtx, newWallet, dexAsset.Symbol, "alpha", "", tLogger, blkFunc, splitTx)
rig.backends["beta"], rig.connectionMasters["beta"] = tBackend(t, tCtx, newWallet, dexAsset.Symbol, "beta", "", tLogger, blkFunc, splitTx)
rig.backends["gamma"], rig.connectionMasters["gamma"] = tBackend(t, tCtx, newWallet, dexAsset.Symbol, "alpha", "gamma", tLogger, blkFunc, splitTx)
defer rig.close()
contractValue := 2 * dexAsset.LotSize

Expand All @@ -154,46 +160,46 @@ func Run(t *testing.T, newWallet WalletConstructor, address string, dexAsset *de
tLogger.Debugf("%s %f available, %f immature, %f locked",
name, float64(bal.Available)/1e8, float64(bal.Immature)/1e8, float64(bal.Locked)/1e8)
}

// Unlock the wallet for use.
err := rig.gamma().Unlock(walletPassword, time.Hour*24)
if err != nil {
t.Fatalf("error unlocking gamma wallet: %v", err)
}

// Gamma should only have 10 BTC utxos, so calling fund for less should only
// return 1 utxo.
utxos, err := rig.gamma().FundOrder(contractValue*3, dexAsset)
utxos, err := rig.gamma().FundOrder(contractValue*3, false, dexAsset)
if err != nil {
t.Fatalf("Funding error: %v", err)
}
utxo := utxos[0]

// UTXOs should be locked
utxos, _ = rig.gamma().FundOrder(contractValue*3, dexAsset)
utxos, _ = rig.gamma().FundOrder(contractValue*3, false, dexAsset)
if inUTXOs(utxo, utxos) {
t.Fatalf("received locked output")
}
// Unlock
rig.gamma().ReturnCoins([]asset.Coin{utxo})
rig.gamma().ReturnCoins(utxos)
// Make sure we get the first utxo back with Fund.
utxos, _ = rig.gamma().FundOrder(contractValue*3, dexAsset)
if !inUTXOs(utxo, utxos) {
utxos, _ = rig.gamma().FundOrder(contractValue*3, false, dexAsset)
if !splitTx && !inUTXOs(utxo, utxos) {
t.Fatalf("unlocked output not returned")
}
rig.gamma().ReturnCoins(utxos)

// Get a separate set of UTXOs for each contract.
utxos1, err := rig.gamma().FundOrder(contractValue, dexAsset)
utxos1, err := rig.gamma().FundOrder(contractValue, false, dexAsset)
if err != nil {
t.Fatalf("error funding first contract: %v", err)
}
// Get a separate set of UTXOs for each contract.
utxos2, err := rig.gamma().FundOrder(contractValue*2, dexAsset)
utxos2, err := rig.gamma().FundOrder(contractValue*2, false, dexAsset)
if err != nil {
t.Fatalf("error funding second contract: %v", err)
}

// Unlock the wallet for use.
err = rig.gamma().Unlock(walletPassword, time.Hour*24)
if err != nil {
t.Fatalf("error unlocking gamma wallet: %v", err)
}

secretKey1 := randBytes(32)
keyHash1 := sha256.Sum256(secretKey1)
secretKey2 := randBytes(32)
Expand Down Expand Up @@ -319,7 +325,7 @@ func Run(t *testing.T, newWallet WalletConstructor, address string, dexAsset *de
lockTime = time.Now().Add(-24 * time.Hour)

// Have gamma send a swap contract to the alpha address.
utxos, _ = rig.gamma().FundOrder(contractValue, dexAsset)
utxos, _ = rig.gamma().FundOrder(contractValue, false, dexAsset)
contract := &asset.Contract{
Address: address,
Value: contractValue,
Expand Down
8 changes: 6 additions & 2 deletions client/asset/btc/livetest/regnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package livetest

import (
"fmt"
"testing"

"decred.org/dcrdex/client/asset/btc"
Expand All @@ -20,13 +21,16 @@ var (
Symbol: "btc",
SwapSize: dexbtc.InitTxSize,
SwapSizeBase: dexbtc.InitTxSizeBase,
MaxFeeRate: 2,
MaxFeeRate: 10,
LotSize: 1e6,
RateStep: 10,
SwapConf: 1,
}
)

func TestWallet(t *testing.T) {
Run(t, btc.NewWallet, alphaAddress, tBTC)
fmt.Println("////////// WITHOUT SPLIT FUNDING TRANSACTIONS //////////")
Run(t, btc.NewWallet, alphaAddress, tBTC, false)
fmt.Println("////////// WITH SPLIT FUNDING TRANSACTIONS //////////")
Run(t, btc.NewWallet, alphaAddress, tBTC, true)
}
4 changes: 2 additions & 2 deletions client/asset/btc/walletclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ func (wc *walletClient) LockUnspent(unlock bool, ops []*output) error {
var rpcops []*RPCOutpoint // To clear all, this must be nil, not empty slice.
for _, op := range ops {
rpcops = append(rpcops, &RPCOutpoint{
TxID: op.txHash.String(),
Vout: op.vout,
TxID: op.txHash().String(),
Vout: op.vout(),
})
}
var success bool
Expand Down
Loading