lnwallet: have wallet return db so it can be closed during shutdown

* Also remove some extra print statements from debugging
* Separate out logic to create wallet from creating an ID
This commit is contained in:
Olaoluwa Osuntokun 2016-01-06 15:12:06 -08:00
parent 986eb83ceb
commit cf65aaa2c9
4 changed files with 46 additions and 59 deletions

@ -22,7 +22,6 @@ import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"log"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -121,12 +120,10 @@ func createWallet(privPass, pubPass, userSeed []byte,
return err return err
} }
err = manager.Close() if err := manager.Close(); err != nil {
if err != nil {
return err return err
} }
err = db.Close() if err := db.Close(); err != nil {
if err != nil {
return err return err
} }
@ -143,14 +140,12 @@ func openDb(directory string, dbname string) (walletdb.DB, error) {
if err := checkCreateDir(directory); err != nil { if err := checkCreateDir(directory); err != nil {
return nil, err return nil, err
} }
log.Printf("checkCreateDir(directory) returned\n")
log.Printf("freezes here?\n")
// Open the database using the boltdb backend. // Open the database using the boltdb backend.
wdb, err := walletdb.Open("bdb", dbPath) wdb, err := walletdb.Open("bdb", dbPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.Printf("walletdb.Open() returned\n")
return wdb, nil return wdb, nil
} }
@ -209,17 +204,14 @@ func openWallet(pubPass []byte, dbDir string) (*wallet.Wallet, walletdb.DB, erro
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("Failed to open database: %v", err) return nil, nil, fmt.Errorf("Failed to open database: %v", err)
} }
log.Printf("openDb returned\n")
addrMgrNS, err := db.Namespace(waddrmgrNamespaceKey) addrMgrNS, err := db.Namespace(waddrmgrNamespaceKey)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
log.Printf("db.Namespace(waddrmgrNamespaceKey) returned\n")
txMgrNS, err := db.Namespace(wtxmgrNamespaceKey) txMgrNS, err := db.Namespace(wtxmgrNamespaceKey)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
log.Printf("db.Namespace(wtxmgrNamespaceKey) returned\n")
// TODO(roasbeef): pass these in as funcs instead, priv pass already // TODO(roasbeef): pass these in as funcs instead, priv pass already
// loaded into memory, use tadge's format to read HD seed. // loaded into memory, use tadge's format to read HD seed.
cbs := &waddrmgr.OpenCallbacks{ cbs := &waddrmgr.OpenCallbacks{
@ -228,6 +220,5 @@ func openWallet(pubPass []byte, dbDir string) (*wallet.Wallet, walletdb.DB, erro
} }
w, err := wallet.Open(pubPass, ActiveNetParams, db, addrMgrNS, txMgrNS, w, err := wallet.Open(pubPass, ActiveNetParams, db, addrMgrNS, txMgrNS,
cbs) cbs)
log.Printf("wallet.Open returned\n")
return w, db, err return w, db, err
} }

