manager_test.go raw

   1  // Copyright (c) 2014-2016 The btcsuite developers
   2  package waddrmgr_test
   3  
   4  import (
   5  	"encoding/hex"
   6  	"fmt"
   7  	"github.com/p9c/p9/pkg/btcaddr"
   8  	"os"
   9  	"reflect"
  10  	"testing"
  11  	"time"
  12  	
  13  	"github.com/davecgh/go-spew/spew"
  14  	
  15  	"github.com/p9c/p9/pkg/chaincfg"
  16  	"github.com/p9c/p9/pkg/chainhash"
  17  	"github.com/p9c/p9/pkg/snacl"
  18  	"github.com/p9c/p9/pkg/util"
  19  	"github.com/p9c/p9/pkg/waddrmgr"
  20  	"github.com/p9c/p9/pkg/walletdb"
  21  )
  22  
  23  // // newHash converts the passed big-endian hex string into a chainhash.Hash.
  24  // // It only differs from the one available in wire in that it panics on an
  25  // // error since it will only (and must only) be called with hard-coded, and
  26  // // therefore known good, hashes.
  27  // func newHash(// 	hexStr string) *chainhash.Hash {
  28  // 	hash, e := chainhash.NewHashFromStr(hexStr)
  29  // 	if e != nil  {
  30  // 		panic(e)
  31  // 	}
  32  // 	return hash
  33  // }
  34  
  35  // failingSecretKeyGen is a waddrmgr.SecretKeyGenerator that always returns
  36  // snacl.ErrDecryptFailed.
  37  func failingSecretKeyGen(
  38  	passphrase *[]byte,
  39  	config *waddrmgr.ScryptOptions,
  40  ) (*snacl.SecretKey, error) {
  41  	return nil, snacl.ErrDecryptFailed
  42  }
  43  
  44  // testContext is used to store context information about a running test which
  45  // is passed into helper functions. The useSpends field indicates whether or not
  46  // the spend data should be empty or figure it out based on the specific test
  47  // blocks provided.
  48  //
  49  // This is needed because the first loop where the blocks are inserted, the
  50  // tests are running against the latest block and therefore none of the outputs
  51  // can be spent yet.
  52  //
  53  // However, on subsequent runs, all blocks have been inserted and therefore some
  54  // of the transaction outputs are spent.
  55  type testContext struct {
  56  	t            *testing.T
  57  	db           walletdb.DB
  58  	rootManager  *waddrmgr.Manager
  59  	manager      *waddrmgr.ScopedKeyManager
  60  	account      uint32
  61  	create       bool
  62  	unlocked     bool
  63  	watchingOnly bool
  64  }
  65  
  66  // addrType is the type of address being tested
  67  type addrType byte
  68  
  69  const (
  70  	addrPubKeyHash addrType = iota
  71  	addrScriptHash
  72  )
  73  
  74  // expectedAddr is used to house the expected return values from a managed
  75  // address. Not all fields for used for all managed address types.
  76  type expectedAddr struct {
  77  	address     string
  78  	addressHash []byte
  79  	internal    bool
  80  	compressed  bool
  81  	// used           bool
  82  	imported       bool
  83  	pubKey         []byte
  84  	privKey        []byte
  85  	privKeyWIF     string
  86  	script         []byte
  87  	derivationInfo waddrmgr.DerivationPath
  88  }
  89  
  90  // testNamePrefix is a helper to return a prefix to show for test errors based
  91  // on the state of the test context.
  92  func testNamePrefix(tc *testContext) string {
  93  	prefix := "Open "
  94  	if tc.create {
  95  		prefix = "Create "
  96  	}
  97  	return prefix + fmt.Sprintf("account #%d", tc.account)
  98  }
  99  
 100  // testManagedPubKeyAddress ensures the data returned by all exported functions
 101  // provided by the passed managed public key address matches the corresponding
 102  // fields in the provided expected address.
 103  //
 104  // When the test context indicates the manager is unlocked, the private data
 105  // will also be tested, otherwise, the functions which deal with private data
 106  // are checked to ensure they return the correct error.
 107  func testManagedPubKeyAddress(
 108  	tc *testContext, prefix string,
 109  	gotAddr waddrmgr.ManagedPubKeyAddress, wantAddr *expectedAddr,
 110  ) bool {
 111  	// Ensure pubkey is the expected value for the managed address.
 112  	var gpubBytes []byte
 113  	if gotAddr.Compressed() {
 114  		gpubBytes = gotAddr.PubKey().SerializeCompressed()
 115  	} else {
 116  		gpubBytes = gotAddr.PubKey().SerializeUncompressed()
 117  	}
 118  	if !reflect.DeepEqual(gpubBytes, wantAddr.pubKey) {
 119  		tc.t.Errorf(
 120  			"%s PubKey: unexpected public key - got %x, want "+
 121  				"%x", prefix, gpubBytes, wantAddr.pubKey,
 122  		)
 123  		return false
 124  	}
 125  	// Ensure exported pubkey string is the expected value for the managed address.
 126  	gpubHex := gotAddr.ExportPubKey()
 127  	wantPubHex := hex.EncodeToString(wantAddr.pubKey)
 128  	if gpubHex != wantPubHex {
 129  		tc.t.Errorf(
 130  			"%s ExportPubKey: unexpected public key - got %s, "+
 131  				"want %s", prefix, gpubHex, wantPubHex,
 132  		)
 133  		return false
 134  	}
 135  	// Ensure that the derivation path has been properly re-set after the address
 136  	// was read from disk.
 137  	_, gotAddrPath, ok := gotAddr.DerivationInfo()
 138  	if !ok && !gotAddr.Imported() {
 139  		tc.t.Errorf(
 140  			"%s PubKey: non-imported address has empty "+
 141  				"derivation info", prefix,
 142  		)
 143  		return false
 144  	}
 145  	expectedDerivationInfo := wantAddr.derivationInfo
 146  	if gotAddrPath != expectedDerivationInfo {
 147  		tc.t.Errorf(
 148  			"%s PubKey: wrong derivation info: expected %v, "+
 149  				"got %v", prefix, spew.Sdump(gotAddrPath),
 150  			spew.Sdump(expectedDerivationInfo),
 151  		)
 152  		return false
 153  	}
 154  	// Ensure private key is the expected value for the managed address. Since this
 155  	// is only available when the manager is unlocked, also check for the expected
 156  	// error when the manager is locked.
 157  	gotPrivKey, e := gotAddr.PrivKey()
 158  	switch {
 159  	case tc.watchingOnly:
 160  		// Confirm expected watching-only error.
 161  		testName := fmt.Sprintf("%s PrivKey", prefix)
 162  		if !checkManagerError(tc.t, testName, e, waddrmgr.ErrWatchingOnly) {
 163  			return false
 164  		}
 165  	case tc.unlocked:
 166  		if e != nil {
 167  			tc.t.Errorf(
 168  				"%s PrivKey: unexpected error - got %v",
 169  				prefix, e,
 170  			)
 171  			return false
 172  		}
 173  		gpriv := gotPrivKey.Serialize()
 174  		if !reflect.DeepEqual(gpriv, wantAddr.privKey) {
 175  			tc.t.Errorf(
 176  				"%s PrivKey: unexpected private key - "+
 177  					"got %x, want %x", prefix, gpriv, wantAddr.privKey,
 178  			)
 179  			return false
 180  		}
 181  	default:
 182  		// Confirm expected locked error.
 183  		testName := fmt.Sprintf("%s PrivKey", prefix)
 184  		if !checkManagerError(tc.t, testName, e, waddrmgr.ErrLocked) {
 185  			return false
 186  		}
 187  	}
 188  	// Ensure exported private key in Wallet Import Format (WIF) is the expected
 189  	// value for the managed address. Since this is only available when the manager
 190  	// is unlocked, also check for the expected error when the manager is locked.
 191  	gotWIF, e := gotAddr.ExportPrivKey()
 192  	switch {
 193  	case tc.watchingOnly:
 194  		// Confirm expected watching-only error.
 195  		testName := fmt.Sprintf("%s ExportPrivKey", prefix)
 196  		if !checkManagerError(tc.t, testName, e, waddrmgr.ErrWatchingOnly) {
 197  			return false
 198  		}
 199  	case tc.unlocked:
 200  		if e != nil {
 201  			tc.t.Errorf(
 202  				"%s ExportPrivKey: unexpected error - "+
 203  					"got %v", prefix, e,
 204  			)
 205  			return false
 206  		}
 207  		if gotWIF.String() != wantAddr.privKeyWIF {
 208  			tc.t.Errorf(
 209  				"%s ExportPrivKey: unexpected WIF - got "+
 210  					"%v, want %v", prefix, gotWIF.String(),
 211  				wantAddr.privKeyWIF,
 212  			)
 213  			return false
 214  		}
 215  	default:
 216  		// Confirm expected locked error.
 217  		testName := fmt.Sprintf("%s ExportPrivKey", prefix)
 218  		if !checkManagerError(tc.t, testName, e, waddrmgr.ErrLocked) {
 219  			return false
 220  		}
 221  	}
 222  	// Imported addresses should return a nil derivation info.
 223  	if _, _, ok := gotAddr.DerivationInfo(); gotAddr.Imported() && ok {
 224  		tc.t.Errorf("%s Imported: expected nil derivation info", prefix)
 225  		return false
 226  	}
 227  	return true
 228  }
 229  
 230  // testManagedScriptAddress ensures the data returned by all exported functions
 231  // provided by the passed managed script address matches the corresponding
 232  // fields in the provided expected address.
 233  //
 234  // When the test context indicates the manager is unlocked, the private data
 235  // will also be tested, otherwise, the functions which deal with private data
 236  // are checked to ensure they return the correct error.
 237  func testManagedScriptAddress(
 238  	tc *testContext,
 239  	prefix string,
 240  	gotAddr waddrmgr.ManagedScriptAddress,
 241  	wantAddr *expectedAddr,
 242  ) bool {
 243  	// Ensure script is the expected value for the managed address. Since this is
 244  	// only available when the manager is unlocked, also check for the expected
 245  	// error when the manager is locked.
 246  	gotScript, e := gotAddr.Script()
 247  	switch {
 248  	case tc.watchingOnly:
 249  		// Confirm expected watching-only error.
 250  		testName := fmt.Sprintf("%s Script", prefix)
 251  		if !checkManagerError(tc.t, testName, e, waddrmgr.ErrWatchingOnly) {
 252  			return false
 253  		}
 254  	case tc.unlocked:
 255  		if e != nil {
 256  			tc.t.Errorf(
 257  				"%s Script: unexpected error - got %v",
 258  				prefix, e,
 259  			)
 260  			return false
 261  		}
 262  		if !reflect.DeepEqual(gotScript, wantAddr.script) {
 263  			tc.t.Errorf(
 264  				"%s Script: unexpected script - got %x, "+
 265  					"want %x", prefix, gotScript, wantAddr.script,
 266  			)
 267  			return false
 268  		}
 269  	default:
 270  		// Confirm expected locked error.
 271  		testName := fmt.Sprintf("%s Script", prefix)
 272  		if !checkManagerError(tc.t, testName, e, waddrmgr.ErrLocked) {
 273  			return false
 274  		}
 275  	}
 276  	return true
 277  }
 278  
 279  // testAddress ensures the data returned by all exported functions provided by
 280  // the passed managed address matches the corresponding fields in the provided
 281  // expected address. It also type asserts the managed address to determine its
 282  // specific type and calls the corresponding testing functions accordingly.
 283  //
 284  // When the test context indicates the manager is unlocked, the private data
 285  // will also be tested, otherwise, the functions which deal with private data
 286  // are checked to ensure they return the correct error.
 287  func testAddress(tc *testContext, prefix string, gotAddr waddrmgr.ManagedAddress, wantAddr *expectedAddr) bool {
 288  	if gotAddr.Account() != tc.account {
 289  		tc.t.Errorf(
 290  			"ManagedAddress.Account: unexpected account - got "+
 291  				"%d, want %d", gotAddr.Account(), tc.account,
 292  		)
 293  		return false
 294  	}
 295  	if gotAddr.Address().EncodeAddress() != wantAddr.address {
 296  		tc.t.Errorf(
 297  			"%s EncodeAddress: unexpected address - got %s, "+
 298  				"want %s", prefix, gotAddr.Address().EncodeAddress(),
 299  			wantAddr.address,
 300  		)
 301  		return false
 302  	}
 303  	if !reflect.DeepEqual(gotAddr.AddrHash(), wantAddr.addressHash) {
 304  		tc.t.Errorf(
 305  			"%s AddrHash: unexpected address hash - got %x, "+
 306  				"want %x", prefix, gotAddr.AddrHash(),
 307  			wantAddr.addressHash,
 308  		)
 309  		return false
 310  	}
 311  	if gotAddr.Internal() != wantAddr.internal {
 312  		tc.t.Errorf(
 313  			"%s Internal: unexpected internal flag - got %v, "+
 314  				"want %v", prefix, gotAddr.Internal(), wantAddr.internal,
 315  		)
 316  		return false
 317  	}
 318  	if gotAddr.Compressed() != wantAddr.compressed {
 319  		tc.t.Errorf(
 320  			"%s Compressed: unexpected compressed flag - got "+
 321  				"%v, want %v", prefix, gotAddr.Compressed(),
 322  			wantAddr.compressed,
 323  		)
 324  		return false
 325  	}
 326  	if gotAddr.Imported() != wantAddr.imported {
 327  		tc.t.Errorf(
 328  			"%s Imported: unexpected imported flag - got %v, "+
 329  				"want %v", prefix, gotAddr.Imported(), wantAddr.imported,
 330  		)
 331  		return false
 332  	}
 333  	switch addr := gotAddr.(type) {
 334  	case waddrmgr.ManagedPubKeyAddress:
 335  		if !testManagedPubKeyAddress(tc, prefix, addr, wantAddr) {
 336  			return false
 337  		}
 338  	case waddrmgr.ManagedScriptAddress:
 339  		if !testManagedScriptAddress(tc, prefix, addr, wantAddr) {
 340  			return false
 341  		}
 342  	}
 343  	return true
 344  }
 345  
 346  // testExternalAddresses tests several facets of external addresses such as
 347  // generating multiple addresses via NextExternalAddresses, ensuring they can be
 348  // retrieved by Address, and that they work properly when the manager is locked
 349  // and unlocked.
 350  func testExternalAddresses(tc *testContext) bool {
 351  	prefix := testNamePrefix(tc) + " testExternalAddresses"
 352  	var addrs []waddrmgr.ManagedAddress
 353  	if tc.create {
 354  		prefix = prefix + " NextExternalAddresses"
 355  		e := walletdb.Update(
 356  			tc.db, func(tx walletdb.ReadWriteTx) (e error) {
 357  				ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
 358  				addrs, e = tc.manager.NextExternalAddresses(ns, tc.account, 5)
 359  				return e
 360  			},
 361  		)
 362  		if e != nil {
 363  			tc.t.Errorf("%s: unexpected error: %v", prefix, e)
 364  			return false
 365  		}
 366  		if len(addrs) != len(expectedExternalAddrs) {
 367  			tc.t.Errorf(
 368  				"%s: unexpected number of addresses - got "+
 369  					"%d, want %d", prefix, len(addrs),
 370  				len(expectedExternalAddrs),
 371  			)
 372  			return false
 373  		}
 374  	}
 375  	// Setup a closure to test the results since the same tests need to be repeated
 376  	// with the manager locked and unlocked.
 377  	testResults := func() bool {
 378  		// Ensure the returned addresses are the expected ones. When not in the create
 379  		// phase, there will be no addresses in the addrs slice, so this really only
 380  		// runs during the first phase of the tests.
 381  		for i := 0; i < len(addrs); i++ {
 382  			prefix = fmt.Sprintf("%s ExternalAddress #%d", prefix, i)
 383  			if !testAddress(tc, prefix, addrs[i], &expectedExternalAddrs[i]) {
 384  				return false
 385  			}
 386  		}
 387  		// Ensure the last external address is the expected one.
 388  		leaPrefix := prefix + " LastExternalAddress"
 389  		var lastAddr waddrmgr.ManagedAddress
 390  		e := walletdb.View(
 391  			tc.db, func(tx walletdb.ReadTx) (e error) {
 392  				ns := tx.ReadBucket(waddrmgrNamespaceKey)
 393  				lastAddr, e = tc.manager.LastExternalAddress(ns, tc.account)
 394  				return e
 395  			},
 396  		)
 397  		if e != nil {
 398  			tc.t.Errorf("%s: unexpected error: %v", leaPrefix, e)
 399  			return false
 400  		}
 401  		if !testAddress(tc, leaPrefix, lastAddr, &expectedExternalAddrs[len(expectedExternalAddrs)-1]) {
 402  			return false
 403  		}
 404  		// Now, use the Address API to retrieve each of the expected new addresses and
 405  		// ensure they're accurate.
 406  		chainParams := tc.manager.ChainParams()
 407  		for i := 0; i < len(expectedExternalAddrs); i++ {
 408  			pkHash := expectedExternalAddrs[i].addressHash
 409  			utilAddr, e := btcaddr.NewPubKeyHash(
 410  				pkHash, chainParams,
 411  			)
 412  			if e != nil {
 413  				tc.t.Errorf(
 414  					"%s NewPubKeyHash #%d: "+
 415  						"unexpected error: %v", prefix, i, e,
 416  				)
 417  				return false
 418  			}
 419  			prefix = fmt.Sprintf("%s Address #%d", prefix, i)
 420  			var addr waddrmgr.ManagedAddress
 421  			e = walletdb.View(
 422  				tc.db, func(tx walletdb.ReadTx) (e error) {
 423  					ns := tx.ReadBucket(waddrmgrNamespaceKey)
 424  					addr, e = tc.manager.Address(ns, utilAddr)
 425  					return e
 426  				},
 427  			)
 428  			if e != nil {
 429  				tc.t.Errorf(
 430  					"%s: unexpected error: %v", prefix,
 431  					e,
 432  				)
 433  				return false
 434  			}
 435  			if !testAddress(tc, prefix, addr, &expectedExternalAddrs[i]) {
 436  				return false
 437  			}
 438  		}
 439  		return true
 440  	}
 441  	// Since the manager is locked at this point, the public address information is
 442  	// tested and the private functions are checked to ensure they return the
 443  	// expected error.
 444  	if !testResults() {
 445  		return false
 446  	}
 447  	// Everything after this point involves retesting with an unlocked address
 448  	// manager which is not possible for watching-only mode, so just exit now in
 449  	// that case.
 450  	if tc.watchingOnly {
 451  		return true
 452  	}
 453  	// Unlock the manager and retest all of the addresses to ensure the private
 454  	// information is valid as well.
 455  	e := walletdb.View(
 456  		tc.db, func(tx walletdb.ReadTx) (e error) {
 457  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
 458  			return tc.rootManager.Unlock(ns, privPassphrase)
 459  		},
 460  	)
 461  	if e != nil {
 462  		tc.t.Errorf("Unlock: unexpected error: %v", e)
 463  		return false
 464  	}
 465  	tc.unlocked = true
 466  	if !testResults() {
 467  		return false
 468  	}
 469  	// Relock the manager for future tests.
 470  	if e := tc.rootManager.Lock(); E.Chk(e) {
 471  		tc.t.Errorf("Lock: unexpected error: %v", e)
 472  		return false
 473  	}
 474  	tc.unlocked = false
 475  	return true
 476  }
 477  
 478  // testInternalAddresses tests several facets of internal addresses such as
 479  // generating multiple addresses via NextInternalAddresses, ensuring they can be
 480  // retrieved by Address, and that they work properly when the manager is locked
 481  // and unlocked.
 482  func testInternalAddresses(tc *testContext) bool {
 483  	// When the address manager is not in watching-only mode, unlocked it first to
 484  	// ensure that address generation works correctly when the address manager is
 485  	// unlocked and then locked later. These tests reverse the order done in the
 486  	// external tests which starts with a locked manager and unlock it afterwards.
 487  	if !tc.watchingOnly {
 488  		// Unlock the manager and retest all of the addresses to ensure the private
 489  		// information is valid as well.
 490  		e := walletdb.View(
 491  			tc.db, func(tx walletdb.ReadTx) (e error) {
 492  				ns := tx.ReadBucket(waddrmgrNamespaceKey)
 493  				return tc.rootManager.Unlock(ns, privPassphrase)
 494  			},
 495  		)
 496  		if e != nil {
 497  			tc.t.Errorf("Unlock: unexpected error: %v", e)
 498  			return false
 499  		}
 500  		tc.unlocked = true
 501  	}
 502  	prefix := testNamePrefix(tc) + " testInternalAddresses"
 503  	var addrs []waddrmgr.ManagedAddress
 504  	if tc.create {
 505  		prefix = prefix + " NextInternalAddress"
 506  		e := walletdb.Update(
 507  			tc.db, func(tx walletdb.ReadWriteTx) (e error) {
 508  				ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
 509  				addrs, e = tc.manager.NextInternalAddresses(ns, tc.account, 5)
 510  				return e
 511  			},
 512  		)
 513  		if e != nil {
 514  			tc.t.Errorf("%s: unexpected error: %v", prefix, e)
 515  			return false
 516  		}
 517  		if len(addrs) != len(expectedInternalAddrs) {
 518  			tc.t.Errorf(
 519  				"%s: unexpected number of addresses - got "+
 520  					"%d, want %d", prefix, len(addrs),
 521  				len(expectedInternalAddrs),
 522  			)
 523  			return false
 524  		}
 525  	}
 526  	// Setup a closure to test the results since the same tests need to be repeated
 527  	// with the manager locked and unlocked.
 528  	testResults := func() bool {
 529  		// Ensure the returned addresses are the expected ones. When not in the create
 530  		// phase, there will be no addresses in the addrs slice, so this really only
 531  		// runs during the first phase of the tests.
 532  		for i := 0; i < len(addrs); i++ {
 533  			prefix = fmt.Sprintf("%s InternalAddress #%d", prefix, i)
 534  			if !testAddress(tc, prefix, addrs[i], &expectedInternalAddrs[i]) {
 535  				return false
 536  			}
 537  		}
 538  		// Ensure the last internal address is the expected one.
 539  		liaPrefix := prefix + " LastInternalAddress"
 540  		var lastAddr waddrmgr.ManagedAddress
 541  		e := walletdb.View(
 542  			tc.db, func(tx walletdb.ReadTx) (e error) {
 543  				ns := tx.ReadBucket(waddrmgrNamespaceKey)
 544  				lastAddr, e = tc.manager.LastInternalAddress(ns, tc.account)
 545  				return e
 546  			},
 547  		)
 548  		if e != nil {
 549  			tc.t.Errorf("%s: unexpected error: %v", liaPrefix, e)
 550  			return false
 551  		}
 552  		if !testAddress(tc, liaPrefix, lastAddr, &expectedInternalAddrs[len(expectedInternalAddrs)-1]) {
 553  			return false
 554  		}
 555  		// Now, use the Address API to retrieve each of the expected new addresses and
 556  		// ensure they're accurate.
 557  		chainParams := tc.manager.ChainParams()
 558  		for i := 0; i < len(expectedInternalAddrs); i++ {
 559  			pkHash := expectedInternalAddrs[i].addressHash
 560  			utilAddr, e := btcaddr.NewPubKeyHash(
 561  				pkHash, chainParams,
 562  			)
 563  			if e != nil {
 564  				tc.t.Errorf(
 565  					"%s NewPubKeyHash #%d: "+
 566  						"unexpected error: %v", prefix, i, e,
 567  				)
 568  				return false
 569  			}
 570  			prefix = fmt.Sprintf("%s Address #%d", prefix, i)
 571  			var addr waddrmgr.ManagedAddress
 572  			e = walletdb.View(
 573  				tc.db, func(tx walletdb.ReadTx) (e error) {
 574  					ns := tx.ReadBucket(waddrmgrNamespaceKey)
 575  					addr, e = tc.manager.Address(ns, utilAddr)
 576  					return e
 577  				},
 578  			)
 579  			if e != nil {
 580  				tc.t.Errorf(
 581  					"%s: unexpected error: %v", prefix,
 582  					e,
 583  				)
 584  				return false
 585  			}
 586  			if !testAddress(tc, prefix, addr, &expectedInternalAddrs[i]) {
 587  				return false
 588  			}
 589  		}
 590  		return true
 591  	}
 592  	// The address manager could either be locked or unlocked here depending on
 593  	// whether or not it's a watching-only manager. When it's unlocked, this will
 594  	// test both the public and private address data are accurate. When it's locked,
 595  	// it must be watching-only, so only the public address information is tested
 596  	// and the private functions are checked to ensure they return the expected
 597  	// ErrWatchingOnly error.
 598  	if !testResults() {
 599  		return false
 600  	}
 601  	// Everything after this point involves locking the address manager and
 602  	// retesting the addresses with a locked manager. However, for watching-only
 603  	// mode, this has already happened, so just exit now in that case.
 604  	if tc.watchingOnly {
 605  		return true
 606  	}
 607  	// Lock the manager and retest all of the addresses to ensure the public
 608  	// information remains valid and the private functions return the expected
 609  	// error.
 610  	if e := tc.rootManager.Lock(); E.Chk(e) {
 611  		tc.t.Errorf("Lock: unexpected error: %v", e)
 612  		return false
 613  	}
 614  	tc.unlocked = false
 615  	if !testResults() {
 616  		return false
 617  	}
 618  	return true
 619  }
 620  
 621  // testLocking tests the basic locking semantics of the address manager work as
 622  // expected. Other tests ensure addresses behave as expected under locked and
 623  // unlocked conditions.
 624  func testLocking(tc *testContext) bool {
 625  	if tc.unlocked {
 626  		tc.t.Error("testLocking called with an unlocked manager")
 627  		return false
 628  	}
 629  	if !tc.rootManager.IsLocked() {
 630  		tc.t.Error("IsLocked: returned false on locked manager")
 631  		return false
 632  	}
 633  	// Locking an already lock manager should return an error. The error should be
 634  	// ErrLocked or ErrWatchingOnly depending on the type of the address manager.
 635  	e := tc.rootManager.Lock()
 636  	wantErrCode := waddrmgr.ErrLocked
 637  	if tc.watchingOnly {
 638  		wantErrCode = waddrmgr.ErrWatchingOnly
 639  	}
 640  	if !checkManagerError(tc.t, "Lock", e, wantErrCode) {
 641  		return false
 642  	}
 643  	// Ensure unlocking with the correct passphrase doesn't return any unexpected
 644  	// errors and the manager properly reports it is unlocked. Since watching-only
 645  	// address managers can't be unlocked, also ensure the correct error for that
 646  	// case.
 647  	e = walletdb.View(
 648  		tc.db, func(tx walletdb.ReadTx) (e error) {
 649  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
 650  			return tc.rootManager.Unlock(ns, privPassphrase)
 651  		},
 652  	)
 653  	if tc.watchingOnly {
 654  		if !checkManagerError(tc.t, "Unlock", e, waddrmgr.ErrWatchingOnly) {
 655  			return false
 656  		}
 657  	} else if e != nil {
 658  		tc.t.Errorf("Unlock: unexpected error: %v", e)
 659  		return false
 660  	}
 661  	if !tc.watchingOnly && tc.rootManager.IsLocked() {
 662  		tc.t.Error("IsLocked: returned true on unlocked manager")
 663  		return false
 664  	}
 665  	// Unlocking the manager again is allowed. Since watching-only address managers
 666  	// can't be unlocked, also ensure the correct error for that case.
 667  	e = walletdb.View(
 668  		tc.db, func(tx walletdb.ReadTx) (e error) {
 669  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
 670  			return tc.rootManager.Unlock(ns, privPassphrase)
 671  		},
 672  	)
 673  	if tc.watchingOnly {
 674  		if !checkManagerError(tc.t, "Unlock2", e, waddrmgr.ErrWatchingOnly) {
 675  			return false
 676  		}
 677  	} else if e != nil {
 678  		tc.t.Errorf("Unlock: unexpected error: %v", e)
 679  		return false
 680  	}
 681  	if !tc.watchingOnly && tc.rootManager.IsLocked() {
 682  		tc.t.Error("IsLocked: returned true on unlocked manager")
 683  		return false
 684  	}
 685  	// Unlocking the manager with an invalid passphrase must result in an error and
 686  	// a locked manager.
 687  	e = walletdb.View(
 688  		tc.db, func(tx walletdb.ReadTx) (e error) {
 689  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
 690  			return tc.rootManager.Unlock(ns, []byte("invalidpassphrase"))
 691  		},
 692  	)
 693  	wantErrCode = waddrmgr.ErrWrongPassphrase
 694  	if tc.watchingOnly {
 695  		wantErrCode = waddrmgr.ErrWatchingOnly
 696  	}
 697  	if !checkManagerError(tc.t, "Unlock", e, wantErrCode) {
 698  		return false
 699  	}
 700  	if !tc.rootManager.IsLocked() {
 701  		tc.t.Error(
 702  			"IsLocked: manager is unlocked after failed unlock " +
 703  				"attempt",
 704  		)
 705  		return false
 706  	}
 707  	return true
 708  }
 709  
 710  // testImportPrivateKey tests that importing private keys works properly. It
 711  // ensures they can be retrieved by Address after they have been imported and
 712  // the addresses give the expected values when the manager is locked and
 713  // unlocked.
 714  //
 715  // This function expects the manager is already locked when called and returns
 716  // with the manager locked.
 717  func testImportPrivateKey(tc *testContext) bool {
 718  	tests := []struct {
 719  		name       string
 720  		in         string
 721  		blockstamp waddrmgr.BlockStamp
 722  		expected   expectedAddr
 723  	}{
 724  		{
 725  			name: "wif for uncompressed pubkey address",
 726  			in:   "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ",
 727  			expected: expectedAddr{
 728  				address:     "1GAehh7TsJAHuUAeKZcXf5CnwuGuGgyX2S",
 729  				addressHash: hexToBytes("a65d1a239d4ec666643d350c7bb8fc44d2881128"),
 730  				internal:    false,
 731  				imported:    true,
 732  				compressed:  false,
 733  				pubKey: hexToBytes(
 734  					"04d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3" +
 735  						"d66a2c5f10780d95b7df42645cd85228a6fb29940e858e7e558" +
 736  						"42ae2bd115d1ed7cc0e82d934e929c97648cb0a",
 737  				),
 738  				privKey: hexToBytes("0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d"),
 739  				// privKeyWIF is set to the in field during tests
 740  			},
 741  		},
 742  		{
 743  			name: "wif for compressed pubkey address",
 744  			in:   "KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617",
 745  			expected: expectedAddr{
 746  				address:     "1LoVGDgRs9hTfTNJNuXKSpywcbdvwRXpmK",
 747  				addressHash: hexToBytes("d9351dcbad5b8f3b8bfa2f2cdc85c28118ca9326"),
 748  				internal:    false,
 749  				imported:    true,
 750  				compressed:  true,
 751  				pubKey:      hexToBytes("02d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c"),
 752  				privKey:     hexToBytes("0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d"),
 753  				// privKeyWIF is set to the in field during tests
 754  			},
 755  		},
 756  	}
 757  	// The manager must be unlocked to import a private key, however a watching-only
 758  	// manager can't be unlocked.
 759  	if !tc.watchingOnly {
 760  		e := walletdb.View(
 761  			tc.db, func(tx walletdb.ReadTx) (e error) {
 762  				ns := tx.ReadBucket(waddrmgrNamespaceKey)
 763  				return tc.rootManager.Unlock(ns, privPassphrase)
 764  			},
 765  		)
 766  		if e != nil {
 767  			tc.t.Errorf("Unlock: unexpected error: %v", e)
 768  			return false
 769  		}
 770  		tc.unlocked = true
 771  	}
 772  	// Only import the private keys when in the create phase of testing.
 773  	tc.account = waddrmgr.ImportedAddrAccount
 774  	prefix := testNamePrefix(tc) + " testImportPrivateKey"
 775  	if tc.create {
 776  		for i, test := range tests {
 777  			test.expected.privKeyWIF = test.in
 778  			wif, e := util.DecodeWIF(test.in)
 779  			if e != nil {
 780  				tc.t.Errorf(
 781  					"%s DecodeWIF #%d (%s): unexpected "+
 782  						"error: %v", prefix, i, test.name, e,
 783  				)
 784  				continue
 785  			}
 786  			var addr waddrmgr.ManagedPubKeyAddress
 787  			e = walletdb.Update(
 788  				tc.db, func(tx walletdb.ReadWriteTx) (e error) {
 789  					ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
 790  					addr, e = tc.manager.ImportPrivateKey(ns, wif, &test.blockstamp)
 791  					return e
 792  				},
 793  			)
 794  			if e != nil {
 795  				tc.t.Errorf(
 796  					"%s ImportPrivateKey #%d (%s): "+
 797  						"unexpected error: %v", prefix, i,
 798  					test.name, e,
 799  				)
 800  				continue
 801  			}
 802  			if !testAddress(
 803  				tc, prefix+" ImportPrivateKey", addr,
 804  				&test.expected,
 805  			) {
 806  				continue
 807  			}
 808  		}
 809  	}
 810  	// Setup a closure to test the results since the same tests need to be repeated
 811  	// with the manager unlocked and locked.
 812  	chainParams := tc.manager.ChainParams()
 813  	testResults := func() bool {
 814  		failed := false
 815  		for i, test := range tests {
 816  			test.expected.privKeyWIF = test.in
 817  			// Use the Address API to retrieve each of the expected new addresses and ensure
 818  			// they're accurate.
 819  			utilAddr, e := btcaddr.NewPubKeyHash(
 820  				test.expected.addressHash, chainParams,
 821  			)
 822  			if e != nil {
 823  				tc.t.Errorf(
 824  					"%s NewPubKeyHash #%d (%s): "+
 825  						"unexpected error: %v", prefix, i,
 826  					test.name, e,
 827  				)
 828  				failed = true
 829  				continue
 830  			}
 831  			taPrefix := fmt.Sprintf(
 832  				"%s Address #%d (%s)", prefix,
 833  				i, test.name,
 834  			)
 835  			var ma waddrmgr.ManagedAddress
 836  			e = walletdb.View(
 837  				tc.db, func(tx walletdb.ReadTx) (e error) {
 838  					ns := tx.ReadBucket(waddrmgrNamespaceKey)
 839  					ma, e = tc.manager.Address(ns, utilAddr)
 840  					return e
 841  				},
 842  			)
 843  			if e != nil {
 844  				tc.t.Errorf(
 845  					"%s: unexpected error: %v", taPrefix,
 846  					e,
 847  				)
 848  				failed = true
 849  				continue
 850  			}
 851  			if !testAddress(tc, taPrefix, ma, &test.expected) {
 852  				failed = true
 853  				continue
 854  			}
 855  		}
 856  		return !failed
 857  	}
 858  	// The address manager could either be locked or unlocked here depending on
 859  	// whether or not it's a watching-only manager. When it's unlocked, this will
 860  	// test both the public and private address data are accurate. When it's locked,
 861  	// it must be watching-only, so only the public address information is tested
 862  	// and the private functions are checked to ensure they return the expected
 863  	// ErrWatchingOnly error.
 864  	if !testResults() {
 865  		return false
 866  	}
 867  	// Everything after this point involves locking the address manager and
 868  	// retesting the addresses with a locked manager. However, for watching-only
 869  	// mode, this has already happened, so just exit now in that case.
 870  	if tc.watchingOnly {
 871  		return true
 872  	}
 873  	// Lock the manager and retest all of the addresses to ensure the private
 874  	// information returns the expected error.
 875  	if e := tc.rootManager.Lock(); E.Chk(e) {
 876  		tc.t.Errorf("Lock: unexpected error: %v", e)
 877  		return false
 878  	}
 879  	tc.unlocked = false
 880  	if !testResults() {
 881  		return false
 882  	}
 883  	return true
 884  }
 885  
 886  // testImportScript tests that importing scripts works properly. It ensures they
 887  // can be retrieved by Address after they have been imported and the addresses
 888  // give the expected values when the manager is locked and unlocked.
 889  //
 890  // This function expects the manager is already locked when called and returns
 891  // with the manager locked.
 892  func testImportScript(tc *testContext) bool {
 893  	tests := []struct {
 894  		name       string
 895  		in         []byte
 896  		blockstamp waddrmgr.BlockStamp
 897  		expected   expectedAddr
 898  	}{
 899  		{
 900  			name: "p2sh uncompressed pubkey",
 901  			in: hexToBytes(
 902  				"41048b65a0e6bb200e6dac05e74281b1ab9a41e8" +
 903  					"0006d6b12d8521e09981da97dd96ac72d24d1a7d" +
 904  					"ed9493a9fc20fdb4a714808f0b680f1f1d935277" +
 905  					"48b5e3f629ffac",
 906  			),
 907  			expected: expectedAddr{
 908  				address:     "3MbyWAu9UaoBewR3cArF1nwf4aQgVwzrA5",
 909  				addressHash: hexToBytes("da6e6a632d96dc5530d7b3c9f3017725d023093e"),
 910  				internal:    false,
 911  				imported:    true,
 912  				compressed:  false,
 913  				// script is set to the in field during tests.
 914  			},
 915  		},
 916  		{
 917  			name: "p2sh multisig",
 918  			in: hexToBytes(
 919  				"524104cb9c3c222c5f7a7d3b9bd152f363a0b6d5" +
 920  					"4c9eb312c4d4f9af1e8551b6c421a6a4ab0e2910" +
 921  					"5f24de20ff463c1c91fcf3bf662cdde4783d4799" +
 922  					"f787cb7c08869b4104ccc588420deeebea22a7e9" +
 923  					"00cc8b68620d2212c374604e3487ca08f1ff3ae1" +
 924  					"2bdc639514d0ec8612a2d3c519f084d9a00cbbe3" +
 925  					"b53d071e9b09e71e610b036aa24104ab47ad1939" +
 926  					"edcb3db65f7fedea62bbf781c5410d3f22a7a3a5" +
 927  					"6ffefb2238af8627363bdf2ed97c1f89784a1aec" +
 928  					"db43384f11d2acc64443c7fc299cef0400421a53ae",
 929  			),
 930  			expected: expectedAddr{
 931  				address:     "34CRZpt8j81rgh9QhzuBepqPi4cBQSjhjr",
 932  				addressHash: hexToBytes("1b800cec1fe92222f36a502c139bed47c5959715"),
 933  				internal:    false,
 934  				imported:    true,
 935  				compressed:  false,
 936  				// script is set to the in field during tests.
 937  			},
 938  		},
 939  	}
 940  	// The manager must be unlocked to import a private key and also for testing
 941  	// private data. However, a watching-only manager can't be unlocked.
 942  	if !tc.watchingOnly {
 943  		e := walletdb.View(
 944  			tc.db, func(tx walletdb.ReadTx) (e error) {
 945  				ns := tx.ReadBucket(waddrmgrNamespaceKey)
 946  				return tc.rootManager.Unlock(ns, privPassphrase)
 947  			},
 948  		)
 949  		if e != nil {
 950  			tc.t.Errorf("Unlock: unexpected error: %v", e)
 951  			return false
 952  		}
 953  		tc.unlocked = true
 954  	}
 955  	// Only import the scripts when in the create phase of testing.
 956  	tc.account = waddrmgr.ImportedAddrAccount
 957  	prefix := testNamePrefix(tc)
 958  	if tc.create {
 959  		for i, test := range tests {
 960  			test.expected.script = test.in
 961  			prefix = fmt.Sprintf(
 962  				"%s ImportScript #%d (%s)", prefix,
 963  				i, test.name,
 964  			)
 965  			var addr waddrmgr.ManagedScriptAddress
 966  			e := walletdb.Update(
 967  				tc.db, func(tx walletdb.ReadWriteTx) (e error) {
 968  					ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
 969  					addr, e = tc.manager.ImportScript(ns, test.in, &test.blockstamp)
 970  					return e
 971  				},
 972  			)
 973  			if e != nil {
 974  				tc.t.Errorf(
 975  					"%s: unexpected error: %v", prefix,
 976  					e,
 977  				)
 978  				continue
 979  			}
 980  			if !testAddress(tc, prefix, addr, &test.expected) {
 981  				continue
 982  			}
 983  		}
 984  	}
 985  	// Setup a closure to test the results since the same tests need to be repeated
 986  	// with the manager unlocked and locked.
 987  	chainParams := tc.manager.ChainParams()
 988  	testResults := func() bool {
 989  		failed := false
 990  		for i, test := range tests {
 991  			test.expected.script = test.in
 992  			// Use the Address API to retrieve each of the expected new addresses and ensure
 993  			// they're accurate.
 994  			utilAddr, e := btcaddr.NewScriptHash(
 995  				test.in,
 996  				chainParams,
 997  			)
 998  			if e != nil {
 999  				tc.t.Errorf(
1000  					"%s NewScriptHash #%d (%s): "+
1001  						"unexpected error: %v", prefix, i,
1002  					test.name, e,
1003  				)
1004  				failed = true
1005  				continue
1006  			}
1007  			taPrefix := fmt.Sprintf(
1008  				"%s Address #%d (%s)", prefix,
1009  				i, test.name,
1010  			)
1011  			var ma waddrmgr.ManagedAddress
1012  			e = walletdb.View(
1013  				tc.db, func(tx walletdb.ReadTx) (e error) {
1014  					ns := tx.ReadBucket(waddrmgrNamespaceKey)
1015  					ma, e = tc.manager.Address(ns, utilAddr)
1016  					return e
1017  				},
1018  			)
1019  			if e != nil {
1020  				tc.t.Errorf(
1021  					"%s: unexpected error: %v", taPrefix,
1022  					e,
1023  				)
1024  				failed = true
1025  				continue
1026  			}
1027  			if !testAddress(tc, taPrefix, ma, &test.expected) {
1028  				failed = true
1029  				continue
1030  			}
1031  		}
1032  		return !failed
1033  	}
1034  	// The address manager could either be locked or unlocked here depending on
1035  	// whether or not it's a watching-only manager. When it's unlocked, this will
1036  	// test both the public and private address data are accurate. When it's locked,
1037  	// it must be watching-only, so only the public address information is tested
1038  	// and the private functions are checked to ensure they return the expected
1039  	// ErrWatchingOnly error.
1040  	if !testResults() {
1041  		return false
1042  	}
1043  	// Everything after this point involves locking the address manager and
1044  	// retesting the addresses with a locked manager. However, for watching-only
1045  	// mode, this has already happened, so just exit now in that case.
1046  	if tc.watchingOnly {
1047  		return true
1048  	}
1049  	// Lock the manager and retest all of the addresses to ensure the private
1050  	// information returns the expected error.
1051  	if e := tc.rootManager.Lock(); E.Chk(e) {
1052  		tc.t.Errorf("Lock: unexpected error: %v", e)
1053  		return false
1054  	}
1055  	tc.unlocked = false
1056  	if !testResults() {
1057  		return false
1058  	}
1059  	return true
1060  }
1061  
1062  // testMarkUsed ensures used addresses are flagged as such.
1063  func testMarkUsed(tc *testContext) bool {
1064  	tests := []struct {
1065  		name string
1066  		typ  addrType
1067  		in   []byte
1068  	}{
1069  		{
1070  			name: "managed address",
1071  			typ:  addrPubKeyHash,
1072  			in:   hexToBytes("2ef94abb9ee8f785d087c3ec8d6ee467e92d0d0a"),
1073  		},
1074  		{
1075  			name: "script address",
1076  			typ:  addrScriptHash,
1077  			in:   hexToBytes("da6e6a632d96dc5530d7b3c9f3017725d023093e"),
1078  		},
1079  	}
1080  	prefix := "MarkUsed"
1081  	chainParams := tc.manager.ChainParams()
1082  	for i, test := range tests {
1083  		addrHash := test.in
1084  		var addr btcaddr.Address
1085  		var e error
1086  		switch test.typ {
1087  		case addrPubKeyHash:
1088  			addr, e = btcaddr.NewPubKeyHash(addrHash, chainParams)
1089  		case addrScriptHash:
1090  			addr, e = btcaddr.NewScriptHashFromHash(addrHash, chainParams)
1091  		default:
1092  			panic("unreachable")
1093  		}
1094  		if e != nil {
1095  			tc.t.Errorf("%s #%d: NewAddress unexpected error: %v", prefix, i, e)
1096  			continue
1097  		}
1098  		e = walletdb.Update(
1099  			tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1100  				ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1101  				maddr, e := tc.manager.Address(ns, addr)
1102  				if e != nil {
1103  					tc.t.Errorf("%s #%d: Address unexpected error: %v", prefix, i, e)
1104  					return nil
1105  				}
1106  				if tc.create {
1107  					// Test that initially the address is not flagged as used
1108  					used := maddr.Used(ns)
1109  					if used != false {
1110  						tc.t.Errorf(
1111  							"%s #%d: unexpected used flag -- got "+
1112  								"%v, want %v", prefix, i, used, false,
1113  						)
1114  					}
1115  				}
1116  				e = tc.manager.MarkUsed(ns, addr)
1117  				if e != nil {
1118  					tc.t.Errorf("%s #%d: unexpected error: %v", prefix, i, e)
1119  					return nil
1120  				}
1121  				used := maddr.Used(ns)
1122  				if used != true {
1123  					tc.t.Errorf(
1124  						"%s #%d: unexpected used flag -- got "+
1125  							"%v, want %v", prefix, i, used, true,
1126  					)
1127  				}
1128  				return nil
1129  			},
1130  		)
1131  		if e != nil {
1132  			tc.t.Errorf("Unexpected error %v", e)
1133  		}
1134  	}
1135  	return true
1136  }
1137  
1138  // testChangePassphrase ensures changes both the public and private passphrases
1139  // works as intended.
1140  func testChangePassphrase(tc *testContext) bool {
1141  	// Force an error when changing the passphrase due to failure to generate a new
1142  	// secret key by replacing the generation function one that intentionally
1143  	// errors.
1144  	testName := "ChangePassphrase (public) with invalid new secret key"
1145  	oldKeyGen := waddrmgr.SetSecretKeyGen(failingSecretKeyGen)
1146  	e := walletdb.Update(
1147  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1148  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1149  			return tc.rootManager.ChangePassphrase(
1150  				ns, pubPassphrase, pubPassphrase2, false, fastScrypt,
1151  			)
1152  		},
1153  	)
1154  	if !checkManagerError(tc.t, testName, e, waddrmgr.ErrCrypto) {
1155  		return false
1156  	}
1157  	// Attempt to change public passphrase with invalid old passphrase.
1158  	testName = "ChangePassphrase (public) with invalid old passphrase"
1159  	waddrmgr.SetSecretKeyGen(oldKeyGen)
1160  	e = walletdb.Update(
1161  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1162  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1163  			return tc.rootManager.ChangePassphrase(
1164  				ns, []byte("bogus"), pubPassphrase2, false, fastScrypt,
1165  			)
1166  		},
1167  	)
1168  	if !checkManagerError(tc.t, testName, e, waddrmgr.ErrWrongPassphrase) {
1169  		return false
1170  	}
1171  	// Change the public passphrase.
1172  	testName = "ChangePassphrase (public)"
1173  	e = walletdb.Update(
1174  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1175  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1176  			return tc.rootManager.ChangePassphrase(
1177  				ns, pubPassphrase, pubPassphrase2, false, fastScrypt,
1178  			)
1179  		},
1180  	)
1181  	if e != nil {
1182  		tc.t.Errorf("%s: unexpected error: %v", testName, e)
1183  		return false
1184  	}
1185  	// Ensure the public passphrase was successfully changed.
1186  	if !tc.rootManager.TstCheckPublicPassphrase(pubPassphrase2) {
1187  		tc.t.Errorf("%s: passphrase does not match", testName)
1188  		return false
1189  	}
1190  	// Change the private passphrase back to what it was.
1191  	e = walletdb.Update(
1192  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1193  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1194  			return tc.rootManager.ChangePassphrase(
1195  				ns, pubPassphrase2, pubPassphrase, false, fastScrypt,
1196  			)
1197  		},
1198  	)
1199  	if e != nil {
1200  		tc.t.Errorf("%s: unexpected error: %v", testName, e)
1201  		return false
1202  	}
1203  	// Attempt to change private passphrase with invalid old passphrase. The error
1204  	// should be ErrWrongPassphrase or ErrWatchingOnly depending on the type of the
1205  	// address manager.
1206  	testName = "ChangePassphrase (private) with invalid old passphrase"
1207  	e = walletdb.Update(
1208  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1209  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1210  			return tc.rootManager.ChangePassphrase(
1211  				ns, []byte("bogus"), privPassphrase2, true, fastScrypt,
1212  			)
1213  		},
1214  	)
1215  	wantErrCode := waddrmgr.ErrWrongPassphrase
1216  	if tc.watchingOnly {
1217  		wantErrCode = waddrmgr.ErrWatchingOnly
1218  	}
1219  	if !checkManagerError(tc.t, testName, e, wantErrCode) {
1220  		return false
1221  	}
1222  	// Everything after this point involves testing that the private passphrase for
1223  	// the address manager can be changed successfully. This is not possible for
1224  	// watching-only mode, so just exit now in that case.
1225  	if tc.watchingOnly {
1226  		return true
1227  	}
1228  	// Change the private passphrase.
1229  	testName = "ChangePassphrase (private)"
1230  	e = walletdb.Update(
1231  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1232  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1233  			return tc.rootManager.ChangePassphrase(
1234  				ns, privPassphrase, privPassphrase2, true, fastScrypt,
1235  			)
1236  		},
1237  	)
1238  	if e != nil {
1239  		tc.t.Errorf("%s: unexpected error: %v", testName, e)
1240  		return false
1241  	}
1242  	// Unlock the manager with the new passphrase to ensure it changed as expected.
1243  	e = walletdb.Update(
1244  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1245  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1246  			return tc.rootManager.Unlock(ns, privPassphrase2)
1247  		},
1248  	)
1249  	if e != nil {
1250  		tc.t.Errorf(
1251  			"%s: failed to unlock with new private "+
1252  				"passphrase: %v", testName, e,
1253  		)
1254  		return false
1255  	}
1256  	tc.unlocked = true
1257  	// Change the private passphrase back to what it was while the manager is
1258  	// unlocked to ensure that path works properly as well.
1259  	e = walletdb.Update(
1260  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1261  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1262  			return tc.rootManager.ChangePassphrase(
1263  				ns, privPassphrase2, privPassphrase, true, fastScrypt,
1264  			)
1265  		},
1266  	)
1267  	if e != nil {
1268  		tc.t.Errorf("%s: unexpected error: %v", testName, e)
1269  		return false
1270  	}
1271  	if tc.rootManager.IsLocked() {
1272  		tc.t.Errorf("%s: manager is locked", testName)
1273  		return false
1274  	}
1275  	// Relock the manager for future tests.
1276  	if e := tc.rootManager.Lock(); E.Chk(e) {
1277  		tc.t.Errorf("Lock: unexpected error: %v", e)
1278  		return false
1279  	}
1280  	tc.unlocked = false
1281  	return true
1282  }
1283  
1284  // testNewAccount tests the new account creation func of the address manager
1285  // works as expected.
1286  func testNewAccount(tc *testContext) bool {
1287  	if tc.watchingOnly {
1288  		// Creating new accounts in watching-only mode should return ErrWatchingOnly
1289  		e := walletdb.Update(
1290  			tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1291  				ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1292  				_, e = tc.manager.NewAccount(ns, "test")
1293  				return e
1294  			},
1295  		)
1296  		if !checkManagerError(
1297  			tc.t, "Create account in watching-only mode", e,
1298  			waddrmgr.ErrWatchingOnly,
1299  		) {
1300  			tc.manager.Close()
1301  			return false
1302  		}
1303  		return true
1304  	}
1305  	// Creating new accounts when wallet is locked should return ErrLocked
1306  	e := walletdb.Update(
1307  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1308  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1309  			_, e = tc.manager.NewAccount(ns, "test")
1310  			return e
1311  		},
1312  	)
1313  	if !checkManagerError(
1314  		tc.t, "Create account when wallet is locked", e,
1315  		waddrmgr.ErrLocked,
1316  	) {
1317  		tc.manager.Close()
1318  		return false
1319  	}
1320  	// Unlock the wallet to decrypt cointype keys required to derive account keys
1321  	e = walletdb.Update(
1322  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1323  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1324  			e = tc.rootManager.Unlock(ns, privPassphrase)
1325  			return e
1326  		},
1327  	)
1328  	if e != nil {
1329  		tc.t.Errorf("Unlock: unexpected error: %v", e)
1330  		return false
1331  	}
1332  	tc.unlocked = true
1333  	testName := "acct-create"
1334  	expectedAccount := tc.account + 1
1335  	if !tc.create {
1336  		// Create a new account in open mode
1337  		testName = "acct-open"
1338  		expectedAccount++
1339  	}
1340  	var account uint32
1341  	e = walletdb.Update(
1342  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1343  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1344  			account, e = tc.manager.NewAccount(ns, testName)
1345  			return e
1346  		},
1347  	)
1348  	if e != nil {
1349  		tc.t.Errorf("NewAccount: unexpected error: %v", e)
1350  		return false
1351  	}
1352  	if account != expectedAccount {
1353  		tc.t.Errorf(
1354  			"NewAccount "+
1355  				"account mismatch -- got %d, "+
1356  				"want %d", account, expectedAccount,
1357  		)
1358  		return false
1359  	}
1360  	// Test duplicate account name error
1361  	e = walletdb.Update(
1362  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1363  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1364  			_, e = tc.manager.NewAccount(ns, testName)
1365  			return e
1366  		},
1367  	)
1368  	wantErrCode := waddrmgr.ErrDuplicateAccount
1369  	if !checkManagerError(tc.t, testName, e, wantErrCode) {
1370  		return false
1371  	}
1372  	// Test account name validation
1373  	testName = "" // Empty account names are not allowed
1374  	e = walletdb.Update(
1375  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1376  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1377  			_, e = tc.manager.NewAccount(ns, testName)
1378  			return e
1379  		},
1380  	)
1381  	wantErrCode = waddrmgr.ErrInvalidAccount
1382  	if !checkManagerError(tc.t, testName, e, wantErrCode) {
1383  		return false
1384  	}
1385  	testName = "imported" // A reserved account name
1386  	e = walletdb.Update(
1387  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1388  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1389  			_, e = tc.manager.NewAccount(ns, testName)
1390  			return e
1391  		},
1392  	)
1393  	wantErrCode = waddrmgr.ErrInvalidAccount
1394  	if !checkManagerError(tc.t, testName, e, wantErrCode) {
1395  		return false
1396  	}
1397  	return true
1398  }
1399  
1400  // testLookupAccount tests the basic account lookup func of the address manager
1401  // works as expected.
1402  func testLookupAccount(tc *testContext) bool {
1403  	// Lookup accounts created earlier in testNewAccount
1404  	expectedAccounts := map[string]uint32{
1405  		waddrmgr.TstDefaultAccountName:   waddrmgr.DefaultAccountNum,
1406  		waddrmgr.ImportedAddrAccountName: waddrmgr.ImportedAddrAccount,
1407  	}
1408  	for acctName, expectedAccount := range expectedAccounts {
1409  		var account uint32
1410  		e := walletdb.View(
1411  			tc.db, func(tx walletdb.ReadTx) (e error) {
1412  				ns := tx.ReadBucket(waddrmgrNamespaceKey)
1413  				account, e = tc.manager.LookupAccount(ns, acctName)
1414  				return e
1415  			},
1416  		)
1417  		if e != nil {
1418  			tc.t.Errorf("LookupAccount: unexpected error: %v", e)
1419  			return false
1420  		}
1421  		if account != expectedAccount {
1422  			tc.t.Errorf(
1423  				"LookupAccount "+
1424  					"account mismatch -- got %d, "+
1425  					"want %d", account, expectedAccount,
1426  			)
1427  			return false
1428  		}
1429  	}
1430  	// Test account not found error
1431  	testName := "non existent account"
1432  	e := walletdb.View(
1433  		tc.db, func(tx walletdb.ReadTx) (e error) {
1434  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
1435  			_, e = tc.manager.LookupAccount(ns, testName)
1436  			return e
1437  		},
1438  	)
1439  	wantErrCode := waddrmgr.ErrAccountNotFound
1440  	if !checkManagerError(tc.t, testName, e, wantErrCode) {
1441  		return false
1442  	}
1443  	// Test last account
1444  	var lastAccount uint32
1445  	e = walletdb.View(
1446  		tc.db, func(tx walletdb.ReadTx) (e error) {
1447  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
1448  			lastAccount, e = tc.manager.LastAccount(ns)
1449  			return e
1450  		},
1451  	)
1452  	var expectedLastAccount uint32
1453  	expectedLastAccount = 1
1454  	if !tc.create {
1455  		// Existing wallet manager will have 3 accounts
1456  		expectedLastAccount = 2
1457  	}
1458  	if lastAccount != expectedLastAccount {
1459  		tc.t.Errorf(
1460  			"LookupAccount "+
1461  				"account mismatch -- got %d, "+
1462  				"want %d", lastAccount, expectedLastAccount,
1463  		)
1464  		return false
1465  	}
1466  	// Test account lookup for default account adddress
1467  	var expectedAccount uint32
1468  	for i, addr := range expectedAddrs {
1469  		addr, e := btcaddr.NewPubKeyHash(
1470  			addr.addressHash,
1471  			tc.manager.ChainParams(),
1472  		)
1473  		if e != nil {
1474  			tc.t.Errorf("AddrAccount #%d: unexpected error: %v", i, e)
1475  			return false
1476  		}
1477  		var account uint32
1478  		e = walletdb.View(
1479  			tc.db, func(tx walletdb.ReadTx) (e error) {
1480  				ns := tx.ReadBucket(waddrmgrNamespaceKey)
1481  				account, e = tc.manager.AddrAccount(ns, addr)
1482  				return e
1483  			},
1484  		)
1485  		if e != nil {
1486  			tc.t.Errorf("AddrAccount #%d: unexpected error: %v", i, e)
1487  			return false
1488  		}
1489  		if account != expectedAccount {
1490  			tc.t.Errorf(
1491  				"AddrAccount "+
1492  					"account mismatch -- got %d, "+
1493  					"want %d", account, expectedAccount,
1494  			)
1495  			return false
1496  		}
1497  	}
1498  	return true
1499  }
1500  
1501  // testRenameAccount tests the rename account func of the address manager works
1502  // as expected.
1503  func testRenameAccount(tc *testContext) bool {
1504  	var acctName string
1505  	e := walletdb.View(
1506  		tc.db, func(tx walletdb.ReadTx) (e error) {
1507  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
1508  			acctName, e = tc.manager.AccountName(ns, tc.account)
1509  			return e
1510  		},
1511  	)
1512  	if e != nil {
1513  		tc.t.Errorf("AccountName: unexpected error: %v", e)
1514  		return false
1515  	}
1516  	testName := acctName + "-renamed"
1517  	e = walletdb.Update(
1518  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1519  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1520  			return tc.manager.RenameAccount(ns, tc.account, testName)
1521  		},
1522  	)
1523  	if e != nil {
1524  		tc.t.Errorf("RenameAccount: unexpected error: %v", e)
1525  		return false
1526  	}
1527  	var newName string
1528  	e = walletdb.View(
1529  		tc.db, func(tx walletdb.ReadTx) (e error) {
1530  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
1531  			newName, e = tc.manager.AccountName(ns, tc.account)
1532  			return e
1533  		},
1534  	)
1535  	if e != nil {
1536  		tc.t.Errorf("AccountName: unexpected error: %v", e)
1537  		return false
1538  	}
1539  	if newName != testName {
1540  		tc.t.Errorf(
1541  			"RenameAccount "+
1542  				"account name mismatch -- got %s, "+
1543  				"want %s", newName, testName,
1544  		)
1545  		return false
1546  	}
1547  	// Test duplicate account name error
1548  	e = walletdb.Update(
1549  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1550  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1551  			return tc.manager.RenameAccount(ns, tc.account, testName)
1552  		},
1553  	)
1554  	wantErrCode := waddrmgr.ErrDuplicateAccount
1555  	if !checkManagerError(tc.t, testName, e, wantErrCode) {
1556  		return false
1557  	}
1558  	// Test old account name is no longer valid
1559  	e = walletdb.View(
1560  		tc.db, func(tx walletdb.ReadTx) (e error) {
1561  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
1562  			_, e = tc.manager.LookupAccount(ns, acctName)
1563  			return e
1564  		},
1565  	)
1566  	wantErrCode = waddrmgr.ErrAccountNotFound
1567  	if !checkManagerError(tc.t, testName, e, wantErrCode) {
1568  		return false
1569  	}
1570  	return true
1571  }
1572  
1573  // testForEachAccount tests the retrieve all accounts func of the address
1574  // manager works as expected.
1575  func testForEachAccount(tc *testContext) bool {
1576  	prefix := testNamePrefix(tc) + " testForEachAccount"
1577  	expectedAccounts := []uint32{0, 1}
1578  	if !tc.create {
1579  		// Existing wallet manager will have 3 accounts
1580  		expectedAccounts = append(expectedAccounts, 2)
1581  	}
1582  	// Imported account
1583  	expectedAccounts = append(expectedAccounts, waddrmgr.ImportedAddrAccount)
1584  	var accounts []uint32
1585  	e := walletdb.View(
1586  		tc.db, func(tx walletdb.ReadTx) (e error) {
1587  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
1588  			return tc.manager.ForEachAccount(
1589  				ns, func(account uint32) (e error) {
1590  					accounts = append(accounts, account)
1591  					return nil
1592  				},
1593  			)
1594  		},
1595  	)
1596  	if e != nil {
1597  		tc.t.Errorf("%s: unexpected error: %v", prefix, e)
1598  		return false
1599  	}
1600  	if len(accounts) != len(expectedAccounts) {
1601  		tc.t.Errorf(
1602  			"%s: unexpected number of accounts - got "+
1603  				"%d, want %d", prefix, len(accounts),
1604  			len(expectedAccounts),
1605  		)
1606  		return false
1607  	}
1608  	for i, account := range accounts {
1609  		if expectedAccounts[i] != account {
1610  			tc.t.Errorf(
1611  				"%s #%d: "+
1612  					"account mismatch -- got %d, "+
1613  					"want %d", prefix, i, account, expectedAccounts[i],
1614  			)
1615  		}
1616  	}
1617  	return true
1618  }
1619  
1620  // testForEachAccountAddress tests that iterating through the given account
1621  // addresses using the manager API works as expected.
1622  func testForEachAccountAddress(tc *testContext) bool {
1623  	prefix := testNamePrefix(tc) + " testForEachAccountAddress"
1624  	// Make a map of expected addresses
1625  	expectedAddrMap := make(map[string]*expectedAddr, len(expectedAddrs))
1626  	for i := 0; i < len(expectedAddrs); i++ {
1627  		expectedAddrMap[expectedAddrs[i].address] = &expectedAddrs[i]
1628  	}
1629  	var addrs []waddrmgr.ManagedAddress
1630  	e := walletdb.View(
1631  		tc.db, func(tx walletdb.ReadTx) (e error) {
1632  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
1633  			return tc.manager.ForEachAccountAddress(
1634  				ns, tc.account,
1635  				func(maddr waddrmgr.ManagedAddress) (e error) {
1636  					addrs = append(addrs, maddr)
1637  					return nil
1638  				},
1639  			)
1640  		},
1641  	)
1642  	if e != nil {
1643  		tc.t.Errorf("%s: unexpected error: %v", prefix, e)
1644  		return false
1645  	}
1646  	for i := 0; i < len(addrs); i++ {
1647  		prefix = fmt.Sprintf("%s: #%d", prefix, i)
1648  		gotAddr := addrs[i]
1649  		wantAddr := expectedAddrMap[gotAddr.Address().String()]
1650  		if !testAddress(tc, prefix, gotAddr, wantAddr) {
1651  			return false
1652  		}
1653  		delete(expectedAddrMap, gotAddr.Address().String())
1654  	}
1655  	if len(expectedAddrMap) != 0 {
1656  		tc.t.Errorf(
1657  			"%s: unexpected addresses -- got %d, want %d", prefix,
1658  			len(expectedAddrMap), 0,
1659  		)
1660  		return false
1661  	}
1662  	return true
1663  }
1664  
1665  // testManagerAPI tests the functions provided by the Manager API as well as the
1666  // ManagedAddress, ManagedPubKeyAddress, and ManagedScriptAddress interfaces.
1667  func testManagerAPI(tc *testContext) {
1668  	testLocking(tc)
1669  	testExternalAddresses(tc)
1670  	testInternalAddresses(tc)
1671  	testImportPrivateKey(tc)
1672  	testImportScript(tc)
1673  	testMarkUsed(tc)
1674  	testChangePassphrase(tc)
1675  	// Reset default account
1676  	tc.account = 0
1677  	testNewAccount(tc)
1678  	testLookupAccount(tc)
1679  	testForEachAccount(tc)
1680  	testForEachAccountAddress(tc)
1681  	// Rename account 1 "acct-create"
1682  	tc.account = 1
1683  	testRenameAccount(tc)
1684  }
1685  
1686  // testWatchingOnly tests various facets of a watching-only address manager such
1687  // as running the full set of API tests against a newly converted copy as well
1688  // as when it is opened from an existing namespace.
1689  func testWatchingOnly(tc *testContext) bool {
1690  	// Make a copy of the current database so the copy can be converted to watching
1691  	// only.
1692  	woMgrName := "mgrtestwo.bin"
1693  	_ = os.Remove(woMgrName)
1694  	fi, e := os.OpenFile(woMgrName, os.O_CREATE|os.O_RDWR, 0600)
1695  	if e != nil {
1696  		tc.t.Errorf("%v", e)
1697  		return false
1698  	}
1699  	if e = tc.db.Copy(fi); E.Chk(e) {
1700  		if e = fi.Close(); waddrmgr.E.Chk(e) {
1701  		}
1702  		tc.t.Errorf("%v", e)
1703  		return false
1704  	}
1705  	if e = fi.Close(); waddrmgr.E.Chk(e) {
1706  	}
1707  	defer func() {
1708  		if e = os.Remove(woMgrName); waddrmgr.E.Chk(e) {
1709  		}
1710  	}()
1711  	// Open the new database copy and get the address manager namespace.
1712  	var db walletdb.DB
1713  	if db, e = walletdb.Open("bdb", woMgrName); waddrmgr.E.Chk(e) {
1714  		tc.t.Errorf("openDbNamespace: unexpected error: %v", e)
1715  		return false
1716  	}
1717  	
1718  	defer func() {
1719  		if e = db.Close(); waddrmgr.E.Chk(e) {
1720  		}
1721  	}()
1722  	// Open the manager using the namespace and convert it to watching-only.
1723  	var mgr *waddrmgr.Manager
1724  	e = walletdb.View(
1725  		db, func(tx walletdb.ReadTx) (e error) {
1726  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
1727  			mgr, e = waddrmgr.Open(ns, pubPassphrase, &chaincfg.MainNetParams)
1728  			return e
1729  		},
1730  	)
1731  	if e != nil {
1732  		tc.t.Errorf("%v", e)
1733  		return false
1734  	}
1735  	e = walletdb.Update(
1736  		db, func(tx walletdb.ReadWriteTx) (e error) {
1737  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1738  			return mgr.ConvertToWatchingOnly(ns)
1739  		},
1740  	)
1741  	if e != nil {
1742  		tc.t.Errorf("%v", e)
1743  		return false
1744  	}
1745  	// Run all of the manager API tests against the converted manager and close it.
1746  	// We'll also retrieve the default scope (BIP0044) from the manager in order to
1747  	// use.
1748  	scopedMgr, e := mgr.FetchScopedKeyManager(waddrmgr.KeyScopeBIP0044)
1749  	if e != nil {
1750  		tc.t.Errorf("unable to fetch bip 44 scope %v", e)
1751  		return false
1752  	}
1753  	testManagerAPI(
1754  		&testContext{
1755  			t:            tc.t,
1756  			db:           db,
1757  			rootManager:  mgr,
1758  			manager:      scopedMgr,
1759  			account:      0,
1760  			create:       false,
1761  			watchingOnly: true,
1762  		},
1763  	)
1764  	mgr.Close()
1765  	// Open the watching-only manager and run all the tests again.
1766  	e = walletdb.View(
1767  		db, func(tx walletdb.ReadTx) (e error) {
1768  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
1769  			mgr, e = waddrmgr.Open(ns, pubPassphrase, &chaincfg.MainNetParams)
1770  			return e
1771  		},
1772  	)
1773  	if e != nil {
1774  		tc.t.Errorf("Open Watching-Only: unexpected error: %v", e)
1775  		return false
1776  	}
1777  	defer mgr.Close()
1778  	scopedMgr, e = mgr.FetchScopedKeyManager(waddrmgr.KeyScopeBIP0044)
1779  	if e != nil {
1780  		tc.t.Errorf("unable to fetch bip 44 scope %v", e)
1781  		return false
1782  	}
1783  	testManagerAPI(
1784  		&testContext{
1785  			t:            tc.t,
1786  			db:           db,
1787  			rootManager:  mgr,
1788  			manager:      scopedMgr,
1789  			account:      0,
1790  			create:       false,
1791  			watchingOnly: true,
1792  		},
1793  	)
1794  	return true
1795  }
1796  
1797  // testSync tests various facets of setting the manager sync state.
1798  func testSync(tc *testContext) bool {
1799  	// Ensure syncing the manager to nil results in the synced to state being the
1800  	// earliest block (genesis block in this case).
1801  	e := walletdb.Update(
1802  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1803  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1804  			return tc.rootManager.SetSyncedTo(ns, nil)
1805  		},
1806  	)
1807  	if e != nil {
1808  		tc.t.Errorf("SetSyncedTo unexpected e on nil: %v", e)
1809  		return false
1810  	}
1811  	blockStamp := waddrmgr.BlockStamp{
1812  		Height: 0,
1813  		Hash:   *chaincfg.MainNetParams.GenesisHash,
1814  	}
1815  	gotBlockStamp := tc.rootManager.SyncedTo()
1816  	if gotBlockStamp != blockStamp {
1817  		tc.t.Errorf(
1818  			"SyncedTo unexpected block stamp on nil -- "+
1819  				"got %v, want %v", gotBlockStamp, blockStamp,
1820  		)
1821  		return false
1822  	}
1823  	// If we update to a new more recent block time stamp, then upon retrieval it
1824  	// should be returned as the best known state.
1825  	latestHash, e := chainhash.NewHash(seed)
1826  	if e != nil {
1827  		tc.t.Errorf("%v", e)
1828  		return false
1829  	}
1830  	blockStamp = waddrmgr.BlockStamp{
1831  		Height:    1,
1832  		Hash:      *latestHash,
1833  		Timestamp: time.Unix(1234, 0),
1834  	}
1835  	e = walletdb.Update(
1836  		tc.db, func(tx walletdb.ReadWriteTx) (e error) {
1837  			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1838  			return tc.rootManager.SetSyncedTo(ns, &blockStamp)
1839  		},
1840  	)
1841  	if e != nil {
1842  		tc.t.Errorf("SetSyncedTo unexpected e on nil: %v", e)
1843  		return false
1844  	}
1845  	gotBlockStamp = tc.rootManager.SyncedTo()
1846  	if gotBlockStamp != blockStamp {
1847  		tc.t.Errorf(
1848  			"SyncedTo unexpected block stamp on nil -- "+
1849  				"got %v, want %v", gotBlockStamp, blockStamp,
1850  		)
1851  		return false
1852  	}
1853  	return true
1854  }
1855  
1856  // // TestManager performs a full suite of tests against the address manager API.
1857  // // It makes use of a test context because the address manager is persistent and
1858  // // much of the testing involves having specific state.
1859  // func TestManager(// 	t *testing.T) {
1860  // 	t.Parallel()
1861  // 	teardown, db := emptyDB(t)
1862  // 	defer teardown()
1863  // 	// Open manager that does not exist to ensure the expected error is
1864  // 	// returned.
1865  // 	e := walletdb.View(db, func(tx walletdb.ReadTx) (e error) {
1866  // 		ns := tx.ReadBucket(waddrmgrNamespaceKey)
1867  // 		_, e := waddrmgr.Open(ns, pubPassphrase, &chaincfg.MainNetParams)
1868  // 		return e
1869  // 	})
1870  // 	if !checkManagerError(t, "Open non-existent", e, waddrmgr.ErrNoExist) {
1871  // 		return
1872  // 	}
1873  // 	// Create a new manager.
1874  // 	var mgr *waddrmgr.Manager
1875  // 	e = walletdb.Update(db, func(tx walletdb.ReadWriteTx) (e error) {
1876  // 		ns, e := tx.CreateTopLevelBucket(waddrmgrNamespaceKey)
1877  // 		if e != nil  {
1878  // 			return e
1879  // 		}
1880  // 		e = waddrmgr.Create(
1881  // 			ns, seed, pubPassphrase, privPassphrase,
1882  // 			&chaincfg.MainNetParams, fastScrypt, time.Time{},
1883  // 		)
1884  // 		if e != nil  {
1885  // 			return e
1886  // 		}
1887  // 		mgr, e = waddrmgr.Open(ns, pubPassphrase, &chaincfg.MainNetParams)
1888  // 		return e
1889  // 	})
1890  // 	if e != nil  {
1891  // 		t.Errorf("Create/Open: unexpected error: %v", e)
1892  // 		return
1893  // 	}
1894  // 	// NOTE: Not using deferred close here since part of the tests is
1895  // 	// explicitly closing the manager and then opening the existing one.
1896  // 	// Attempt to create the manager again to ensure the expected error is
1897  // 	// returned.
1898  // 	e = walletdb.Update(db, func(tx walletdb.ReadWriteTx) (e error) {
1899  // 		ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
1900  // 		return waddrmgr.Create(ns, seed, pubPassphrase, privPassphrase,
1901  // 			&chaincfg.MainNetParams, fastScrypt, time.Time{})
1902  // 	})
1903  // 	if !checkManagerError(t, "Create existing", e, waddrmgr.ErrAlreadyExists) {
1904  // 		mgr.Close()
1905  // 		return
1906  // 	}
1907  // 	// Run all of the manager API tests in create mode and close the
1908  // 	// manager after they've completed
1909  // 	scopedMgr, e := mgr.FetchScopedKeyManager(waddrmgr.KeyScopeBIP0044)
1910  // 	if e != nil  {
1911  // 		t.Fatalf("unable to fetch default scope: %v", e)
1912  // 	}
1913  // 	testManagerAPI(&testContext{
1914  // 		t:            t,
1915  // 		db:           db,
1916  // 		manager:      scopedMgr,
1917  // 		rootManager:  mgr,
1918  // 		account:      0,
1919  // 		create:       true,
1920  // 		watchingOnly: false,
1921  // 	})
1922  // 	mgr.Close()
1923  // 	// Ensure the expected error is returned if the latest manager version
1924  // 	// constant is bumped without writing code to actually do the upgrade.
1925  // 	*waddrmgr.TstLatestMgrVersion++
1926  // 	e = walletdb.View(db, func(tx walletdb.ReadTx) (e error) {
1927  // 		ns := tx.ReadBucket(waddrmgrNamespaceKey)
1928  // 		_, e := waddrmgr.Open(ns, pubPassphrase, &chaincfg.MainNetParams)
1929  // 		return e
1930  // 	})
1931  // 	if !checkManagerError(t, "Upgrade needed", e, waddrmgr.ErrUpgrade) {
1932  // 		return
1933  // 	}
1934  // 	*waddrmgr.TstLatestMgrVersion--
1935  // 	// Open the manager and run all the tests again in open mode which
1936  // 	// avoids reinserting new addresses like the create mode tests do.
1937  // 	e = walletdb.View(db, func(tx walletdb.ReadTx) (e error) {
1938  // 		ns := tx.ReadBucket(waddrmgrNamespaceKey)
1939  // 		var e error
1940  // 		mgr, e = waddrmgr.Open(ns, pubPassphrase, &chaincfg.MainNetParams)
1941  // 		return e
1942  // 	})
1943  // 	if e != nil  {
1944  // 		t.Errorf("Open: unexpected error: %v", e)
1945  // 		return
1946  // 	}
1947  // 	defer mgr.Close()
1948  // 	scopedMgr, e = mgr.FetchScopedKeyManager(waddrmgr.KeyScopeBIP0044)
1949  // 	if e != nil  {
1950  // 		t.Fatalf("unable to fetch default scope: %v", e)
1951  // 	}
1952  // 	tc := &testContext{
1953  // 		t:            t,
1954  // 		db:           db,
1955  // 		manager:      scopedMgr,
1956  // 		rootManager:  mgr,
1957  // 		account:      0,
1958  // 		create:       false,
1959  // 		watchingOnly: false,
1960  // 	}
1961  // 	testManagerAPI(tc)
1962  // 	// Now that the address manager has been tested in both the newly
1963  // 	// created and opened modes, test a watching-only version.
1964  // 	testWatchingOnly(tc)
1965  // 	// Ensure that the manager sync state functionality works as expected.
1966  // 	testSync(tc)
1967  // 	// Unlock the manager so it can be closed with it unlocked to ensure
1968  // 	// it works without issue.
1969  // 	e = walletdb.View(db, func(tx walletdb.ReadTx) (e error) {
1970  // 		ns := tx.ReadBucket(waddrmgrNamespaceKey)
1971  // 		return mgr.Unlock(ns, privPassphrase)
1972  // 	})
1973  // 	if e != nil  {
1974  // 		t.Errorf("Unlock: unexpected error: %v", e)
1975  // 	}
1976  // }
1977  
1978  // TestEncryptDecryptErrors ensures that errors which occur while encrypting and
1979  // decrypting data return the expected errors.
1980  func TestEncryptDecryptErrors(t *testing.T) {
1981  	t.Parallel()
1982  	teardown, db, mgr := setupManager(t)
1983  	defer teardown()
1984  	invalidKeyType := waddrmgr.CryptoKeyType(0xff)
1985  	var e error
1986  	if _, e = mgr.Encrypt(invalidKeyType, []byte{}); e == nil {
1987  		t.Fatalf("Encrypt accepted an invalid key type!")
1988  	}
1989  	if _, e = mgr.Decrypt(invalidKeyType, []byte{}); e == nil {
1990  		t.Fatalf("Encrypt accepted an invalid key type!")
1991  	}
1992  	if !mgr.IsLocked() {
1993  		t.Fatal("Manager should be locked at this point.")
1994  	}
1995  	// Now the mgr is locked and encrypting/decrypting with private keys should fail.
1996  	_, e = mgr.Encrypt(waddrmgr.CKTPrivate, []byte{})
1997  	checkManagerError(
1998  		t, "encryption with private key fails when manager is locked",
1999  		e, waddrmgr.ErrLocked,
2000  	)
2001  	_, e = mgr.Decrypt(waddrmgr.CKTPrivate, []byte{})
2002  	checkManagerError(
2003  		t, "decryption with private key fails when manager is locked",
2004  		e, waddrmgr.ErrLocked,
2005  	)
2006  	// Unlock the manager for these tests
2007  	e = walletdb.View(
2008  		db, func(tx walletdb.ReadTx) (e error) {
2009  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
2010  			return mgr.Unlock(ns, privPassphrase)
2011  		},
2012  	)
2013  	if e != nil {
2014  		t.Fatal("Attempted to unlock the manager, but failed:", e)
2015  	}
2016  	// Make sure to cover the ErrCrypto error path in Encrypt.
2017  	waddrmgr.TstRunWithFailingCryptoKeyPriv(
2018  		mgr, func() {
2019  			_, e = mgr.Encrypt(waddrmgr.CKTPrivate, []byte{})
2020  		},
2021  	)
2022  	checkManagerError(t, "failed encryption", e, waddrmgr.ErrCrypto)
2023  	// Make sure to cover the ErrCrypto error path in Decrypt.
2024  	waddrmgr.TstRunWithFailingCryptoKeyPriv(
2025  		mgr, func() {
2026  			_, e = mgr.Decrypt(waddrmgr.CKTPrivate, []byte{})
2027  		},
2028  	)
2029  	checkManagerError(t, "failed decryption", e, waddrmgr.ErrCrypto)
2030  }
2031  
2032  // TestEncryptDecrypt ensures that encrypting and decrypting data with the the
2033  // various crypto key types works as expected.
2034  func TestEncryptDecrypt(t *testing.T) {
2035  	t.Parallel()
2036  	teardown, db, mgr := setupManager(t)
2037  	defer teardown()
2038  	plainText := []byte("this is a plaintext")
2039  	// Make sure address manager is unlocked
2040  	e := walletdb.View(
2041  		db, func(tx walletdb.ReadTx) (e error) {
2042  			ns := tx.ReadBucket(waddrmgrNamespaceKey)
2043  			return mgr.Unlock(ns, privPassphrase)
2044  		},
2045  	)
2046  	if e != nil {
2047  		t.Fatal("Attempted to unlock the manager, but failed:", e)
2048  	}
2049  	keyTypes := []waddrmgr.CryptoKeyType{
2050  		waddrmgr.CKTPublic,
2051  		waddrmgr.CKTPrivate,
2052  		waddrmgr.CKTScript,
2053  	}
2054  	for _, keyType := range keyTypes {
2055  		cipherText, e := mgr.Encrypt(keyType, plainText)
2056  		if e != nil {
2057  			t.Fatalf("Failed to encrypt plaintext: %v", e)
2058  		}
2059  		decryptedCipherText, e := mgr.Decrypt(keyType, cipherText)
2060  		if e != nil {
2061  			t.Fatalf("Failed to decrypt plaintext: %v", e)
2062  		}
2063  		if !reflect.DeepEqual(decryptedCipherText, plainText) {
2064  			t.Fatal("Got:", decryptedCipherText, ", want:", plainText)
2065  		}
2066  	}
2067  }
2068  
2069  // // TestScopedKeyManagerManagement tests that callers are able to properly
2070  // // create, retrieve, and utilize new scoped managers outside the set of default
2071  // // created scopes.
2072  // func TestScopedKeyManagerManagement(t *testing.T) {
2073  // 	t.Parallel()
2074  // 	teardown, db := emptyDB(t)
2075  // 	defer teardown()
2076  // 	// We'll start the test by creating a new root manager that will be used for the
2077  // 	// duration of the test.
2078  // 	var mgr *waddrmgr.Manager
2079  // 	e := walletdb.Update(
2080  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2081  // 			ns, e := tx.CreateTopLevelBucket(waddrmgrNamespaceKey)
2082  // 			if e != nil {
2083  // 				return e
2084  // 			}
2085  // 			e = waddrmgr.Create(
2086  // 				ns, seed, pubPassphrase, privPassphrase,
2087  // 				&chaincfg.MainNetParams, fastScrypt, time.Time{},
2088  // 			)
2089  // 			if e != nil {
2090  // 				return e
2091  // 			}
2092  // 			mgr, e = waddrmgr.Open(
2093  // 				ns, pubPassphrase, &chaincfg.MainNetParams,
2094  // 			)
2095  // 			if e != nil {
2096  // 				return e
2097  // 			}
2098  // 			return mgr.Unlock(ns, privPassphrase)
2099  // 		},
2100  // 	)
2101  // 	if e != nil {
2102  // 		t.Fatalf("create/open: unexpected error: %v", e)
2103  // 	}
2104  // 	// All the default scopes should have been created and loaded into memory upon
2105  // 	// initial opening.
2106  // 	for _, scope := range waddrmgr.DefaultKeyScopes {
2107  // 		_, e := mgr.FetchScopedKeyManager(scope)
2108  // 		if e != nil {
2109  // 			t.Fatalf("unable to fetch scope %v: %v", scope, e)
2110  // 		}
2111  // 	}
2112  // 	// Next, ensure that if we create an internal and external addrs for each of the
2113  // 	// default scope types, then they're derived according to their schema.
2114  // 	e = walletdb.Update(
2115  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2116  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2117  // 			for _, scope := range waddrmgr.DefaultKeyScopes {
2118  // 				sMgr, e := mgr.FetchScopedKeyManager(scope)
2119  // 				if e != nil {
2120  // 					t.Fatalf("unable to fetch scope %v: %v", scope, e)
2121  // 				}
2122  // 				externalAddr, e := sMgr.NextExternalAddresses(
2123  // 					ns, waddrmgr.DefaultAccountNum, 1,
2124  // 				)
2125  // 				if e != nil {
2126  // 					t.Fatalf("unable to derive external addr: %v", e)
2127  // 				}
2128  // 				// The external address should match the prescribed addr schema for this scoped
2129  // 				// key manager.
2130  // 				if externalAddr[0].AddrType() != waddrmgr.ScopeAddrMap[scope].ExternalAddrType {
2131  // 					t.Fatalf(
2132  // 						"addr type mismatch: expected %v, got %v",
2133  // 						externalAddr[0].AddrType(),
2134  // 						waddrmgr.ScopeAddrMap[scope].ExternalAddrType,
2135  // 					)
2136  // 				}
2137  // 				internalAddr, e := sMgr.NextInternalAddresses(
2138  // 					ns, waddrmgr.DefaultAccountNum, 1,
2139  // 				)
2140  // 				if e != nil {
2141  // 					t.Fatalf("unable to derive internal addr: %v", e)
2142  // 				}
2143  // 				// Similarly, the internal address should match the prescribed addr schema for
2144  // 				// this scoped key manager.
2145  // 				if internalAddr[0].AddrType() != waddrmgr.ScopeAddrMap[scope].InternalAddrType {
2146  // 					t.Fatalf(
2147  // 						"addr type mismatch: expected %v, got %v",
2148  // 						internalAddr[0].AddrType(),
2149  // 						waddrmgr.ScopeAddrMap[scope].InternalAddrType,
2150  // 					)
2151  // 				}
2152  // 			}
2153  // 			return e
2154  // 		},
2155  // 	)
2156  // 	if e != nil {
2157  // 		t.Fatalf("unable to read db: %v", e)
2158  // 	}
2159  // 	// Now that the manager is open, we'll create a "test" scope that we'll be
2160  // 	// utilizing for the remainder of the test.
2161  // 	testScope := waddrmgr.KeyScope{
2162  // 		Purpose: 99,
2163  // 		Coin:    0,
2164  // 	}
2165  // 	addrSchema := waddrmgr.ScopeAddrSchema{
2166  // 		ExternalAddrType: waddrmgr.NestedWitnessPubKey,
2167  // 		InternalAddrType: waddrmgr.WitnessPubKey,
2168  // 	}
2169  // 	var scopedMgr *waddrmgr.ScopedKeyManager
2170  // 	e = walletdb.Update(
2171  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2172  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2173  // 			scopedMgr, e = mgr.NewScopedKeyManager(ns, testScope, addrSchema)
2174  // 			if e != nil {
2175  // 				return e
2176  // 			}
2177  // 			return nil
2178  // 		},
2179  // 	)
2180  // 	if e != nil {
2181  // 		t.Fatalf("unable to read db: %v", e)
2182  // 	}
2183  // 	// The manager was just created, we should be able to look it up within the root
2184  // 	// manager.
2185  // 	if _, e = mgr.FetchScopedKeyManager(testScope); E.Chk(e) {
2186  // 		t.Fatalf("attempt to read created mgr failed: %v", e)
2187  // 	}
2188  // 	var externalAddr, internalAddr []waddrmgr.ManagedAddress
2189  // 	e = walletdb.Update(
2190  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2191  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2192  // 			// We'll now create a new external address to ensure we retrieve the proper
2193  // 			// type.
2194  // 			externalAddr, e = scopedMgr.NextExternalAddresses(
2195  // 				ns, waddrmgr.DefaultAccountNum, 1,
2196  // 			)
2197  // 			if e != nil {
2198  // 				t.Fatalf("unable to derive external addr: %v", e)
2199  // 			}
2200  // 			internalAddr, e = scopedMgr.NextInternalAddresses(
2201  // 				ns, waddrmgr.DefaultAccountNum, 1,
2202  // 			)
2203  // 			if e != nil {
2204  // 				t.Fatalf("unable to derive internal addr: %v", e)
2205  // 			}
2206  // 			return nil
2207  // 		},
2208  // 	)
2209  // 	if e != nil {
2210  // 		t.Fatalf("open: unexpected error: %v", e)
2211  // 	}
2212  // 	// Ensure that the type of the address matches as expected.
2213  // 	if externalAddr[0].AddrType() != waddrmgr.NestedWitnessPubKey {
2214  // 		t.Fatalf(
2215  // 			"addr type mismatch: expected %v, got %v",
2216  // 			waddrmgr.NestedWitnessPubKey, externalAddr[0].AddrType(),
2217  // 		)
2218  // 	}
2219  // 	_, ok := externalAddr[0].Address().(*util.ScriptHash)
2220  // 	if !ok {
2221  // 		t.Fatalf("wrong type: %T", externalAddr[0].Address())
2222  // 	}
2223  // 	// We'll also create an internal address and ensure that the types match up
2224  // 	// properly.
2225  // 	if internalAddr[0].AddrType() != waddrmgr.WitnessPubKey {
2226  // 		t.Fatalf(
2227  // 			"addr type mismatch: expected %v, got %v",
2228  // 			waddrmgr.WitnessPubKey, internalAddr[0].AddrType(),
2229  // 		)
2230  // 	}
2231  // 	_, ok = internalAddr[0].Address().(*util.AddressWitnessPubKeyHash)
2232  // 	if !ok {
2233  // 		t.Fatalf("wrong type: %T", externalAddr[0].Address())
2234  // 	}
2235  // 	// We'll now simulate a restart by closing, then restarting the manager.
2236  // 	mgr.Close()
2237  // 	e = walletdb.View(
2238  // 		db, func(tx walletdb.ReadTx) (e error) {
2239  // 			ns := tx.ReadBucket(waddrmgrNamespaceKey)
2240  // 			var e error
2241  // 			mgr, e = waddrmgr.Open(ns, pubPassphrase, &chaincfg.MainNetParams)
2242  // 			if e != nil {
2243  // 				return e
2244  // 			}
2245  // 			return mgr.Unlock(ns, privPassphrase)
2246  // 		},
2247  // 	)
2248  // 	if e != nil {
2249  // 		t.Fatalf("open: unexpected error: %v", e)
2250  // 	}
2251  // 	defer mgr.Close()
2252  // 	// We should be able to retrieve the new scoped manager that we just created.
2253  // 	scopedMgr, e = mgr.FetchScopedKeyManager(testScope)
2254  // 	if e != nil {
2255  // 		t.Fatalf("attempt to read created mgr failed: %v", e)
2256  // 	}
2257  // 	// If we fetch the last generated external address, it should map exactly to the
2258  // 	// address that we just generated.
2259  // 	var lastAddr waddrmgr.ManagedAddress
2260  // 	e = walletdb.Update(
2261  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2262  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2263  // 			lastAddr, e = scopedMgr.LastExternalAddress(
2264  // 				ns, waddrmgr.DefaultAccountNum,
2265  // 			)
2266  // 			if e != nil {
2267  // 				return e
2268  // 			}
2269  // 			return nil
2270  // 		},
2271  // 	)
2272  // 	if e != nil {
2273  // 		t.Fatalf("open: unexpected error: %v", e)
2274  // 	}
2275  // 	if !bytes.Equal(lastAddr.AddrHash(), externalAddr[0].AddrHash()) {
2276  // 		t.Fatalf(
2277  // 			"mismatch addr hashes: expected %x, got %x",
2278  // 			externalAddr[0].AddrHash(), lastAddr.AddrHash(),
2279  // 		)
2280  // 	}
2281  // 	// After the restart, all the default scopes should be been re-loaded.
2282  // 	for _, scope := range waddrmgr.DefaultKeyScopes {
2283  // 		_, e := mgr.FetchScopedKeyManager(scope)
2284  // 		if e != nil {
2285  // 			t.Fatalf("unable to fetch scope %v: %v", scope, e)
2286  // 		}
2287  // 	}
2288  // 	// Finally, if we attempt to query the root manager for this last address, it
2289  // 	// should be able to locate the private key, etc.
2290  // 	e = walletdb.Update(
2291  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2292  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2293  // 			_, e := mgr.Address(ns, lastAddr.Address())
2294  // 			if e != nil {
2295  // 				return fmt.Errorf("unable to find addr: %v", e)
2296  // 			}
2297  // 			e = mgr.MarkUsed(ns, lastAddr.Address())
2298  // 			if e != nil {
2299  // 				return fmt.Errorf(
2300  // 					"unable to mark addr as "+
2301  // 						"used: %v", e,
2302  // 				)
2303  // 			}
2304  // 			return nil
2305  // 		},
2306  // 	)
2307  // 	if e != nil {
2308  // 		t.Fatalf("unable to find addr: %v", e)
2309  // 	}
2310  // }
2311  
2312  // // TestRootHDKeyNeutering tests that callers are unable to create new scoped
2313  // // managers once the root HD key has been deleted from the database.
2314  // func TestRootHDKeyNeutering(t *testing.T) {
2315  // 	t.Parallel()
2316  // 	teardown, db := emptyDB(t)
2317  // 	defer teardown()
2318  // 	// We'll start the test by creating a new root manager that will be used for the
2319  // 	// duration of the test.
2320  // 	var mgr *waddrmgr.Manager
2321  // 	e := walletdb.Update(
2322  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2323  // 			ns, e := tx.CreateTopLevelBucket(waddrmgrNamespaceKey)
2324  // 			if e != nil {
2325  // 				return e
2326  // 			}
2327  // 			e = waddrmgr.Create(
2328  // 				ns, seed, pubPassphrase, privPassphrase,
2329  // 				&chaincfg.MainNetParams, fastScrypt, time.Time{},
2330  // 			)
2331  // 			if e != nil {
2332  // 				return e
2333  // 			}
2334  // 			mgr, e = waddrmgr.Open(
2335  // 				ns, pubPassphrase, &chaincfg.MainNetParams,
2336  // 			)
2337  // 			if e != nil {
2338  // 				return e
2339  // 			}
2340  // 			return mgr.Unlock(ns, privPassphrase)
2341  // 		},
2342  // 	)
2343  // 	if e != nil {
2344  // 		t.Fatalf("create/open: unexpected error: %v", e)
2345  // 	}
2346  // 	defer mgr.Close()
2347  // 	// With the root manager open, we'll now create a new scoped manager for usage
2348  // 	// within this test.
2349  // 	testScope := waddrmgr.KeyScope{
2350  // 		Purpose: 99,
2351  // 		Coin:    0,
2352  // 	}
2353  // 	addrSchema := waddrmgr.ScopeAddrSchema{
2354  // 		ExternalAddrType: waddrmgr.NestedWitnessPubKey,
2355  // 		InternalAddrType: waddrmgr.WitnessPubKey,
2356  // 	}
2357  // 	e = walletdb.Update(
2358  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2359  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2360  // 			_, e := mgr.NewScopedKeyManager(ns, testScope, addrSchema)
2361  // 			if e != nil {
2362  // 				return e
2363  // 			}
2364  // 			return nil
2365  // 		},
2366  // 	)
2367  // 	if e != nil {
2368  // 		t.Fatalf("unable to read db: %v", e)
2369  // 	}
2370  // 	// With the manager created, we'll now neuter the root HD private key.
2371  // 	e = walletdb.Update(
2372  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2373  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2374  // 			return mgr.NeuterRootKey(ns)
2375  // 		},
2376  // 	)
2377  // 	if e != nil {
2378  // 		t.Fatalf("unable to read db: %v", e)
2379  // 	}
2380  // 	// If we try to create *another* scope, this should fail, as the root key is no
2381  // 	// longer in the database.
2382  // 	testScope = waddrmgr.KeyScope{
2383  // 		Purpose: 100,
2384  // 		Coin:    0,
2385  // 	}
2386  // 	e = walletdb.Update(
2387  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2388  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2389  // 			_, e := mgr.NewScopedKeyManager(ns, testScope, addrSchema)
2390  // 			if e != nil {
2391  // 				return e
2392  // 			}
2393  // 			return nil
2394  // 		},
2395  // 	)
2396  // 	if e == nil {
2397  // 		t.Fatalf("new scoped manager creation should have failed")
2398  // 	}
2399  // }
2400  
2401  // // TestNewRawAccount tests that callers are able to properly create, and use raw
2402  // // accounts created with only an account number, and not a string which is
2403  // // eventually mapped to an account number.
2404  // func TestNewRawAccount(t *testing.T) {
2405  // 	t.Parallel()
2406  // 	teardown, db := emptyDB(t)
2407  // 	defer teardown()
2408  // 	// We'll start the test by creating a new root manager that will be used for the
2409  // 	// duration of the test.
2410  // 	var mgr *waddrmgr.Manager
2411  // 	e := walletdb.Update(
2412  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2413  // 			ns, e := tx.CreateTopLevelBucket(waddrmgrNamespaceKey)
2414  // 			if e != nil {
2415  // 				return e
2416  // 			}
2417  // 			e = waddrmgr.Create(
2418  // 				ns, seed, pubPassphrase, privPassphrase,
2419  // 				&chaincfg.MainNetParams, fastScrypt, time.Time{},
2420  // 			)
2421  // 			if e != nil {
2422  // 				return e
2423  // 			}
2424  // 			mgr, e = waddrmgr.Open(
2425  // 				ns, pubPassphrase, &chaincfg.MainNetParams,
2426  // 			)
2427  // 			if e != nil {
2428  // 				return e
2429  // 			}
2430  // 			return mgr.Unlock(ns, privPassphrase)
2431  // 		},
2432  // 	)
2433  // 	if e != nil {
2434  // 		t.Fatalf("create/open: unexpected error: %v", e)
2435  // 	}
2436  // 	defer mgr.Close()
2437  // 	// Now that we have the manager created, we'll fetch one of the default scopes
2438  // 	// for usage within this test.
2439  // 	scopedMgr, e := mgr.FetchScopedKeyManager(waddrmgr.KeyScopeBIP0084)
2440  // 	if e != nil {
2441  // 		t.Fatalf("unable to fetch scope %v: %v", waddrmgr.KeyScopeBIP0084, e)
2442  // 	}
2443  // 	// With the scoped manager retrieved, we'll attempt to create a new raw account
2444  // 	// by number.
2445  // 	const accountNum = 1000
2446  // 	e = walletdb.Update(
2447  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2448  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2449  // 			return scopedMgr.NewRawAccount(ns, accountNum)
2450  // 		},
2451  // 	)
2452  // 	if e != nil {
2453  // 		t.Fatalf("unable to create new account: %v", e)
2454  // 	}
2455  // 	// With the account created, we should be able to derive new addresses from the
2456  // 	// account.
2457  // 	var accountAddrNext waddrmgr.ManagedAddress
2458  // 	e = walletdb.Update(
2459  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2460  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2461  // 			addrs, e := scopedMgr.NextExternalAddresses(
2462  // 				ns, accountNum, 1,
2463  // 			)
2464  // 			if e != nil {
2465  // 				return e
2466  // 			}
2467  // 			accountAddrNext = addrs[0]
2468  // 			return nil
2469  // 		},
2470  // 	)
2471  // 	if e != nil {
2472  // 		t.Fatalf("unable to create addr: %v", e)
2473  // 	}
2474  // 	// Additionally, we should be able to manually derive specific target keys.
2475  // 	var accountTargetAddr waddrmgr.ManagedAddress
2476  // 	e = walletdb.Update(
2477  // 		db, func(tx walletdb.ReadWriteTx) (e error) {
2478  // 			ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
2479  // 			keyPath := waddrmgr.DerivationPath{
2480  // 				Account: accountNum,
2481  // 				Branch:  0,
2482  // 				Index:   0,
2483  // 			}
2484  // 			accountTargetAddr, e = scopedMgr.DeriveFromKeyPath(
2485  // 				ns, keyPath,
2486  // 			)
2487  // 			return e
2488  // 		},
2489  // 	)
2490  // 	if e != nil {
2491  // 		t.Fatalf("unable to derive addr: %v", e)
2492  // 	}
2493  // 	// The two keys we just derived should match up perfectly.
2494  // 	if accountAddrNext.AddrType() != accountTargetAddr.AddrType() {
2495  // 		t.Fatalf(
2496  // 			"wrong addr type: %v vs %v",
2497  // 			accountAddrNext.AddrType(), accountTargetAddr.AddrType(),
2498  // 		)
2499  // 	}
2500  // 	if !bytes.Equal(accountAddrNext.AddrHash(), accountTargetAddr.AddrHash()) {
2501  // 		t.Fatalf(
2502  // 			"wrong pubkey hash: %x vs %x", accountAddrNext.AddrHash(),
2503  // 			accountTargetAddr.AddrHash(),
2504  // 		)
2505  // 	}
2506  // }
2507