decred.org/dcrdex@v1.0.5/client/asset/btc/livetest/regnet_test.go (about) 1 //go:build harness 2 3 package livetest 4 5 import ( 6 "context" 7 "encoding/hex" 8 "fmt" 9 "os/exec" 10 "os/user" 11 "path/filepath" 12 "testing" 13 "time" 14 15 "decred.org/dcrdex/client/asset" 16 "decred.org/dcrdex/client/asset/btc" 17 "decred.org/dcrdex/dex" 18 "decred.org/dcrdex/dex/encode" 19 ) 20 21 const ( 22 alphaAddress = "bcrt1qaujcvxuvp9vdcqaa6s3acyh8kxmuyqnyg4jcfl" 23 betaAddress = "bcrt1qwhxklx3vms6xc0lxlunez93m9wn8qzxkkn5dy2" 24 gammaAddress = "bcrt1qll362edf4levwg7yqyt7kawjklvejvj74w87py" 25 walletTypeSPV = "SPV" 26 ) 27 28 var ( 29 tBTC = &dex.Asset{ 30 ID: 0, 31 Symbol: "btc", 32 Version: 0, // match btc.version 33 MaxFeeRate: 10, 34 SwapConf: 1, 35 } 36 37 usr, _ = user.Current() 38 harnessCtlDir = filepath.Join(usr.HomeDir, "dextest", "btc", "harness-ctl") 39 tPW = []byte("abc") 40 ) 41 42 func TestWallet(t *testing.T) { 43 const lotSize = 1e6 44 45 fmt.Println("////////// RPC WALLET W/O SPLIT //////////") 46 Run(t, &Config{ 47 NewWallet: btc.NewWallet, 48 LotSize: lotSize, 49 Asset: tBTC, 50 }) 51 52 fmt.Println("////////// RPC WALLET WITH SPLIT //////////") 53 Run(t, &Config{ 54 NewWallet: btc.NewWallet, 55 LotSize: lotSize, 56 Asset: tBTC, 57 SplitTx: true, 58 }) 59 60 spvDir := t.TempDir() 61 62 createWallet := func(cfg *asset.WalletConfig, name string, logger dex.Logger) error { 63 // var seed [32]byte 64 // copy(seed[:], []byte(name)) 65 seed := encode.RandomBytes(32) 66 67 err := (&btc.Driver{}).Create(&asset.CreateWalletParams{ 68 Type: walletTypeSPV, 69 Seed: seed[:], 70 Pass: tPW, // match walletPassword in livetest.go -> Run 71 DataDir: cfg.DataDir, 72 Net: dex.Simnet, 73 Logger: logger, 74 }) 75 if err != nil { 76 return fmt.Errorf("error creating SPV wallet: %w", err) 77 } 78 79 w, err := btc.NewWallet(cfg, logger, dex.Regtest) 80 if err != nil { 81 t.Fatalf("error creating backend: %v", err) 82 } 83 84 ctx, cancel := context.WithCancel(context.Background()) 85 defer cancel() 86 cm := dex.NewConnectionMaster(w) 87 err = cm.Connect(ctx) 88 if err != nil { 89 t.Fatalf("error connecting backend: %v", err) 90 } 91 defer cm.Disconnect() 92 93 addr, err := w.DepositAddress() 94 if err != nil { 95 return fmt.Errorf("Address error: %w", err) 96 } 97 98 // TODO: Randomize the address scope passed to 99 // btcwallet.Wallet.{NewAddress, NewChangeAddress} between 100 // waddrmgr.KeyScopeBIP0084 and waddrmgr.KeyScopeBIP0044 so that we 101 // know we can handle non-segwit previous outpoints too. 102 if err := loadAddress(addr); err != nil { 103 return fmt.Errorf("loadAddress error: %v", err) 104 } 105 106 time.Sleep(time.Second * 3) 107 108 for { 109 ss, err := w.SyncStatus() 110 if err != nil { 111 return fmt.Errorf("SyncStatus error: %w", err) 112 } 113 if ss.Synced { 114 break 115 } 116 fmt.Printf("%s sync progress %.1f \n", name, ss.BlockProgress()*100) 117 time.Sleep(time.Second) 118 } 119 120 bal, _ := w.Balance() 121 logger.Infof("%s with address %s is synced with balance = %+v \n", name, addr, bal) 122 123 return nil 124 } 125 126 spvConstructor := func(cfg *asset.WalletConfig, logger dex.Logger, network dex.Network) (asset.Wallet, error) { 127 token := hex.EncodeToString(encode.RandomBytes(4)) 128 cfg.Type = walletTypeSPV 129 cfg.DataDir = filepath.Join(spvDir, token) 130 131 name := parseName(cfg.Settings) 132 133 // regtest connects to alpha node by default if "peer" isn't set. 134 if name == "beta" { 135 cfg.Settings["peer"] = "localhost:20576" // beta node 136 } 137 138 err := createWallet(cfg, name, logger) 139 if err != nil { 140 return nil, fmt.Errorf("createWallet error: %v", err) 141 } 142 143 w, err := btc.NewWallet(cfg, logger, network) 144 if err != nil { 145 return nil, err 146 } 147 148 return w, nil 149 } 150 151 fmt.Println("////////// SPV WALLET W/O SPLIT //////////") 152 Run(t, &Config{ 153 NewWallet: spvConstructor, 154 LotSize: lotSize, 155 Asset: tBTC, 156 SPV: true, 157 }) 158 159 fmt.Println("////////// SPV WALLET WITH SPLIT //////////") 160 Run(t, &Config{ 161 NewWallet: spvConstructor, 162 LotSize: lotSize, 163 Asset: tBTC, 164 SPV: true, 165 SplitTx: true, 166 }) 167 } 168 169 func loadAddress(addr string) error { 170 for _, v := range []string{"10", "18", "5", "7", "1", "15", "3", "25"} { 171 if err := runCmd("./alpha", "sendtoaddress", addr, v); err != nil { 172 return err 173 } 174 } 175 return runCmd("./mine-alpha", "1") 176 } 177 178 func runCmdWithOutput(exe string, args ...string) (string, error) { 179 cmd := exec.Command(exe, args...) 180 cmd.Dir = harnessCtlDir 181 b, err := cmd.Output() 182 // if len(op) > 0 { 183 // fmt.Printf("output from command %q: %s \n", cmd, string(op)) 184 // } 185 return string(b), err 186 } 187 188 func runCmd(exe string, args ...string) error { 189 _, err := runCmdWithOutput(exe, args...) 190 return err 191 } 192 193 func parseName(settings map[string]string) string { 194 name := settings["walletname"] 195 if name == "" { 196 name = filepath.Base(settings["datadir"]) 197 } 198 return name 199 }