github.com/decred/dcrlnd@v0.7.6/lnwallet/remotedcrwallet/keychain_test.go (about) 1 package remotedcrwallet 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "testing" 9 "time" 10 11 "github.com/decred/dcrlnd/channeldb" 12 "github.com/decred/dcrlnd/keychain" 13 "github.com/decred/dcrlnd/lnwallet" 14 15 base "decred.org/dcrwallet/v4/wallet" 16 17 "github.com/decred/dcrd/chaincfg/chainhash" 18 "github.com/decred/dcrd/chaincfg/v3" 19 "github.com/decred/dcrd/hdkeychain/v3" 20 "github.com/decred/dcrd/txscript/v4/stdaddr" 21 walletloader "github.com/decred/dcrlnd/lnwallet/dcrwallet/loader" 22 ) 23 24 var ( 25 testHDSeed = chainhash.Hash{ 26 0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab, 27 0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4, 28 0x4f, 0x2f, 0x6f, 0x25, 0x98, 0xa3, 0xef, 0xb9, 29 0x69, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53, 30 } 31 ) 32 33 type mockOnchainAddrSourcer struct { 34 w *base.Wallet 35 } 36 37 func (mas *mockOnchainAddrSourcer) NewAddress(t lnwallet.AddressType, change bool, 38 accountName string) (stdaddr.Address, error) { 39 var addr stdaddr.Address 40 var err error 41 if change { 42 addr, err = mas.w.NewInternalAddress(context.TODO(), 0) 43 } else { 44 addr, err = mas.w.NewExternalAddress(context.TODO(), 0) 45 } 46 47 if err != nil { 48 return nil, err 49 } 50 51 // Convert to a regular p2pkh address, since the addresses returned are 52 // used as paramaters to PayT.(stdaddr.Hash160er).Hash160()[:] which doesn't understand 53 // the native wallet types. 54 return stdaddr.DecodeAddress(addr.String(), chaincfg.SimNetParams()) 55 56 } 57 func (mas *mockOnchainAddrSourcer) Bip44AddressInfo(addr stdaddr.Address) (uint32, uint32, uint32, error) { 58 info, err := mas.w.KnownAddress(context.Background(), addr) 59 if err != nil { 60 return 0, 0, 0, nil 61 } 62 63 switch ma := info.(type) { 64 case base.BIP0044Address: 65 acct, branch, child := ma.Path() 66 return acct, branch, child, nil 67 } 68 69 return 0, 0, 0, fmt.Errorf("unkown address type") 70 } 71 72 func createTestWallet() (func(), *hdkeychain.ExtendedKey, *channeldb.DB, onchainAddrSourcer, error) { 73 tempDir, err := ioutil.TempDir("", "keyring-lnwallet") 74 if err != nil { 75 return nil, nil, nil, nil, err 76 } 77 loader := walletloader.NewLoader(chaincfg.SimNetParams(), tempDir, 20) 78 79 pass := []byte("test") 80 81 birthday := time.Now().Add(-time.Hour * 24) 82 baseWallet, err := loader.CreateNewWallet( 83 context.Background(), pass, pass, testHDSeed[:], birthday, 84 ) 85 if err != nil { 86 return nil, nil, nil, nil, err 87 } 88 89 if err := baseWallet.Unlock(context.Background(), pass, nil); err != nil { 90 return nil, nil, nil, nil, err 91 } 92 93 // Create the temp chandb dir. 94 cdbDir, err := ioutil.TempDir("", "channeldb") 95 if err != nil { 96 return nil, nil, nil, nil, err 97 } 98 99 // Next, create channeldb for the first time. 100 cdb, err := channeldb.Open(cdbDir) 101 if err != nil { 102 return nil, nil, nil, nil, err 103 } 104 105 // The root master xpriv is the default account's one. 106 acctXpriv, err := baseWallet.AccountXpriv(context.Background(), 0) 107 if err != nil { 108 return nil, nil, nil, nil, err 109 } 110 111 // Create the mock onchain addresses sourcer linked to the previously 112 // created wallet. 113 addrSourcer := &mockOnchainAddrSourcer{w: baseWallet} 114 115 cleanUp := func() { 116 baseWallet.Lock() 117 os.RemoveAll(tempDir) 118 cdb.Close() 119 os.RemoveAll(cdbDir) 120 } 121 122 return cleanUp, acctXpriv, cdb, addrSourcer, nil 123 } 124 125 // TestDcrwalletKeyRingImpl tests whether the walletKeyRing implementation 126 // conforms to the required interface spec. 127 func TestDcrwalletKeyRingImpl(t *testing.T) { 128 t.Parallel() 129 130 keychain.CheckKeyRingImpl(t, 131 func() (string, func(), keychain.KeyRing, error) { 132 cleanUp, rootXPriv, cdb, addrSourcer, err := createTestWallet() 133 if err != nil { 134 t.Fatalf("unable to create wallet: %v", err) 135 } 136 137 keyRing, err := newRemoteWalletKeyRing( 138 rootXPriv, cdb, addrSourcer, 139 ) 140 141 return "dcrwallet", cleanUp, keyRing, err 142 }, 143 ) 144 145 } 146 147 // TestDcrwalletSecretKeyRingImpl tests whether the walletKeyRing 148 // implementation conforms to the required interface spec. 149 func TestDcrwalletSecretKeyRingImpl(t *testing.T) { 150 t.Parallel() 151 152 keychain.CheckSecretKeyRingImpl(t, 153 func() (string, func(), keychain.SecretKeyRing, error) { 154 cleanUp, rootXPriv, cdb, addrSourcer, err := createTestWallet() 155 if err != nil { 156 t.Fatalf("unable to create wallet: %v", err) 157 } 158 159 keyRing, err := newRemoteWalletKeyRing( 160 rootXPriv, cdb, addrSourcer, 161 ) 162 163 return "dcrwallet", cleanUp, keyRing, err 164 }, 165 ) 166 167 } 168 169 func init() { 170 // We'll clamp the max range scan to constrain the run time of the 171 // private key scan test. 172 keychain.MaxKeyRangeScan = 3 173 }