@ -244,7 +244,7 @@ type LightningWallet struct {
// If the wallet has never been created (according to the passed dataDir), first-time // If the wallet has never been created (according to the passed dataDir), first-time
// setup is executed. // setup is executed.
// TODO(roasbeef): fin...add config // TODO(roasbeef): fin...add config
func NewLightningWallet(config *Config) (*LightningWallet, error) { func NewLightningWallet(config *Config) (*LightningWallet, walletdb.DB, error) {
// Ensure the wallet exists or create it when the create flag is set. // Ensure the wallet exists or create it when the create flag is set.
netDir := networkDir(config.DataDir, ActiveNetParams) netDir := networkDir(config.DataDir, ActiveNetParams)
dbPath := filepath.Join(netDir, walletDbName) dbPath := filepath.Join(netDir, walletDbName)
@ -257,60 +257,30 @@ func NewLightningWallet(config *Config) (*LightningWallet, error) {
} }
// Wallet has never been created, perform initial set up. // Wallet has never been created, perform initial set up.
var createID bool
if !fileExists(dbPath) { if !fileExists(dbPath) {
// Ensure the data directory for the network exists. // Ensure the data directory for the network exists.
if err := checkCreateDir(netDir); err != nil { if err := checkCreateDir(netDir); err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
return nil, err return nil, nil, err
} }
// Attempt to create a new wallet // Attempt to create a new wallet
if err := createWallet(config.PrivatePass, pubPass, if err := createWallet(config.PrivatePass, pubPass,
config.HdSeed, dbPath); err != nil { config.HdSeed, dbPath); err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
return nil, err return nil, nil, err
} }
log.Printf("createWallet returned\n")
// open wallet to initialize and create id key createID = true
wallet, db, err := openWallet(pubPass, netDir)
if err != nil {
return nil, err
}
log.Printf("openWallet returned\n")
err = wallet.Manager.Unlock(config.PrivatePass)
if err != nil {
return nil, err
}
log.Printf("Unlock returned\n")
adrs, err := wallet.Manager.NextInternalAddresses(0, 1)
if err != nil {
return nil, err
}
idPubkeyHash := adrs[0].Address().ScriptAddress()
if err != nil {
return nil, err
}
lnNamespace, err := db.Namespace(lightningNamespaceKey)
if err != nil {
return nil, err
}
cdb := channeldb.New(wallet.Manager, lnNamespace)
err = cdb.PutIdKey(idPubkeyHash)
if err != nil {
return nil, err
}
err = db.Close()
if err != nil {
return nil, err
}
log.Printf("stored identity key pubkey hash in channeldb\n")
} }
// Wallet has been created and been initialized at this point, open it // Wallet has been created and been initialized at this point, open it
// along with all the required DB namepsaces, and the DB itself. // along with all the required DB namepsaces, and the DB itself.
wallet, db, err := openWallet(pubPass, netDir) wallet, db, err := openWallet(pubPass, netDir)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// Create a special namespace for our unique payment channel related // Create a special namespace for our unique payment channel related
@ -318,7 +288,28 @@ func NewLightningWallet(config *Config) (*LightningWallet, error) {
// created namespace. // created namespace.
lnNamespace, err := db.Namespace(lightningNamespaceKey) lnNamespace, err := db.Namespace(lightningNamespaceKey)
if err != nil { if err != nil {
return nil, err return nil, nil, err
}
cdb := channeldb.New(wallet.Manager, lnNamespace)
if err := wallet.Manager.Unlock(config.PrivatePass); err != nil {
return nil, nil, err
}
// If we just created the wallet, then reserve, and store a key for
// our ID within the Lightning Network.
if createID {
adrs, err := wallet.Manager.NextInternalAddresses(waddrmgr.DefaultAccountNum, 1)
if err != nil {
return nil, nil, err
}
idPubkeyHash := adrs[0].Address().ScriptAddress()
if err := cdb.PutIdKey(idPubkeyHash); err != nil {
return nil, nil, err
}
log.Printf("stored identity key pubkey hash in channeldb\n")
} }
// TODO(roasbeef): logging // TODO(roasbeef): logging
@ -326,7 +317,7 @@ func NewLightningWallet(config *Config) (*LightningWallet, error) {
return &LightningWallet{ return &LightningWallet{
db: db, db: db,
Wallet: wallet, Wallet: wallet,
ChannelDB: channeldb.New(wallet.Manager, lnNamespace), ChannelDB: cdb,
msgChan: make(chan interface{}, msgBufferSize), msgChan: make(chan interface{}, msgBufferSize),
// TODO(roasbeef): make this atomic.Uint32 instead? Which is // TODO(roasbeef): make this atomic.Uint32 instead? Which is
// faster, locks or CAS? I'm guessing CAS because assembly: // faster, locks or CAS? I'm guessing CAS because assembly:
@ -335,7 +326,7 @@ func NewLightningWallet(config *Config) (*LightningWallet, error) {
cfg: config, cfg: config,
fundingLimbo: make(map[uint64]*ChannelReservation), fundingLimbo: make(map[uint64]*ChannelReservation),
quit: make(chan struct{}), quit: make(chan struct{}),
}, nil }, db, nil
} }
// Startup establishes a connection to the RPC source, and spins up all // Startup establishes a connection to the RPC source, and spins up all

@ -69,7 +69,7 @@ type bobNode struct {
// For simplicity, used for both the commit tx and the multi-sig output. // For simplicity, used for both the commit tx and the multi-sig output.
channelKey *btcec.PublicKey channelKey *btcec.PublicKey
deliveryAddress btcutil.Address deliveryAddress btcutil.Address
revocation [wire.HashSize]byte revocation [20]byte
delay uint32 delay uint32
id [wire.HashSize]byte id [wire.HashSize]byte
@ -152,7 +152,7 @@ func newBobNode() (*bobNode, error) {
// Bob's initial revocation hash is just his private key with the first // Bob's initial revocation hash is just his private key with the first
// byte changed... // byte changed...
var revocation [wire.HashSize]byte var revocation [20]byte
copy(revocation[:], bobsPrivKey) copy(revocation[:], bobsPrivKey)
revocation[0] = 0xff revocation[0] = 0xff
@ -301,12 +301,14 @@ func createTestWallet() (string, *LightningWallet, error) {
config := &Config{PrivatePass: privPass, HdSeed: testHdSeed[:], config := &Config{PrivatePass: privPass, HdSeed: testHdSeed[:],
DataDir: tempTestDir} DataDir: tempTestDir}
wallet, err := NewLightningWallet(config) wallet, _, err := NewLightningWallet(config)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
// TODO(roasbeef): check error once nodetest is finished. // TODO(roasbeef): check error once nodetest is finished.
_ = wallet.Startup() if err := wallet.Startup(); err != nil {
return "", nil, err
}
// Load our test wallet with 5 outputs each holding 4BTC. // Load our test wallet with 5 outputs each holding 4BTC.
if err := loadTestCredits(wallet, 5, 4); err != nil { if err := loadTestCredits(wallet, 5, 4); err != nil {

@ -28,17 +28,20 @@ func main() {
// TODO(roasbeef): accept config via cli flags, move to real config file // TODO(roasbeef): accept config via cli flags, move to real config file
// afterwards // afterwards
config := &lnwallet.Config{PrivatePass: []byte("hello"), DataDir: "test_wal"} config := &lnwallet.Config{PrivatePass: []byte("hello"), DataDir: "test_wal"}
lnwallet, err := lnwallet.NewLightningWallet(config) lnwallet, db, err := lnwallet.NewLightningWallet(config)
if err != nil { if err != nil {
fmt.Printf("unable to create wallet: %v\n", err) fmt.Printf("unable to create wallet: %v\n", err)
os.Exit(1) os.Exit(1)
} }
if err := lnwallet.Startup(); err != nil { if err := lnwallet.Startup(); err != nil {
fmt.Printf("unable to start wallet: %v\n", err) fmt.Printf("unable to start wallet: %v\n", err)
os.Exit(1) os.Exit(1)
} }
lnwallet.Unlock(cf.PrivatePass, time.Duration(0))
lnwallet.Unlock(config.PrivatePass, time.Duration(0))
fmt.Println("wallet open") fmt.Println("wallet open")
defer db.Close()
// Initialize, and register our implementation of the gRPC server. // Initialize, and register our implementation of the gRPC server.
var opts []grpc.ServerOption var opts []grpc.ServerOption