scoped_manager.go raw

   1  package waddrmgr
   2  
   3  import (
   4  	"fmt"
   5  	"github.com/p9c/p9/pkg/btcaddr"
   6  	"github.com/p9c/p9/pkg/chaincfg"
   7  	"sync"
   8  
   9  	ec "github.com/p9c/p9/pkg/ecc"
  10  	"github.com/p9c/p9/pkg/util"
  11  	"github.com/p9c/p9/pkg/util/hdkeychain"
  12  	"github.com/p9c/p9/pkg/util/zero"
  13  	"github.com/p9c/p9/pkg/walletdb"
  14  )
  15  
  16  // DerivationPath represents a derivation path from a particular key manager's
  17  // scope.
  18  //
  19  // Each ScopedKeyManager starts key derivation from the end of their cointype
  20  // hardened key: m/purpose'/cointype'. The fields in this struct allow further
  21  // derivation to the next three child levels after the coin type key.
  22  //
  23  // This restriction is in the spriti of BIP0044 type derivation. We maintain a
  24  // degree of coherency with the standard, but allow arbitrary derivations beyond
  25  // the cointype key.
  26  //
  27  // The key derived using this path will be exactly:
  28  // m/purpose'/cointype'/account/branch/index, where purpose' and cointype' are
  29  // bound by the scope of a particular manager.
  30  type DerivationPath struct {
  31  	// Account is the account, or the first immediate child from the scoped
  32  	// manager's hardened coin type key.
  33  	Account uint32
  34  	// Branch is the branch to be derived from the account index above. For
  35  	// BIP0044-like derivation, this is either 0 (external) or 1 (internal).
  36  	// However, we allow this value to vary arbitrarily within its size range.
  37  	Branch uint32
  38  	// Index is the final child in the derivation path. This denotes the key index
  39  	// within as a child of the account and branch.
  40  	Index uint32
  41  }
  42  
  43  // KeyScope represents a restricted key scope from the primary root key within
  44  // the HD chain. From the root manager (m/) we can create a nearly arbitrary
  45  // number of ScopedKeyManagers of key derivation path: m/purpose'/cointype'.
  46  // These scoped managers can then me managed indecently, as they house the
  47  // encrypted cointype key and can derive any child keys from there on.
  48  type KeyScope struct {
  49  	// Purpose is the purpose of this key scope. This is the first child of the
  50  	// master HD key.
  51  	Purpose uint32
  52  	// Coin is a value that represents the particular coin which is the child of the
  53  	// purpose key. With this key, any accounts, or other children can be derived at
  54  	// all.
  55  	Coin uint32
  56  }
  57  
  58  // ScopedIndex is a tuple of KeyScope and child Index. This is used to compactly
  59  // identify a particular child key, when the account and branch can be inferred
  60  // from context.
  61  type ScopedIndex struct {
  62  	// Scope is the BIP44 account' used to derive the child key.
  63  	Scope KeyScope
  64  	// Index is the BIP44 address_index used to derive the child key.
  65  	Index uint32
  66  }
  67  
  68  // String returns a human readable version describing the keypath encapsulated
  69  // by the target key scope.
  70  func (k *KeyScope) String() string {
  71  	return fmt.Sprintf("m/%v'/%v'", k.Purpose, k.Coin)
  72  }
  73  
  74  // ScopeAddrSchema is the address schema of a particular KeyScope. This will be
  75  // persisted within the database, and will be consulted when deriving any keys
  76  // for a particular scope to know how to encode the public keys as addresses.
  77  type ScopeAddrSchema struct {
  78  	// ExternalAddrType is the address type for all keys within branch 0.
  79  	ExternalAddrType AddressType
  80  	// InternalAddrType is the address type for all keys within branch 1 (change addresses).
  81  	InternalAddrType AddressType
  82  }
  83  
  84  // // KeyScopeBIP0049Plus is the key scope of our modified BIP0049 derivation. We
  85  // // say this is BIP0049 "plus", as we'll actually use p2wkh change all change
  86  // // addresses.
  87  // KeyScopeBIP0049Plus = KeyScope{
  88  // 	Purpose: 49,
  89  // 	Coin:    0,
  90  // }
  91  // // KeyScopeBIP0084 is the key scope for BIP0084 derivation. BIP0084 will be used
  92  // // to derive all p2wkh addresses.
  93  // KeyScopeBIP0084 = KeyScope{
  94  // 	Purpose: 84,
  95  // 	Coin:    0,
  96  // }
  97  
  98  var (
  99  	// KeyScopeBIP0044 is the key scope for BIP0044 derivation. Legacy wallets will
 100  	// only be able to use this key scope, and no keys beyond it.
 101  	KeyScopeBIP0044 = KeyScope{
 102  		Purpose: 44,
 103  		Coin:    0,
 104  	}
 105  	// DefaultKeyScopes is the set of default key scopes that will be created by the
 106  	// root manager upon initial creation.
 107  	DefaultKeyScopes = []KeyScope{
 108  		// KeyScopeBIP0049Plus,
 109  		// KeyScopeBIP0084,
 110  		KeyScopeBIP0044,
 111  	}
 112  	// ScopeAddrMap is a map from the default key scopes to the scope address schema
 113  	// for each scope type. This will be consulted during the initial creation of
 114  	// the root key manager.
 115  	ScopeAddrMap = map[KeyScope]ScopeAddrSchema{
 116  		// KeyScopeBIP0049Plus: {
 117  		// 	ExternalAddrType: NestedWitnessPubKey,
 118  		// 	InternalAddrType: WitnessPubKey,
 119  		// },
 120  		// KeyScopeBIP0084: {
 121  		// 	ExternalAddrType: WitnessPubKey,
 122  		// 	InternalAddrType: WitnessPubKey,
 123  		// },
 124  		KeyScopeBIP0044: {
 125  			InternalAddrType: PubKeyHash,
 126  			ExternalAddrType: PubKeyHash,
 127  		},
 128  	}
 129  )
 130  
 131  // ScopedKeyManager is a sub key manager under the main root key manager. The
 132  // root key manager will handle the root HD key (m/), while each sub scoped key
 133  // manager will handle the cointype key for a particular key scope
 134  // (m/purpose'/cointype'). This abstraction allows higher-level applications
 135  // built upon the root key manager to perform their own arbitrary key
 136  // derivation, while still being protected under the encryption of the root key
 137  // manager.
 138  type ScopedKeyManager struct {
 139  	// scope is the scope of this key manager. We can only generate keys that are
 140  	// direct children of this scope.
 141  	scope KeyScope
 142  	// addrSchema is the address schema for this sub manager. This will be consulted
 143  	// when encoding addresses from derived keys.
 144  	addrSchema ScopeAddrSchema
 145  	// rootManager is a pointer to the root key manager. We'll maintain this as we
 146  	// need access to the crypto encryption keys before we can derive any new
 147  	// accounts of child keys of accounts.
 148  	rootManager *Manager
 149  	// addrs is a cached map of all the addresses that we currently manager.
 150  	addrs map[addrKey]ManagedAddress
 151  	// acctInfo houses information about accounts including what is needed to
 152  	// generate deterministic chained keys for each created account.
 153  	acctInfo map[uint32]*accountInfo
 154  	// deriveOnUnlock is a list of private keys which needs to be derived on the
 155  	// next unlock. This occurs when a public address is derived while the address
 156  	// manager is locked since it does not have access to the private extended key
 157  	// (hence nor the underlying private key) in order to encrypt it.
 158  	deriveOnUnlock []*unlockDeriveInfo
 159  	mtx            sync.RWMutex
 160  }
 161  
 162  // Scope returns the exact KeyScope of this scoped key manager.
 163  func (s *ScopedKeyManager) Scope() KeyScope {
 164  	return s.scope
 165  }
 166  
 167  // AddrSchema returns the set address schema for the target ScopedKeyManager.
 168  func (s *ScopedKeyManager) AddrSchema() ScopeAddrSchema {
 169  	return s.addrSchema
 170  }
 171  
 172  // zeroSensitivePublicData performs a best try effort to remove and zero all
 173  // sensitive public data associated with the address manager such as
 174  // hierarchical deterministic extended public keys and the crypto public keys.
 175  func (s *ScopedKeyManager) zeroSensitivePublicData() {
 176  	// Clear all of the account private keys.
 177  	for _, acctInfo := range s.acctInfo {
 178  		acctInfo.acctKeyPub.Zero()
 179  		acctInfo.acctKeyPub = nil
 180  	}
 181  }
 182  
 183  // Close cleanly shuts down the manager. It makes a best try effort to remove
 184  // and zero all private key and sensitive public key material associated with
 185  // the address manager from memory.
 186  func (s *ScopedKeyManager) Close() {
 187  	s.mtx.Lock()
 188  	defer s.mtx.Unlock()
 189  	// Attempt to clear sensitive public key material from memory too.
 190  	s.zeroSensitivePublicData()
 191  	// return
 192  }
 193  
 194  // keyToManaged returns a new managed address for the provided derived key and
 195  // its derivation path which consists of the account, branch, and index.
 196  //
 197  // The passed derivedKey is zeroed after the new address is created.
 198  //
 199  // This function MUST be called with the manager lock held for writes.
 200  func (s *ScopedKeyManager) keyToManaged(
 201  	derivedKey *hdkeychain.ExtendedKey,
 202  	account, branch, index uint32,
 203  ) (ManagedAddress, error) {
 204  	var addrType AddressType
 205  	if branch == InternalBranch {
 206  		addrType = s.addrSchema.InternalAddrType
 207  	} else {
 208  		addrType = s.addrSchema.ExternalAddrType
 209  	}
 210  	derivationPath := DerivationPath{
 211  		Account: account,
 212  		Branch:  branch,
 213  		Index:   index,
 214  	}
 215  	// Create a new managed address based on the public or private key depending on
 216  	// whether the passed key is private. Also, zero the key after creating the
 217  	// managed address from it.
 218  	ma, e := newManagedAddressFromExtKey(
 219  		s, derivationPath, derivedKey, addrType,
 220  	)
 221  	defer derivedKey.Zero()
 222  	if e != nil {
 223  		return nil, e
 224  	}
 225  	if !derivedKey.IsPrivate() {
 226  		// Add the managed address to the list of addresses that need their private keys
 227  		// derived when the address manager is next unlocked.
 228  		info := unlockDeriveInfo{
 229  			managedAddr: ma,
 230  			branch:      branch,
 231  			index:       index,
 232  		}
 233  		s.deriveOnUnlock = append(s.deriveOnUnlock, &info)
 234  	}
 235  	if branch == InternalBranch {
 236  		ma.internal = true
 237  	}
 238  	return ma, nil
 239  }
 240  
 241  // deriveKey returns either a public or private derived extended key based on
 242  // the private flag for the given an account info, branch, and index.
 243  func (s *ScopedKeyManager) deriveKey(
 244  	acctInfo *accountInfo, branch,
 245  	index uint32, private bool,
 246  ) (addressKey *hdkeychain.ExtendedKey, e error) {
 247  	// Choose the public or private extended key based on whether or not the private
 248  	// flag was specified. This, in turn, allows for public or private child
 249  	// derivation.
 250  	acctKey := acctInfo.acctKeyPub
 251  	if private {
 252  		acctKey = acctInfo.acctKeyPriv
 253  	}
 254  	// Derive and return the key.
 255  	var branchKey *hdkeychain.ExtendedKey
 256  	if branchKey, e = acctKey.Child(branch); E.Chk(e) {
 257  		str := fmt.Sprintf("failed to derive extended key branch %d", branch)
 258  		return nil, managerError(ErrKeyChain, str, e)
 259  	}
 260  	if addressKey, e = branchKey.Child(index); E.Chk(e) {
 261  		branchKey.Zero() // Zero branch key after it's used.
 262  		str := fmt.Sprintf("failed to derive child extended key -- branch %d, child %d", branch, index)
 263  		return nil, managerError(ErrKeyChain, str, e)
 264  	}
 265  	branchKey.Zero() // Zero branch key after it's used.
 266  	return
 267  }
 268  
 269  // loadAccountInfo attempts to load and cache information about the given
 270  // account from the database. This includes what is necessary to derive new keys
 271  // for it and track the state of the internal and external branches.
 272  //
 273  // This function MUST be called with the manager lock held for writes.
 274  func (s *ScopedKeyManager) loadAccountInfo(
 275  	ns walletdb.ReadBucket,
 276  	account uint32,
 277  ) (*accountInfo, error) {
 278  	// Return the account info from cache if it's available.
 279  	if acctInfo, ok := s.acctInfo[account]; ok {
 280  		return acctInfo, nil
 281  	}
 282  	// The account is either invalid or just wasn't cached, so attempt to load the
 283  	// information from the database.
 284  	var e error
 285  	var rowInterface interface{}
 286  	if rowInterface, e = fetchAccountInfo(ns, &s.scope, account); E.Chk(e) {
 287  		return nil, maybeConvertDbError(e)
 288  	}
 289  	// Ensure the account type is a default account.
 290  	ok := false
 291  	var row *dbDefaultAccountRow
 292  	if row, ok = rowInterface.(*dbDefaultAccountRow); !ok {
 293  		str := fmt.Sprintf("unsupported account type %T", row)
 294  		return nil, managerError(ErrDatabase, str, nil)
 295  	}
 296  	// Use the crypto public key to decrypt the account public extended key.
 297  	var serializedKeyPub []byte
 298  	if serializedKeyPub, e = s.rootManager.cryptoKeyPub.Decrypt(row.pubKeyEncrypted); E.Chk(e) {
 299  		str := fmt.Sprintf("failed to decrypt public key for account %d", account)
 300  		return nil, managerError(ErrCrypto, str, e)
 301  	}
 302  	var acctKeyPub *hdkeychain.ExtendedKey
 303  	if acctKeyPub, e = hdkeychain.NewKeyFromString(string(serializedKeyPub)); E.Chk(e) {
 304  		str := fmt.Sprintf("failed to create extended public key for account %d", account)
 305  		return nil, managerError(ErrKeyChain, str, e)
 306  	}
 307  	// Create the new account info with the known information. The rest of the
 308  	// fields are filled out below.
 309  	acctInfo := &accountInfo{
 310  		acctName:          row.name,
 311  		acctKeyEncrypted:  row.privKeyEncrypted,
 312  		acctKeyPub:        acctKeyPub,
 313  		nextExternalIndex: row.nextExternalIndex,
 314  		nextInternalIndex: row.nextInternalIndex,
 315  	}
 316  	if !s.rootManager.isLocked() {
 317  		// Use the crypto private key to decrypt the account private extended keys.
 318  		var decrypted []byte
 319  		if decrypted, e = s.rootManager.cryptoKeyPriv.Decrypt(acctInfo.acctKeyEncrypted); E.Chk(e) {
 320  			str := fmt.Sprintf("failed to decrypt private key for account %d", account)
 321  			return nil, managerError(ErrCrypto, str, e)
 322  		}
 323  		var acctKeyPriv *hdkeychain.ExtendedKey
 324  		if acctKeyPriv, e = hdkeychain.NewKeyFromString(string(decrypted)); E.Chk(e) {
 325  			str := fmt.Sprintf("failed to create extended private key for account %d", account)
 326  			return nil, managerError(ErrKeyChain, str, e)
 327  		}
 328  		acctInfo.acctKeyPriv = acctKeyPriv
 329  	}
 330  	// Derive and cache the managed address for the last external address.
 331  	branch, index := ExternalBranch, row.nextExternalIndex
 332  	if index > 0 {
 333  		index--
 334  	}
 335  	var lastExtKey *hdkeychain.ExtendedKey
 336  	if lastExtKey, e = s.deriveKey(acctInfo, branch, index, !s.rootManager.isLocked()); E.Chk(e) {
 337  		return nil, e
 338  	}
 339  	var lastExtAddr ManagedAddress
 340  	if lastExtAddr, e = s.keyToManaged(lastExtKey, account, branch, index); E.Chk(e) {
 341  		return nil, e
 342  	}
 343  	acctInfo.lastExternalAddr = lastExtAddr
 344  	// Derive and cache the managed address for the last internal address.
 345  	if branch, index = InternalBranch, row.nextInternalIndex; index > 0 {
 346  		index--
 347  	}
 348  	var lastIntKey *hdkeychain.ExtendedKey
 349  	if lastIntKey, e = s.deriveKey(acctInfo, branch, index, !s.rootManager.isLocked()); E.Chk(e) {
 350  		return nil, e
 351  	}
 352  	var lastIntAddr ManagedAddress
 353  	if lastIntAddr, e = s.keyToManaged(lastIntKey, account, branch, index); E.Chk(e) {
 354  		return nil, e
 355  	}
 356  	acctInfo.lastInternalAddr = lastIntAddr
 357  	// Add it to the cache and return it when everything is successful.
 358  	s.acctInfo[account] = acctInfo
 359  	return acctInfo, nil
 360  }
 361  
 362  // AccountProperties returns properties associated with the account, such as the
 363  // account number, name, and the number of derived and imported keys.
 364  func (s *ScopedKeyManager) AccountProperties(
 365  	ns walletdb.ReadBucket,
 366  	account uint32,
 367  ) (*AccountProperties, error) {
 368  	defer s.mtx.RUnlock()
 369  	s.mtx.RLock()
 370  	props := &AccountProperties{AccountNumber: account}
 371  	// Until keys can be imported into any account, special handling is required for
 372  	// the imported account.
 373  	//
 374  	// loadAccountInfo errors when using it on the imported account since the
 375  	// accountInfo struct is filled with a BIP0044 account's extended keys, and the
 376  	// imported accounts has none.
 377  	//
 378  	// Since only the imported account allows imports currently, the number of
 379  	// imported keys for any other account is zero, and since the imported account
 380  	// cannot contain non-imported keys, the external and internal key counts for it
 381  	// are zero.
 382  	var e error
 383  	if account != ImportedAddrAccount {
 384  		var acctInfo *accountInfo
 385  		if acctInfo, e = s.loadAccountInfo(ns, account); E.Chk(e) {
 386  			return nil, e
 387  		}
 388  		props.AccountName = acctInfo.acctName
 389  		props.ExternalKeyCount = acctInfo.nextExternalIndex
 390  		props.InternalKeyCount = acctInfo.nextInternalIndex
 391  	} else {
 392  		props.AccountName = ImportedAddrAccountName // reserved, nonchangable
 393  		// Could be more efficient if this was tracked by the db.
 394  		var importedKeyCount uint32
 395  		count := func(interface{}) (e error) {
 396  			importedKeyCount++
 397  			return nil
 398  		}
 399  		if e = forEachAccountAddress(ns, &s.scope, ImportedAddrAccount, count); E.Chk(e) {
 400  			return nil, e
 401  		}
 402  		props.ImportedKeyCount = importedKeyCount
 403  	}
 404  	return props, nil
 405  }
 406  
 407  // DeriveFromKeyPath attempts to derive a maximal child key (under the BIP0044
 408  // scheme) from a given key path. If key derivation isn't possible, then an
 409  // error will be returned.
 410  func (s *ScopedKeyManager) DeriveFromKeyPath(
 411  	ns walletdb.ReadBucket,
 412  	kp DerivationPath,
 413  ) (ManagedAddress, error) {
 414  	s.mtx.Lock()
 415  	defer s.mtx.Unlock()
 416  	var extKey *hdkeychain.ExtendedKey
 417  	var e error
 418  	if extKey, e = s.deriveKeyFromPath(
 419  		ns, kp.Account, kp.Branch, kp.Index, !s.rootManager.IsLocked(),
 420  	); E.Chk(e) {
 421  		return nil, e
 422  	}
 423  	return s.keyToManaged(extKey, kp.Account, kp.Branch, kp.Index)
 424  }
 425  
 426  // deriveKeyFromPath returns either a public or private derived extended key
 427  // based on the private flag for the given an account, branch, and index.
 428  //
 429  // This function MUST be called with the manager lock held for writes.
 430  func (s *ScopedKeyManager) deriveKeyFromPath(
 431  	ns walletdb.ReadBucket, account, branch,
 432  	index uint32, private bool,
 433  ) (*hdkeychain.ExtendedKey, error) {
 434  	// Look up the account key information.
 435  	var acctInfo *accountInfo
 436  	var e error
 437  	if acctInfo, e = s.loadAccountInfo(ns, account); E.Chk(e) {
 438  		return nil, e
 439  	}
 440  	return s.deriveKey(acctInfo, branch, index, private)
 441  }
 442  
 443  // chainAddressRowToManaged returns a new managed address based on chained
 444  // address data loaded from the database.
 445  //
 446  // This function MUST be called with the manager lock held for writes.
 447  func (s *ScopedKeyManager) chainAddressRowToManaged(
 448  	ns walletdb.ReadBucket,
 449  	row *dbChainAddressRow,
 450  ) (ManagedAddress, error) {
 451  	// Since the manger's mutex is assumed to held when invoking this function, we
 452  	// use the internal isLocked to avoid a deadlock.
 453  	isLocked := s.rootManager.isLocked()
 454  	var addressKey *hdkeychain.ExtendedKey
 455  	var e error
 456  	if addressKey, e = s.deriveKeyFromPath(ns, row.account, row.branch, row.index, !isLocked); E.Chk(e) {
 457  		return nil, e
 458  	}
 459  	return s.keyToManaged(addressKey, row.account, row.branch, row.index)
 460  }
 461  
 462  // importedAddressRowToManaged returns a new managed address based on imported
 463  // address data loaded from the database.
 464  func (s *ScopedKeyManager) importedAddressRowToManaged(row *dbImportedAddressRow) (ManagedAddress, error) {
 465  	// Use the crypto public key to decrypt the imported public key.
 466  	var pubBytes []byte
 467  	var e error
 468  	if pubBytes, e = s.rootManager.cryptoKeyPub.Decrypt(row.encryptedPubKey); E.Chk(e) {
 469  		str := "failed to decrypt public key for imported address"
 470  		return nil, managerError(ErrCrypto, str, e)
 471  	}
 472  	var pubKey *ec.PublicKey
 473  	if pubKey, e = ec.ParsePubKey(pubBytes, ec.S256()); E.Chk(e) {
 474  		str := "invalid public key for imported address"
 475  		return nil, managerError(ErrCrypto, str, e)
 476  	}
 477  	// Since this is an imported address, we won't populate the full derivation
 478  	// path, as we don't have enough information to do so.
 479  	derivationPath := DerivationPath{
 480  		Account: row.account,
 481  	}
 482  	compressed := len(pubBytes) == ec.PubKeyBytesLenCompressed
 483  	var ma *managedAddress
 484  	if ma, e = newManagedAddressWithoutPrivKey(
 485  		s, derivationPath, pubKey, compressed,
 486  		s.addrSchema.ExternalAddrType,
 487  	); E.Chk(e) {
 488  		return nil, e
 489  	}
 490  	ma.privKeyEncrypted = row.encryptedPrivKey
 491  	ma.imported = true
 492  	return ma, nil
 493  }
 494  
 495  // scriptAddressRowToManaged returns a new managed address based on script
 496  // address data loaded from the database.
 497  func (s *ScopedKeyManager) scriptAddressRowToManaged(row *dbScriptAddressRow) (ManagedAddress, error) {
 498  	// Use the crypto public key to decrypt the imported script hash.
 499  	var scriptHash []byte
 500  	var e error
 501  	if scriptHash, e = s.rootManager.cryptoKeyPub.Decrypt(row.encryptedHash); E.Chk(e) {
 502  		str := "failed to decrypt imported script hash"
 503  		return nil, managerError(ErrCrypto, str, e)
 504  	}
 505  	return newScriptAddress(s, row.account, scriptHash, row.encryptedScript)
 506  }
 507  
 508  // rowInterfaceToManaged returns a new managed address based on the given
 509  // address data loaded from the database. It will automatically select the
 510  // appropriate type.
 511  //
 512  // This function MUST be called with the manager lock held for writes.
 513  func (s *ScopedKeyManager) rowInterfaceToManaged(
 514  	ns walletdb.ReadBucket,
 515  	rowInterface interface{},
 516  ) (ManagedAddress, error) {
 517  	switch row := rowInterface.(type) {
 518  	case *dbChainAddressRow:
 519  		return s.chainAddressRowToManaged(ns, row)
 520  	case *dbImportedAddressRow:
 521  		return s.importedAddressRowToManaged(row)
 522  	case *dbScriptAddressRow:
 523  		return s.scriptAddressRowToManaged(row)
 524  	}
 525  	str := fmt.Sprintf("unsupported address type %T", rowInterface)
 526  	return nil, managerError(ErrDatabase, str, nil)
 527  }
 528  
 529  // loadAndCacheAddress attempts to load the passed address from the database and caches the associated managed address.
 530  //
 531  // This function MUST be called with the manager lock held for writes.
 532  func (s *ScopedKeyManager) loadAndCacheAddress(
 533  	ns walletdb.ReadBucket,
 534  	address btcaddr.Address,
 535  ) (ManagedAddress, error) {
 536  	// Attempt to load the raw address information from the database.
 537  	rowInterface, e := fetchAddress(ns, &s.scope, address.ScriptAddress())
 538  	if e != nil {
 539  		if merr, ok := e.(*ManagerError); ok {
 540  			desc := fmt.Sprintf(
 541  				"failed to fetch address '%s': %v",
 542  				address.ScriptAddress(), merr.Description,
 543  			)
 544  			merr.Description = desc
 545  			return nil, merr
 546  		}
 547  		return nil, maybeConvertDbError(e)
 548  	}
 549  	// Create a new managed address for the specific type of address based on type.
 550  	var managedAddr ManagedAddress
 551  	if managedAddr, e = s.rowInterfaceToManaged(ns, rowInterface); E.Chk(e) {
 552  		return nil, e
 553  	}
 554  	// Cache and return the new managed address.
 555  	s.addrs[addrKey(managedAddr.Address().ScriptAddress())] = managedAddr
 556  	return managedAddr, nil
 557  }
 558  
 559  // existsAddress returns whether or not the passed address is known to the
 560  // address manager.
 561  //
 562  // This function MUST be called with the manager lock held for reads.
 563  func (s *ScopedKeyManager) existsAddress(ns walletdb.ReadBucket, addressID []byte) bool {
 564  	// Chk the in-memory map first since it's faster than a db access.
 565  	if _, ok := s.addrs[addrKey(addressID)]; ok {
 566  		return true
 567  	}
 568  	// Chk the database if not already found above.
 569  	return existsAddress(ns, &s.scope, addressID)
 570  }
 571  
 572  // Address returns a managed address given the passed address if it is known to
 573  // the address manager. A managed address differs from the passed address in
 574  // that it also potentially contains extra information needed to sign
 575  // transactions such as the associated private key for pay-to-pubkey and
 576  // pay-to-pubkey-hash addresses and the script associated with
 577  // pay-to-script-hash addresses.
 578  func (s *ScopedKeyManager) Address(
 579  	ns walletdb.ReadBucket,
 580  	addr btcaddr.Address,
 581  ) (ma ManagedAddress, e error) {
 582  	// ScriptAddress will only return a script hash if we're accessing an address
 583  	// that is either PKH or SH. In the event we're passed a PK address, convert the
 584  	// PK to PKH address so that we can access it from the addrs map and database.
 585  	ok := false
 586  	var pka *btcaddr.PubKey
 587  	if pka, ok = addr.(*btcaddr.PubKey); ok {
 588  		addr = pka.PubKeyHash()
 589  	}
 590  	// Return the address from cache if it's available.
 591  	//
 592  	// NOTE: Not using a defer on the lock here since a write lock is needed if the
 593  	// lookup fails.
 594  	s.mtx.RLock()
 595  	if ma, ok = s.addrs[addrKey(addr.ScriptAddress())]; ok {
 596  		s.mtx.RUnlock()
 597  		return ma, nil
 598  	}
 599  	s.mtx.RUnlock()
 600  	s.mtx.Lock()
 601  	defer s.mtx.Unlock()
 602  	// Attempt to load the address from the database.
 603  	return s.loadAndCacheAddress(ns, addr)
 604  }
 605  
 606  // AddrAccount returns the account to which the given address belongs.
 607  func (s *ScopedKeyManager) AddrAccount(
 608  	ns walletdb.ReadBucket,
 609  	address btcaddr.Address,
 610  ) (account uint32, e error) {
 611  	if account, e = fetchAddrAccount(ns, &s.scope, address.ScriptAddress()); T.Chk(e) {
 612  		return 0, maybeConvertDbError(e)
 613  	}
 614  	return account, nil
 615  }
 616  
 617  // nextAddresses returns the specified number of next chained address from the
 618  // branch indicated by the internal flag.
 619  //
 620  // This function MUST be called with the manager lock held for writes.
 621  func (s *ScopedKeyManager) nextAddresses(
 622  	ns walletdb.ReadWriteBucket,
 623  	account uint32, numAddresses uint32, internal bool,
 624  ) ([]ManagedAddress, error) {
 625  	// The next address can only be generated for accounts that have already been
 626  	// created.
 627  	var acctInfo *accountInfo
 628  	var e error
 629  	if acctInfo, e = s.loadAccountInfo(ns, account); E.Chk(e) {
 630  		return nil, e
 631  	}
 632  	// Choose the account key to used based on whether the address manager is
 633  	// locked.
 634  	acctKey := acctInfo.acctKeyPub
 635  	if !s.rootManager.IsLocked() {
 636  		acctKey = acctInfo.acctKeyPriv
 637  	}
 638  	// Choose the branch key and index depending on whether or not this is an
 639  	// internal address.
 640  	branchNum, nextIndex := ExternalBranch, acctInfo.nextExternalIndex
 641  	if internal {
 642  		branchNum = InternalBranch
 643  		nextIndex = acctInfo.nextInternalIndex
 644  	}
 645  	addrType := s.addrSchema.ExternalAddrType
 646  	if internal {
 647  		addrType = s.addrSchema.InternalAddrType
 648  	}
 649  	// Ensure the requested number of addresses doesn't exceed the maximum allowed
 650  	// for this account.
 651  	if numAddresses > MaxAddressesPerAccount || nextIndex+numAddresses >
 652  		MaxAddressesPerAccount {
 653  		str := fmt.Sprintf(
 654  			"%d new addresses would exceed the maximum "+
 655  				"allowed number of addresses per account of %d",
 656  			numAddresses, MaxAddressesPerAccount,
 657  		)
 658  		return nil, managerError(ErrTooManyAddresses, str, nil)
 659  	}
 660  	// Derive the appropriate branch key and ensure it is zeroed when done.
 661  	var branchKey *hdkeychain.ExtendedKey
 662  	if branchKey, e = acctKey.Child(branchNum); E.Chk(e) {
 663  		str := fmt.Sprintf(
 664  			"failed to derive extended key branch %d",
 665  			branchNum,
 666  		)
 667  		return nil, managerError(ErrKeyChain, str, e)
 668  	}
 669  	defer branchKey.Zero() // Ensure branch key is zeroed when done.
 670  	// Create the requested number of addresses and keep track of the index with
 671  	// each one.
 672  	addressInfo := make([]*unlockDeriveInfo, 0, numAddresses)
 673  	for i := uint32(0); i < numAddresses; i++ {
 674  		// There is an extremely small chance that a particular child is invalid, so use
 675  		// a loop to derive the next valid child.
 676  		var nextKey *hdkeychain.ExtendedKey
 677  		for {
 678  			// Derive the next child in the external chain branch.
 679  			var key *hdkeychain.ExtendedKey
 680  			if key, e = branchKey.Child(nextIndex); E.Chk(e) {
 681  				// When this particular child is invalid, skip to the next index.
 682  				if e == hdkeychain.ErrInvalidChild {
 683  					nextIndex++
 684  					continue
 685  				}
 686  				str := fmt.Sprintf(
 687  					"failed to generate child %d",
 688  					nextIndex,
 689  				)
 690  				return nil, managerError(ErrKeyChain, str, e)
 691  			}
 692  			key.SetNet(s.rootManager.chainParams)
 693  			nextIndex++
 694  			nextKey = key
 695  			break
 696  		}
 697  		// Now that we know this key can be used, we'll create the proper derivation
 698  		// path so this information can be available to callers.
 699  		derivationPath := DerivationPath{
 700  			Account: account,
 701  			Branch:  branchNum,
 702  			Index:   nextIndex - 1,
 703  		}
 704  		// Create a new managed address based on the public or private key depending on
 705  		// whether the generated key is private. Also, zero the next key after creating
 706  		// the managed address from it.
 707  		var addr *managedAddress
 708  		if addr, e = newManagedAddressFromExtKey(s, derivationPath, nextKey, addrType); E.Chk(e) {
 709  			return nil, e
 710  		}
 711  		if internal {
 712  			addr.internal = true
 713  		}
 714  		managedAddr := addr
 715  		nextKey.Zero()
 716  		info := unlockDeriveInfo{
 717  			managedAddr: managedAddr,
 718  			branch:      branchNum,
 719  			index:       nextIndex - 1,
 720  		}
 721  		addressInfo = append(addressInfo, &info)
 722  	}
 723  	// Now that all addresses have been successfully generated, update the database
 724  	// in a single transaction.
 725  	for _, info := range addressInfo {
 726  		ma := info.managedAddr
 727  		addressID := ma.Address().ScriptAddress()
 728  		switch a := ma.(type) {
 729  		case *managedAddress:
 730  			if e = putChainedAddress(
 731  				ns, &s.scope, addressID, account, ssFull,
 732  				info.branch, info.index, adtChain,
 733  			); E.Chk(e) {
 734  				return nil, maybeConvertDbError(e)
 735  			}
 736  		case *scriptAddress:
 737  			var encryptedHash []byte
 738  			if encryptedHash, e = s.rootManager.cryptoKeyPub.Encrypt(a.AddrHash()); E.Chk(e) {
 739  				str := fmt.Sprintf("failed to encrypt script hash %x", a.AddrHash())
 740  				return nil, managerError(ErrCrypto, str, e)
 741  			}
 742  			if e = putScriptAddress(
 743  				ns, &s.scope, a.AddrHash(), ImportedAddrAccount, ssNone, encryptedHash,
 744  				a.scriptEncrypted,
 745  			); E.Chk(e) {
 746  				return nil, maybeConvertDbError(e)
 747  			}
 748  		}
 749  	}
 750  	// Finally update the next address tracking and add the addresses to the cache
 751  	// after the newly generated addresses have been successfully added to the db.
 752  	managedAddresses := make([]ManagedAddress, 0, len(addressInfo))
 753  	for _, info := range addressInfo {
 754  		ma := info.managedAddr
 755  		s.addrs[addrKey(ma.Address().ScriptAddress())] = ma
 756  		// Add the new managed address to the list of addresses that need their private
 757  		// keys derived when the address manager is next unlocked.
 758  		if s.rootManager.IsLocked() && !s.rootManager.WatchOnly() {
 759  			s.deriveOnUnlock = append(s.deriveOnUnlock, info)
 760  		}
 761  		managedAddresses = append(managedAddresses, ma)
 762  	}
 763  	// Set the last address and next address for tracking.
 764  	ma := addressInfo[len(addressInfo)-1].managedAddr
 765  	if internal {
 766  		acctInfo.nextInternalIndex = nextIndex
 767  		acctInfo.lastInternalAddr = ma
 768  	} else {
 769  		acctInfo.nextExternalIndex = nextIndex
 770  		acctInfo.lastExternalAddr = ma
 771  	}
 772  	return managedAddresses, nil
 773  }
 774  
 775  // extendAddresses ensures that all addresses up to and including the lastIndex
 776  // are derived for either an internal or external branch. If the child at
 777  // lastIndex is invalid, this method will proceed until the next valid child is
 778  // found. An error is returned if method failed to properly extend addresses up
 779  // to the requested index.
 780  //
 781  // This function MUST be called with the manager lock held for writes.
 782  func (s *ScopedKeyManager) extendAddresses(
 783  	ns walletdb.ReadWriteBucket,
 784  	account uint32, lastIndex uint32, internal bool,
 785  ) (e error) {
 786  	// The next address can only be generated for accounts that have already been
 787  	// created.
 788  	var acctInfo *accountInfo
 789  	if acctInfo, e = s.loadAccountInfo(ns, account); E.Chk(e) {
 790  		return e
 791  	}
 792  	// Choose the account key to used based on whether the address manager is
 793  	// locked.
 794  	acctKey := acctInfo.acctKeyPub
 795  	if !s.rootManager.IsLocked() {
 796  		acctKey = acctInfo.acctKeyPriv
 797  	}
 798  	// Choose the branch key and index depending on whether or not this is an
 799  	// internal address.
 800  	branchNum, nextIndex := ExternalBranch, acctInfo.nextExternalIndex
 801  	if internal {
 802  		branchNum = InternalBranch
 803  		nextIndex = acctInfo.nextInternalIndex
 804  	}
 805  	addrType := s.addrSchema.ExternalAddrType
 806  	if internal {
 807  		addrType = s.addrSchema.InternalAddrType
 808  	}
 809  	// If the last index requested is already lower than the next index, we can
 810  	// return early.
 811  	if lastIndex < nextIndex {
 812  		return nil
 813  	}
 814  	// Ensure the requested number of addresses doesn't exceed the maximum allowed
 815  	// for this account.
 816  	if lastIndex > MaxAddressesPerAccount {
 817  		str := fmt.Sprintf(
 818  			"last index %d would exceed the maximum "+
 819  				"allowed number of addresses per account of %d",
 820  			lastIndex, MaxAddressesPerAccount,
 821  		)
 822  		return managerError(ErrTooManyAddresses, str, nil)
 823  	}
 824  	// Derive the appropriate branch key and ensure it is zeroed when done.
 825  	var branchKey *hdkeychain.ExtendedKey
 826  	if branchKey, e = acctKey.Child(branchNum); E.Chk(e) {
 827  		str := fmt.Sprintf("failed to derive extended key branch %d", branchNum)
 828  		return managerError(ErrKeyChain, str, e)
 829  	}
 830  	defer branchKey.Zero() // Ensure branch key is zeroed when done.
 831  	// Starting from this branch's nextIndex, derive all child indexes up to and
 832  	// including the requested lastIndex. If a invalid child is detected, this loop
 833  	// will continue deriving until it finds the next subsequent index.
 834  	addressInfo := make([]*unlockDeriveInfo, 0, lastIndex-nextIndex)
 835  	for nextIndex <= lastIndex {
 836  		// There is an extremely small chance that a particular child is invalid, so use
 837  		// a loop to derive the next valid child.
 838  		var nextKey *hdkeychain.ExtendedKey
 839  		for {
 840  			// Derive the next child in the external chain branch.
 841  			var key *hdkeychain.ExtendedKey
 842  			if key, e = branchKey.Child(nextIndex); E.Chk(e) {
 843  				// When this particular child is invalid, skip to the next index.
 844  				if e == hdkeychain.ErrInvalidChild {
 845  					nextIndex++
 846  					continue
 847  				}
 848  				str := fmt.Sprintf(
 849  					"failed to generate child %d",
 850  					nextIndex,
 851  				)
 852  				return managerError(ErrKeyChain, str, e)
 853  			}
 854  			key.SetNet(s.rootManager.chainParams)
 855  			nextIndex++
 856  			nextKey = key
 857  			break
 858  		}
 859  		// Now that we know this key can be used, we'll create the proper derivation
 860  		// path so this information can be available to callers.
 861  		derivationPath := DerivationPath{
 862  			Account: account,
 863  			Branch:  branchNum,
 864  			Index:   nextIndex - 1,
 865  		}
 866  		// Create a new managed address based on the public or private key depending on
 867  		// whether the generated key is private. Also, zero the next key after creating
 868  		// the managed address from it.
 869  		var managedAddr *managedAddress
 870  		if managedAddr, e = newManagedAddressFromExtKey(s, derivationPath, nextKey, addrType); E.Chk(e) {
 871  			return e
 872  		}
 873  		if internal {
 874  			managedAddr.internal = true
 875  		}
 876  		nextKey.Zero()
 877  		info := unlockDeriveInfo{
 878  			managedAddr: managedAddr,
 879  			branch:      branchNum,
 880  			index:       nextIndex - 1,
 881  		}
 882  		addressInfo = append(addressInfo, &info)
 883  	}
 884  	// Now that all addresses have been successfully generated, update the database
 885  	// in a single transaction.
 886  	for _, info := range addressInfo {
 887  		ma := info.managedAddr
 888  		addressID := ma.Address().ScriptAddress()
 889  		switch a := ma.(type) {
 890  		case *managedAddress:
 891  			if e = putChainedAddress(
 892  				ns, &s.scope, addressID, account, ssFull,
 893  				info.branch, info.index, adtChain,
 894  			); E.Chk(e) {
 895  				return maybeConvertDbError(e)
 896  			}
 897  		case *scriptAddress:
 898  			var encryptedHash []byte
 899  			if encryptedHash, e = s.rootManager.cryptoKeyPub.Encrypt(a.AddrHash()); E.Chk(e) {
 900  				str := fmt.Sprintf(
 901  					"failed to encrypt script hash %x",
 902  					a.AddrHash(),
 903  				)
 904  				return managerError(ErrCrypto, str, e)
 905  			}
 906  			if e = putScriptAddress(
 907  				ns, &s.scope, a.AddrHash(), ImportedAddrAccount,
 908  				ssNone, encryptedHash, a.scriptEncrypted,
 909  			); E.Chk(e) {
 910  				return maybeConvertDbError(e)
 911  			}
 912  		}
 913  	}
 914  	// Finally update the next address tracking and add the addresses to the cache
 915  	// after the newly generated addresses have been successfully added to the db.
 916  	for _, info := range addressInfo {
 917  		ma := info.managedAddr
 918  		s.addrs[addrKey(ma.Address().ScriptAddress())] = ma
 919  		// Add the new managed address to the list of addresses that need their private
 920  		// keys derived when the address manager is next unlocked.
 921  		if s.rootManager.IsLocked() && !s.rootManager.WatchOnly() {
 922  			s.deriveOnUnlock = append(s.deriveOnUnlock, info)
 923  		}
 924  	}
 925  	// Set the last address and next address for tracking.
 926  	ma := addressInfo[len(addressInfo)-1].managedAddr
 927  	if internal {
 928  		acctInfo.nextInternalIndex = nextIndex
 929  		acctInfo.lastInternalAddr = ma
 930  	} else {
 931  		acctInfo.nextExternalIndex = nextIndex
 932  		acctInfo.lastExternalAddr = ma
 933  	}
 934  	return nil
 935  }
 936  
 937  // NextExternalAddresses returns the specified number of next chained addresses
 938  // that are intended for external use from the address manager.
 939  func (s *ScopedKeyManager) NextExternalAddresses(
 940  	ns walletdb.ReadWriteBucket,
 941  	account uint32, numAddresses uint32,
 942  ) (ma []ManagedAddress, e error) {
 943  	// Enforce maximum account number.
 944  	if account > MaxAccountNum {
 945  		if e = managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil); E.Chk(e) {
 946  		}
 947  		return nil, e
 948  	}
 949  	s.mtx.Lock()
 950  	defer s.mtx.Unlock()
 951  	return s.nextAddresses(ns, account, numAddresses, false)
 952  }
 953  
 954  // NextInternalAddresses returns the specified number of next chained addresses
 955  // that are intended for internal use such as change from the address manager.
 956  func (s *ScopedKeyManager) NextInternalAddresses(
 957  	ns walletdb.ReadWriteBucket,
 958  	account uint32, numAddresses uint32,
 959  ) (ma []ManagedAddress, e error) {
 960  	// Enforce maximum account number.
 961  	if account > MaxAccountNum {
 962  		if e = managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil); E.Chk(e) {
 963  		}
 964  		return nil, e
 965  	}
 966  	s.mtx.Lock()
 967  	defer s.mtx.Unlock()
 968  	return s.nextAddresses(ns, account, numAddresses, true)
 969  }
 970  
 971  // ExtendExternalAddresses ensures that all valid external keys through
 972  // lastIndex are derived and stored in the wallet. This is used to ensure that
 973  // wallet's persistent state catches up to a external child that was found
 974  // during recovery.
 975  func (s *ScopedKeyManager) ExtendExternalAddresses(
 976  	ns walletdb.ReadWriteBucket,
 977  	account uint32, lastIndex uint32,
 978  ) (e error) {
 979  	if account > MaxAccountNum {
 980  		if e = managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil); E.Chk(e) {
 981  		}
 982  		return e
 983  	}
 984  	s.mtx.Lock()
 985  	defer s.mtx.Unlock()
 986  	return s.extendAddresses(ns, account, lastIndex, false)
 987  }
 988  
 989  // ExtendInternalAddresses ensures that all valid internal keys through
 990  // lastIndex are derived and stored in the wallet. This is used to ensure that
 991  // wallet's persistent state catches up to an internal child that was found
 992  // during recovery.
 993  func (s *ScopedKeyManager) ExtendInternalAddresses(
 994  	ns walletdb.ReadWriteBucket,
 995  	account uint32, lastIndex uint32,
 996  ) (e error) {
 997  	if account > MaxAccountNum {
 998  		e = managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil)
 999  		return e
1000  	}
1001  	s.mtx.Lock()
1002  	defer s.mtx.Unlock()
1003  	return s.extendAddresses(ns, account, lastIndex, true)
1004  }
1005  
1006  // LastExternalAddress returns the most recently requested chained external
1007  // address from calling NextExternalAddress for the given account. The first
1008  // external address for the account will be returned if none have been
1009  // previously requested.
1010  //
1011  // This function will return an error if the provided account number is greater
1012  // than the MaxAccountNum constant or there is no account information for the
1013  // passed account. Any other errors returned are generally unexpected.
1014  func (s *ScopedKeyManager) LastExternalAddress(
1015  	ns walletdb.ReadBucket,
1016  	account uint32,
1017  ) (ManagedAddress, error) {
1018  	// Enforce maximum account number.
1019  	if account > MaxAccountNum {
1020  		return nil, managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil)
1021  	}
1022  	s.mtx.Lock()
1023  	defer s.mtx.Unlock()
1024  	// Load account information for the passed account. It is typically cached, but
1025  	// if not it will be loaded from the database.
1026  	var e error
1027  	var acctInfo *accountInfo
1028  	if acctInfo, e = s.loadAccountInfo(ns, account); E.Chk(e) {
1029  		return nil, e
1030  	}
1031  	if acctInfo.nextExternalIndex > 0 {
1032  		return acctInfo.lastExternalAddr, nil
1033  	}
1034  	return nil, managerError(ErrAddressNotFound, "no previous external address", nil)
1035  }
1036  
1037  // LastInternalAddress returns the most recently requested chained internal
1038  // address from calling NextInternalAddress for the given account. The first
1039  // internal address for the account will be returned if none have been
1040  // previously requested.
1041  //
1042  // This function will return an error if the provided account number is greater
1043  // than the MaxAccountNum constant or there is no account information for the
1044  // passed account. Any other errors returned are generally unexpected.
1045  func (s *ScopedKeyManager) LastInternalAddress(
1046  	ns walletdb.ReadBucket,
1047  	account uint32,
1048  ) (ManagedAddress, error) {
1049  	// Enforce maximum account number.
1050  	if account > MaxAccountNum {
1051  		e := managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil)
1052  		return nil, e
1053  	}
1054  	s.mtx.Lock()
1055  	defer s.mtx.Unlock()
1056  	// Load account information for the passed account. It is typically cached, but
1057  	// if not it will be loaded from the database.
1058  	var acctInfo *accountInfo
1059  	var e error
1060  	if acctInfo, e = s.loadAccountInfo(ns, account); E.Chk(e) {
1061  		return nil, e
1062  	}
1063  	if acctInfo.nextInternalIndex > 0 {
1064  		return acctInfo.lastInternalAddr, nil
1065  	}
1066  	return nil, managerError(ErrAddressNotFound, "no previous internal address", nil)
1067  }
1068  
1069  // NewRawAccount creates a new account for the scoped manager. This method
1070  // differs from the NewAccount method in that this method takes the acount
1071  // number *directly*, rather than taking a string name for the account, then
1072  // mapping that to the next highest account number.
1073  func (s *ScopedKeyManager) NewRawAccount(ns walletdb.ReadWriteBucket, number uint32) (e error) {
1074  	if s.rootManager.WatchOnly() {
1075  		return managerError(ErrWatchingOnly, errWatchingOnly, nil)
1076  	}
1077  	s.mtx.Lock()
1078  	defer s.mtx.Unlock()
1079  	if s.rootManager.IsLocked() {
1080  		return managerError(ErrLocked, errLocked, nil)
1081  	}
1082  	// As this is an ad hoc account that may not follow our normal linear
1083  	// derivation, we'll create a new name for this account based off of the account
1084  	// number.
1085  	name := fmt.Sprintf("act:%v", number)
1086  	return s.newAccount(ns, number, name)
1087  }
1088  
1089  // NewAccount creates and returns a new account stored in the manager based on
1090  // the given account name. If an account with the same name already exists,
1091  // ErrDuplicateAccount will be returned. Since creating a new account requires
1092  // access to the cointype keys (from which extended account keys are derived),
1093  // it requires the manager to be unlocked.
1094  func (s *ScopedKeyManager) NewAccount(ns walletdb.ReadWriteBucket, name string) (account uint32, e error) {
1095  	if s.rootManager.WatchOnly() {
1096  		return 0, managerError(ErrWatchingOnly, errWatchingOnly, nil)
1097  	}
1098  	s.mtx.Lock()
1099  	defer s.mtx.Unlock()
1100  	if s.rootManager.IsLocked() {
1101  		return 0, managerError(ErrLocked, errLocked, nil)
1102  	}
1103  	// Fetch latest account, and create a new account in the same transaction Fetch
1104  	// the latest account number to generate the next account number
1105  	if account, e = fetchLastAccount(ns, &s.scope); E.Chk(e) {
1106  		return 0, e
1107  	}
1108  	account++
1109  	// With the name validated, we'll create a new account for the new contiguous account.
1110  	if e := s.newAccount(ns, account, name); E.Chk(e) {
1111  		return 0, e
1112  	}
1113  	return account, nil
1114  }
1115  
1116  // newAccount is a helper function that derives a new precise account number,
1117  // and creates a mapping from the passed name to the account number in the
1118  // database.
1119  //
1120  // NOTE: This function MUST be called with the manager lock held for writes.
1121  func (s *ScopedKeyManager) newAccount(
1122  	ns walletdb.ReadWriteBucket,
1123  	account uint32, name string,
1124  ) (e error) {
1125  	// Validate the account name.
1126  	if e = ValidateAccountName(name); E.Chk(e) {
1127  		return e
1128  	}
1129  	// Chk that account with the same name does not exist
1130  	if _, e = s.lookupAccount(ns, name); E.Chk(e) {
1131  		str := fmt.Sprintf("account with the same name already exists")
1132  		return managerError(ErrDuplicateAccount, str, e)
1133  	}
1134  	// Fetch the cointype key which will be used to derive the next account extended
1135  	// keys
1136  	var coinTypePrivEnc []byte
1137  	if _, coinTypePrivEnc, e = fetchCoinTypeKeys(ns, &s.scope); E.Chk(e) {
1138  		return e
1139  	}
1140  	// Decrypt the cointype key.
1141  	var serializedKeyPriv []byte
1142  	if serializedKeyPriv, e = s.rootManager.cryptoKeyPriv.Decrypt(coinTypePrivEnc); E.Chk(e) {
1143  		str := fmt.Sprintf("failed to decrypt cointype serialized private key")
1144  		return managerError(ErrLocked, str, e)
1145  	}
1146  	var coinTypeKeyPriv *hdkeychain.ExtendedKey
1147  	if coinTypeKeyPriv, e = hdkeychain.NewKeyFromString(string(serializedKeyPriv)); E.Chk(e) {
1148  		zero.Bytes(serializedKeyPriv)
1149  		str := fmt.Sprintf("failed to create cointype extended private key")
1150  		return managerError(ErrKeyChain, str, e)
1151  	}
1152  	zero.Bytes(serializedKeyPriv)
1153  	// Derive the account key using the cointype key
1154  	var acctKeyPriv *hdkeychain.ExtendedKey
1155  	if acctKeyPriv, e = deriveAccountKey(coinTypeKeyPriv, account); E.Chk(e) {
1156  		coinTypeKeyPriv.Zero()
1157  		str := "failed to convert private key for account"
1158  		return managerError(ErrKeyChain, str, e)
1159  	}
1160  	coinTypeKeyPriv.Zero()
1161  	var acctKeyPub *hdkeychain.ExtendedKey
1162  	if acctKeyPub, e = acctKeyPriv.Neuter(); E.Chk(e) {
1163  		str := "failed to convert public key for account"
1164  		return managerError(ErrKeyChain, str, e)
1165  	}
1166  	// Encrypt the default account keys with the associated crypto keys.
1167  	var acctPubEnc []byte
1168  	if acctPubEnc, e = s.rootManager.cryptoKeyPub.Encrypt([]byte(acctKeyPub.String())); E.Chk(e) {
1169  		str := "failed to  encrypt public key for account"
1170  		return managerError(ErrCrypto, str, e)
1171  	}
1172  	var acctPrivEnc []byte
1173  	if acctPrivEnc, e = s.rootManager.cryptoKeyPriv.Encrypt([]byte(acctKeyPriv.String())); E.Chk(e) {
1174  		str := "failed to encrypt private key for account"
1175  		return managerError(ErrCrypto, str, e)
1176  	}
1177  	// We have the encrypted account extended keys, so save them to the database
1178  	if e = putAccountInfo(ns, &s.scope, account, acctPubEnc, acctPrivEnc, 0, 0, name); E.Chk(e) {
1179  		return e
1180  	}
1181  	// Save last account metadata
1182  	return putLastAccount(ns, &s.scope, account)
1183  }
1184  
1185  // RenameAccount renames an account stored in the manager based on the given
1186  // account number with the given name. If an account with the same name already
1187  // exists, ErrDuplicateAccount will be returned.
1188  func (s *ScopedKeyManager) RenameAccount(
1189  	ns walletdb.ReadWriteBucket,
1190  	account uint32, name string,
1191  ) (e error) {
1192  	s.mtx.Lock()
1193  	defer s.mtx.Unlock()
1194  	// Ensure that a reserved account is not being renamed.
1195  	if isReservedAccountNum(account) {
1196  		str := "reserved account cannot be renamed"
1197  		return managerError(ErrInvalidAccount, str, nil)
1198  	}
1199  	// Chk that account with the new name does not exist
1200  	_, e = s.lookupAccount(ns, name)
1201  	if e == nil {
1202  		str := fmt.Sprintf("account with the same name already exists")
1203  		return managerError(ErrDuplicateAccount, str, e)
1204  	}
1205  	// Validate account name
1206  	if e = ValidateAccountName(name); E.Chk(e) {
1207  		return e
1208  	}
1209  	var rowInterface interface{}
1210  	if rowInterface, e = fetchAccountInfo(ns, &s.scope, account); E.Chk(e) {
1211  		return e
1212  	}
1213  	// Ensure the account type is a default account.
1214  	var row *dbDefaultAccountRow
1215  	ok := false
1216  	if row, ok = rowInterface.(*dbDefaultAccountRow); !ok {
1217  		str := fmt.Sprintf("unsupported account type %T", row)
1218  		return managerError(ErrDatabase, str, nil)
1219  	}
1220  	// Remove the old name key from the account id index.
1221  	if e = deleteAccountIDIndex(ns, &s.scope, account); E.Chk(e) {
1222  		return e
1223  	}
1224  	// Remove the old name key from the account name index.
1225  	if e = deleteAccountNameIndex(ns, &s.scope, row.name); E.Chk(e) {
1226  		return e
1227  	}
1228  	if e = putAccountInfo(
1229  		ns, &s.scope, account, row.pubKeyEncrypted,
1230  		row.privKeyEncrypted, row.nextExternalIndex,
1231  		row.nextInternalIndex, name,
1232  	); E.Chk(e) {
1233  		return e
1234  	}
1235  	// Update in-memory account info with new name if cached and the db write was
1236  	// successful.
1237  	if acctInfo, ok := s.acctInfo[account]; ok {
1238  		acctInfo.acctName = name
1239  	}
1240  	return e
1241  }
1242  
1243  // ImportPrivateKey imports a WIF private key into the address manager. The
1244  // imported address is created using either a compressed or uncompressed
1245  // serialized public key, depending on the CompressPubKey bool of the WIF.
1246  //
1247  // All imported addresses will be part of the account defined by the
1248  // ImportedAddrAccount constant.
1249  //
1250  // NOTE: When the address manager is watching-only, the private key itself will
1251  // not be stored or available since it is private data. Instead, only the public
1252  // key will be stored. This means it is paramount the private key is kept
1253  // elsewhere as the watching-only address manager will NOT ever have access to
1254  // it.
1255  //
1256  // This function will return an error if the address manager is locked and not
1257  // watching-only, or not for the same network as the key trying to be imported.
1258  // It will also return an error if the address already exists. Any other errors
1259  // returned are generally unexpected.
1260  func (s *ScopedKeyManager) ImportPrivateKey(
1261  	ns walletdb.ReadWriteBucket,
1262  	wif *util.WIF, bs *BlockStamp,
1263  ) (ManagedPubKeyAddress, error) {
1264  	// Ensure the address is intended for network the address manager is associated
1265  	// with.
1266  	if !wif.IsForNet(s.rootManager.chainParams) {
1267  		str := fmt.Sprintf(
1268  			"private key is not for the same network the "+
1269  				"address manager is configured for (%s)",
1270  			s.rootManager.chainParams.Name,
1271  		)
1272  		return nil, managerError(ErrWrongNet, str, nil)
1273  	}
1274  	s.mtx.Lock()
1275  	defer s.mtx.Unlock()
1276  	// The manager must be unlocked to encrypt the imported private key.
1277  	if s.rootManager.IsLocked() && !s.rootManager.WatchOnly() {
1278  		return nil, managerError(ErrLocked, errLocked, nil)
1279  	}
1280  	// Prevent duplicates.
1281  	serializedPubKey := wif.SerializePubKey()
1282  	pubKeyHash := btcaddr.Hash160(serializedPubKey)
1283  	alreadyExists := s.existsAddress(ns, pubKeyHash)
1284  	if alreadyExists {
1285  		str := fmt.Sprintf("address for public key %x already exists", serializedPubKey)
1286  		return nil, managerError(ErrDuplicateAddress, str, nil)
1287  	}
1288  	// Encrypt public key.
1289  	var encryptedPubKey []byte
1290  	var e error
1291  	if encryptedPubKey, e = s.rootManager.cryptoKeyPub.Encrypt(serializedPubKey); E.Chk(e) {
1292  		str := fmt.Sprintf("failed to encrypt public key for %x", serializedPubKey)
1293  		return nil, managerError(ErrCrypto, str, e)
1294  	}
1295  	// Encrypt the private key when not a watching-only address manager.
1296  	var encryptedPrivKey []byte
1297  	if !s.rootManager.WatchOnly() {
1298  		privKeyBytes := wif.PrivKey.Serialize()
1299  		if encryptedPrivKey, e = s.rootManager.cryptoKeyPriv.Encrypt(privKeyBytes); E.Chk(e) {
1300  			zero.Bytes(privKeyBytes)
1301  			str := fmt.Sprintf("failed to encrypt private key for %x", serializedPubKey)
1302  			return nil, managerError(ErrCrypto, str, e)
1303  		}
1304  	}
1305  	// The start block needs to be updated when the newly imported address is before
1306  	// the current one.
1307  	s.rootManager.mtx.Lock()
1308  	updateStartBlock := bs.Height < s.rootManager.syncState.startBlock.Height
1309  	s.rootManager.mtx.Unlock()
1310  	// Save the new imported address to the db and update start block (if needed) in
1311  	// a single transaction.
1312  	if e = putImportedAddress(
1313  		ns, &s.scope, pubKeyHash, ImportedAddrAccount, ssNone,
1314  		encryptedPubKey, encryptedPrivKey,
1315  	); E.Chk(e) {
1316  		return nil, e
1317  	}
1318  	if updateStartBlock {
1319  		if e = putStartBlock(ns, bs); E.Chk(e) {
1320  			return nil, e
1321  		}
1322  	}
1323  	// Now that the database has been updated, update the start block in memory too
1324  	// if needed.
1325  	if updateStartBlock {
1326  		s.rootManager.mtx.Lock()
1327  		s.rootManager.syncState.startBlock = *bs
1328  		s.rootManager.mtx.Unlock()
1329  	}
1330  	// The full derivation path for an imported key is incomplete as we don't know
1331  	// exactly how it was derived.
1332  	importedDerivationPath := DerivationPath{Account: ImportedAddrAccount}
1333  	// Create a new managed address based on the imported address.
1334  	var managedAddr *managedAddress
1335  	if !s.rootManager.WatchOnly() {
1336  		managedAddr, e = newManagedAddress(
1337  			s, importedDerivationPath, wif.PrivKey,
1338  			wif.CompressPubKey, s.addrSchema.ExternalAddrType,
1339  		)
1340  	} else {
1341  		pubKey := (*ec.PublicKey)(&wif.PrivKey.PublicKey)
1342  		managedAddr, e = newManagedAddressWithoutPrivKey(
1343  			s, importedDerivationPath, pubKey, wif.CompressPubKey,
1344  			s.addrSchema.ExternalAddrType,
1345  		)
1346  	}
1347  	if E.Chk(e) {
1348  		return nil, e
1349  	}
1350  	managedAddr.imported = true
1351  	// Add the new managed address to the cache of recent addresses and return it.
1352  	s.addrs[addrKey(managedAddr.Address().ScriptAddress())] = managedAddr
1353  	return managedAddr, nil
1354  }
1355  
1356  // ImportScript imports a user-provided script into the address manager. The
1357  // imported script will act as a pay-to-script-hash address.
1358  //
1359  // All imported script addresses will be part of the account defined by the
1360  // ImportedAddrAccount constant.
1361  //
1362  // When the address manager is watching-only, the script itself will not be
1363  // stored or available since it is considered private data.
1364  //
1365  // This function will return an error if the address manager is locked and not
1366  // watching-only, or the address already exists. Any other errors returned are
1367  // generally unexpected.
1368  func (s *ScopedKeyManager) ImportScript(
1369  	ns walletdb.ReadWriteBucket,
1370  	script []byte, bs *BlockStamp,
1371  ) (ManagedScriptAddress, error) {
1372  	s.mtx.Lock()
1373  	defer s.mtx.Unlock()
1374  	// The manager must be unlocked to encrypt the imported script.
1375  	if s.rootManager.IsLocked() && !s.rootManager.WatchOnly() {
1376  		return nil, managerError(ErrLocked, errLocked, nil)
1377  	}
1378  	// Prevent duplicates.
1379  	scriptHash := btcaddr.Hash160(script)
1380  	alreadyExists := s.existsAddress(ns, scriptHash)
1381  	if alreadyExists {
1382  		str := fmt.Sprintf(
1383  			"address for script hash %x already exists",
1384  			scriptHash,
1385  		)
1386  		return nil, managerError(ErrDuplicateAddress, str, nil)
1387  	}
1388  	// Encrypt the script hash using the crypto public key so it is accessible when
1389  	// the address manager is locked or watching-only.
1390  	var encryptedHash []byte
1391  	var e error
1392  	if encryptedHash, e = s.rootManager.cryptoKeyPub.Encrypt(scriptHash); E.Chk(e) {
1393  		str := fmt.Sprintf("failed to encrypt script hash %x", scriptHash)
1394  		return nil, managerError(ErrCrypto, str, e)
1395  	}
1396  	// Encrypt the script for storage in database using the crypto script key when
1397  	// not a watching-only address manager.
1398  	var encryptedScript []byte
1399  	if !s.rootManager.WatchOnly() {
1400  		if encryptedScript, e = s.rootManager.cryptoKeyScript.Encrypt(
1401  			script,
1402  		); E.Chk(e) {
1403  			str := fmt.Sprintf("failed to encrypt script for %x", scriptHash)
1404  			return nil, managerError(ErrCrypto, str, e)
1405  		}
1406  	}
1407  	// The start block needs to be updated when the newly imported address is before
1408  	// the current one.
1409  	updateStartBlock := false
1410  	s.rootManager.mtx.Lock()
1411  	if bs.Height < s.rootManager.syncState.startBlock.Height {
1412  		updateStartBlock = true
1413  	}
1414  	s.rootManager.mtx.Unlock()
1415  	// Save the new imported address to the db and update start block (if needed) in
1416  	// a single transaction.
1417  	if e = putScriptAddress(
1418  		ns, &s.scope, scriptHash, ImportedAddrAccount, ssNone,
1419  		encryptedHash, encryptedScript,
1420  	); E.Chk(e) {
1421  		return nil, maybeConvertDbError(e)
1422  	}
1423  	if updateStartBlock {
1424  		if e = putStartBlock(ns, bs); E.Chk(e) {
1425  			return nil, maybeConvertDbError(e)
1426  		}
1427  	}
1428  	// Now that the database has been updated, update the start block in memory too
1429  	// if needed.
1430  	if updateStartBlock {
1431  		s.rootManager.mtx.Lock()
1432  		s.rootManager.syncState.startBlock = *bs
1433  		s.rootManager.mtx.Unlock()
1434  	}
1435  	// Create a new managed address based on the imported script. Also, when not a
1436  	// watching-only address manager, make a copy of the script since it will be
1437  	// cleared on lock and the script the caller passed should not be cleared out
1438  	// from under the caller.
1439  	var scriptAddr *scriptAddress
1440  	if scriptAddr, e = newScriptAddress(s, ImportedAddrAccount, scriptHash, encryptedScript); E.Chk(e) {
1441  		return nil, e
1442  	}
1443  	if !s.rootManager.WatchOnly() {
1444  		scriptAddr.scriptCT = make([]byte, len(script))
1445  		copy(scriptAddr.scriptCT, script)
1446  	}
1447  	// Add the new managed address to the cache of recent addresses and return it.
1448  	s.addrs[addrKey(scriptHash)] = scriptAddr
1449  	return scriptAddr, nil
1450  }
1451  
1452  // lookupAccount loads account number stored in the manager for the given
1453  // account name
1454  //
1455  // This function MUST be called with the manager lock held for reads.
1456  func (s *ScopedKeyManager) lookupAccount(ns walletdb.ReadBucket, name string) (uint32, error) {
1457  	return fetchAccountByName(ns, &s.scope, name)
1458  }
1459  
1460  // LookupAccount loads account number stored in the manager for the given account name
1461  func (s *ScopedKeyManager) LookupAccount(ns walletdb.ReadBucket, name string) (uint32, error) {
1462  	s.mtx.RLock()
1463  	defer s.mtx.RUnlock()
1464  	return s.lookupAccount(ns, name)
1465  }
1466  
1467  // fetchUsed returns true if the provided address id was flagged used.
1468  func (s *ScopedKeyManager) fetchUsed(
1469  	ns walletdb.ReadBucket,
1470  	addressID []byte,
1471  ) bool {
1472  	return fetchAddressUsed(ns, &s.scope, addressID)
1473  }
1474  
1475  // MarkUsed updates the used flag for the provided address.
1476  func (s *ScopedKeyManager) MarkUsed(
1477  	ns walletdb.ReadWriteBucket,
1478  	address btcaddr.Address,
1479  ) (e error) {
1480  	addressID := address.ScriptAddress()
1481  	if e = markAddressUsed(ns, &s.scope, addressID); E.Chk(e) {
1482  		return maybeConvertDbError(e)
1483  	}
1484  	// Clear caches which might have stale entries for used addresses
1485  	s.mtx.Lock()
1486  	delete(s.addrs, addrKey(addressID))
1487  	s.mtx.Unlock()
1488  	return nil
1489  }
1490  
1491  // ChainParams returns the chain parameters for this address manager.
1492  func (s *ScopedKeyManager) ChainParams() *chaincfg.Params {
1493  	// NOTE: No need for mutex here since the net field does not change after the
1494  	// manager instance is created.
1495  	return s.rootManager.chainParams
1496  }
1497  
1498  // AccountName returns the account name for the given account number stored in
1499  // the manager.
1500  func (s *ScopedKeyManager) AccountName(ns walletdb.ReadBucket, account uint32) (string, error) {
1501  	return fetchAccountName(ns, &s.scope, account)
1502  }
1503  
1504  // ForEachAccount calls the given function with each account stored in the
1505  // manager, breaking early on error.
1506  func (s *ScopedKeyManager) ForEachAccount(
1507  	ns walletdb.ReadBucket,
1508  	fn func(account uint32) error,
1509  ) (e error) {
1510  	return forEachAccount(ns, &s.scope, fn)
1511  }
1512  
1513  // LastAccount returns the last account stored in the manager.
1514  func (s *ScopedKeyManager) LastAccount(ns walletdb.ReadBucket) (uint32, error) {
1515  	return fetchLastAccount(ns, &s.scope)
1516  }
1517  
1518  // ForEachAccountAddress calls the given function with each address of the given
1519  // account stored in the manager, breaking early on error.
1520  func (s *ScopedKeyManager) ForEachAccountAddress(
1521  	ns walletdb.ReadBucket,
1522  	account uint32, fn func(maddr ManagedAddress) error,
1523  ) (e error) {
1524  	s.mtx.Lock()
1525  	defer s.mtx.Unlock()
1526  	addrFn := func(rowInterface interface{}) (e error) {
1527  		var managedAddr ManagedAddress
1528  		if managedAddr, e = s.rowInterfaceToManaged(ns, rowInterface); E.Chk(e) {
1529  			return e
1530  		}
1531  		return fn(managedAddr)
1532  	}
1533  	if e = forEachAccountAddress(ns, &s.scope, account, addrFn); E.Chk(e) {
1534  		return maybeConvertDbError(e)
1535  	}
1536  	return nil
1537  }
1538  
1539  // ForEachActiveAccountAddress calls the given function with each active address
1540  // of the given account stored in the manager, breaking early on error.
1541  //
1542  // TODO(tuxcanfly): actually return only active addresses
1543  func (s *ScopedKeyManager) ForEachActiveAccountAddress(
1544  	ns walletdb.ReadBucket, account uint32,
1545  	fn func(maddr ManagedAddress) error,
1546  ) (e error) {
1547  	return s.ForEachAccountAddress(ns, account, fn)
1548  }
1549  
1550  // ForEachActiveAddress calls the given function with each active address stored
1551  // in the manager, breaking early on error.
1552  func (s *ScopedKeyManager) ForEachActiveAddress(
1553  	ns walletdb.ReadBucket,
1554  	fn func(addr btcaddr.Address) error,
1555  ) (e error) {
1556  	s.mtx.Lock()
1557  	defer s.mtx.Unlock()
1558  	addrFn := func(rowInterface interface{}) (e error) {
1559  		var managedAddr ManagedAddress
1560  		if managedAddr, e = s.rowInterfaceToManaged(ns, rowInterface); E.Chk(e) {
1561  			return e
1562  		}
1563  		return fn(managedAddr.Address())
1564  	}
1565  	if e = forEachActiveAddress(ns, &s.scope, addrFn); E.Chk(e) {
1566  		return maybeConvertDbError(e)
1567  	}
1568  	return nil
1569  }
1570