waddrmgr: add support for wallet birthday for creating new wallet
TODO: support for wallet upgrades and key imports
This commit is contained in:
parent
44f94c4ca5
commit
555bd5d583
3 changed files with 68 additions and 2 deletions
|
@ -194,6 +194,7 @@ var (
|
|||
// Sync related key names (sync bucket).
|
||||
syncedToName = []byte("syncedto")
|
||||
startBlockName = []byte("startblock")
|
||||
birthdayName = []byte("birthday")
|
||||
|
||||
// Account related key names (account bucket).
|
||||
acctNumAcctsName = []byte("numaccts")
|
||||
|
@ -1489,6 +1490,37 @@ func putStartBlock(ns walletdb.ReadWriteBucket, bs *BlockStamp) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// fetchBirthday loads the manager's bithday timestamp from the database.
|
||||
func fetchBirthday(ns walletdb.ReadBucket) (time.Time, error) {
|
||||
bucket := ns.NestedReadBucket(syncBucketName)
|
||||
|
||||
var t time.Time
|
||||
|
||||
buf := bucket.Get(birthdayName)
|
||||
if len(buf) != 8 {
|
||||
str := "malformed birthday stored in database"
|
||||
return t, managerError(ErrDatabase, str, nil)
|
||||
}
|
||||
|
||||
t = time.Unix(int64(binary.BigEndian.Uint64(buf)), 0)
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// putBirthday stores the provided birthday timestamp to the database.
|
||||
func putBirthday(ns walletdb.ReadWriteBucket, t time.Time) error {
|
||||
bucket := ns.NestedReadWriteBucket(syncBucketName)
|
||||
|
||||
buf := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(buf, uint64(t.Unix()))
|
||||
|
||||
err := bucket.Put(birthdayName, buf)
|
||||
if err != nil {
|
||||
str := "failed to store birthday"
|
||||
return managerError(ErrDatabase, str, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// managerExists returns whether or not the manager has already been created
|
||||
// in the given database namespace.
|
||||
func managerExists(ns walletdb.ReadBucket) bool {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"crypto/sha512"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/roasbeef/btcd/btcec"
|
||||
"github.com/roasbeef/btcd/chaincfg"
|
||||
|
@ -249,6 +250,7 @@ type Manager struct {
|
|||
chainParams *chaincfg.Params
|
||||
addrs map[addrKey]ManagedAddress
|
||||
syncState syncState
|
||||
birthday time.Time
|
||||
watchingOnly bool
|
||||
locked bool
|
||||
closed bool
|
||||
|
@ -1985,12 +1987,13 @@ func (m *Manager) Decrypt(keyType CryptoKeyType, in []byte) ([]byte, error) {
|
|||
func newManager(chainParams *chaincfg.Params, masterKeyPub *snacl.SecretKey,
|
||||
masterKeyPriv *snacl.SecretKey, cryptoKeyPub EncryptorDecryptor,
|
||||
cryptoKeyPrivEncrypted, cryptoKeyScriptEncrypted []byte, syncInfo *syncState,
|
||||
privPassphraseSalt [saltSize]byte) *Manager {
|
||||
birthday time.Time, privPassphraseSalt [saltSize]byte) *Manager {
|
||||
|
||||
return &Manager{
|
||||
chainParams: chainParams,
|
||||
addrs: make(map[addrKey]ManagedAddress),
|
||||
syncState: *syncInfo,
|
||||
birthday: birthday,
|
||||
locked: true,
|
||||
acctInfo: make(map[uint32]*accountInfo),
|
||||
masterKeyPub: masterKeyPub,
|
||||
|
@ -2124,6 +2127,10 @@ func loadManager(ns walletdb.ReadBucket, pubPassphrase []byte, chainParams *chai
|
|||
if err != nil {
|
||||
return nil, maybeConvertDbError(err)
|
||||
}
|
||||
birthday, err := fetchBirthday(ns)
|
||||
if err != nil {
|
||||
return nil, maybeConvertDbError(err)
|
||||
}
|
||||
|
||||
// When not a watching-only manager, set the master private key params,
|
||||
// but don't derive it now since the manager starts off locked.
|
||||
|
@ -2174,7 +2181,7 @@ func loadManager(ns walletdb.ReadBucket, pubPassphrase []byte, chainParams *chai
|
|||
// call to new with the values loaded from the database.
|
||||
mgr := newManager(chainParams, &masterKeyPub, &masterKeyPriv,
|
||||
cryptoKeyPub, cryptoKeyPrivEnc, cryptoKeyScriptEnc, syncInfo,
|
||||
privPassphraseSalt)
|
||||
birthday, privPassphraseSalt)
|
||||
mgr.watchingOnly = watchingOnly
|
||||
return mgr, nil
|
||||
}
|
||||
|
@ -2438,6 +2445,11 @@ func Create(ns walletdb.ReadWriteBucket, seed, pubPassphrase, privPassphrase []b
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Use 48 hours as margin of safety for wallet birthday.
|
||||
err = putBirthday(ns, time.Now().Add(-48*time.Hour))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Save the information for the imported account to the database.
|
||||
err = putAccountInfo(ns, ImportedAddrAccount, nil,
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
package waddrmgr
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
||||
"github.com/roasbeef/btcwallet/walletdb"
|
||||
)
|
||||
|
@ -87,3 +89,23 @@ func (m *Manager) BlockHash(ns walletdb.ReadBucket, height int32) (
|
|||
|
||||
return fetchBlockHash(ns, height)
|
||||
}
|
||||
|
||||
// Birthday returns the birthday, or earliest time a key could have been used,
|
||||
// for the manager.
|
||||
func (m *Manager) Birthday() time.Time {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
|
||||
return m.birthday
|
||||
}
|
||||
|
||||
// SetBirthday sets the birthday, or earliest time a key could have been used,
|
||||
// for the manager.
|
||||
func (m *Manager) SetBirthday(ns walletdb.ReadWriteBucket,
|
||||
birthday time.Time) error {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
|
||||
m.birthday = birthday
|
||||
return putBirthday(ns, birthday)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue