150 lines
3.9 KiB
Go
150 lines
3.9 KiB
Go
|
package walletunlocker_test
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"io/ioutil"
|
||
|
"os"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||
|
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
|
||
|
"github.com/lightningnetwork/lnd/walletunlocker"
|
||
|
"github.com/roasbeef/btcd/chaincfg"
|
||
|
"github.com/roasbeef/btcwallet/wallet"
|
||
|
"golang.org/x/net/context"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
walletDbName = "wallet.db"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
testPassword = []byte("test-password")
|
||
|
testSeed = []byte("test-seed-123456789")
|
||
|
|
||
|
testNetParams = &chaincfg.MainNetParams
|
||
|
)
|
||
|
|
||
|
func createTestWallet(t *testing.T, dir string, netParams *chaincfg.Params) {
|
||
|
netDir := btcwallet.NetworkDir(dir, netParams)
|
||
|
loader := wallet.NewLoader(netParams, netDir)
|
||
|
_, err := loader.CreateNewWallet(testPassword, testPassword, testSeed)
|
||
|
if err != nil {
|
||
|
t.Fatalf("failed creating wallet: %v", err)
|
||
|
}
|
||
|
err = loader.UnloadWallet()
|
||
|
if err != nil {
|
||
|
t.Fatalf("failed unloading wallet: %v", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TestCreateWallet checks that CreateWallet correctly returns a password that
|
||
|
// can be used for creating a wallet if no wallet exists from before, and
|
||
|
// returns an error when it already exists.
|
||
|
func TestCreateWallet(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
|
||
|
// testDir is empty, meaning wallet was not created from before.
|
||
|
testDir, err := ioutil.TempDir("", "testcreate")
|
||
|
if err != nil {
|
||
|
t.Fatalf("unable to create temp directory: %v", err)
|
||
|
}
|
||
|
defer func() {
|
||
|
os.RemoveAll(testDir)
|
||
|
}()
|
||
|
|
||
|
// Create new UnlockerService.
|
||
|
service := walletunlocker.New(nil, testDir, testNetParams)
|
||
|
|
||
|
ctx := context.Background()
|
||
|
req := &lnrpc.CreateWalletRequest{
|
||
|
Password: testPassword,
|
||
|
}
|
||
|
_, err = service.CreateWallet(ctx, req)
|
||
|
if err != nil {
|
||
|
t.Fatalf("CreateWallet call failed: %v", err)
|
||
|
}
|
||
|
|
||
|
// Password should be sent over the channel.
|
||
|
select {
|
||
|
case pw := <-service.CreatePasswords:
|
||
|
if !bytes.Equal(pw, testPassword) {
|
||
|
t.Fatalf("expected to receive password %x, got %x",
|
||
|
testPassword, pw)
|
||
|
}
|
||
|
case <-time.After(3 * time.Second):
|
||
|
t.Fatalf("password not received")
|
||
|
}
|
||
|
|
||
|
// Create a wallet in testDir.
|
||
|
createTestWallet(t, testDir, testNetParams)
|
||
|
|
||
|
// Now calling CreateWallet should fail, since a wallet already exists
|
||
|
// in the directory.
|
||
|
_, err = service.CreateWallet(ctx, req)
|
||
|
if err == nil {
|
||
|
t.Fatalf("CreateWallet did not fail as expected")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TestUnlockWallet checks that trying to unlock non-existing wallet fail,
|
||
|
// that unlocking existing wallet with wrong passphrase fails, and that
|
||
|
// unlocking existing wallet with correct passphrase succeeds.
|
||
|
func TestUnlockWallet(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
|
||
|
// testDir is empty, meaning wallet was not created from before.
|
||
|
testDir, err := ioutil.TempDir("", "testunlock")
|
||
|
if err != nil {
|
||
|
t.Fatalf("unable to create temp directory: %v", err)
|
||
|
}
|
||
|
defer func() {
|
||
|
os.RemoveAll(testDir)
|
||
|
}()
|
||
|
|
||
|
// Create new UnlockerService.
|
||
|
service := walletunlocker.New(nil, testDir, testNetParams)
|
||
|
|
||
|
ctx := context.Background()
|
||
|
req := &lnrpc.UnlockWalletRequest{
|
||
|
Password: testPassword,
|
||
|
}
|
||
|
|
||
|
// Should fail to unlock non-existing wallet.
|
||
|
_, err = service.UnlockWallet(ctx, req)
|
||
|
if err == nil {
|
||
|
t.Fatalf("expected call to UnlockWallet to fail")
|
||
|
}
|
||
|
|
||
|
// Create a wallet we can try to unlock.
|
||
|
createTestWallet(t, testDir, testNetParams)
|
||
|
|
||
|
// Try unlocking this wallet with the wrong passphrase.
|
||
|
wrongReq := &lnrpc.UnlockWalletRequest{
|
||
|
Password: []byte("wrong-ofc"),
|
||
|
}
|
||
|
_, err = service.UnlockWallet(ctx, wrongReq)
|
||
|
if err == nil {
|
||
|
t.Fatalf("expected call to UnlockWallet to fail")
|
||
|
}
|
||
|
|
||
|
// With the correct password, we should be able to unlock the wallet.
|
||
|
_, err = service.UnlockWallet(ctx, req)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unable to unlock wallet: %v", err)
|
||
|
}
|
||
|
|
||
|
// Password should be sent over the channel.
|
||
|
select {
|
||
|
case pw := <-service.UnlockPasswords:
|
||
|
if !bytes.Equal(pw, testPassword) {
|
||
|
t.Fatalf("expected to receive password %x, got %x",
|
||
|
testPassword, pw)
|
||
|
}
|
||
|
case <-time.After(3 * time.Second):
|
||
|
t.Fatalf("password not received")
|
||
|
}
|
||
|
|
||
|
}
|