-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
client: bitcoin spv #1230
client: bitcoin spv #1230
Changes from 1 commit
2a591a5
4a27537
7e13921
284052b
5c34c9a
e13925f
c1046e3
2b6ecf8
5084c09
f5c5c38
47e512a
856ee5b
8ac1c89
644c1e5
af38f4c
97f7a39
55daa99
f147edf
5c71c93
350557b
d316157
010b451
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -172,6 +172,7 @@ var ( | |
spvWalletDefinition, | ||
rpcWalletDefinition, | ||
}, | ||
LegacyWalletIndex: 1, | ||
} | ||
) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1797,27 +1797,15 @@ func (c *Core) CreateWallet(appPW, walletPW []byte, form *WalletForm) error { | |
// derived deterministically from the app seed and a random password. The | ||
// password is returned for encrypting and storing. | ||
func (c *Core) createSeededWallet(assetID uint32, crypter encrypt.Crypter, form *WalletForm) ([]byte, error) { | ||
creds := c.creds() | ||
if creds == nil { | ||
return nil, errors.New("no v2 credentials stored") | ||
} | ||
|
||
appSeed, err := crypter.Decrypt(creds.EncSeed) | ||
seed, pw, err := c.assetSeedAndPass(assetID, crypter) | ||
if err != nil { | ||
return nil, fmt.Errorf("app seed decryption error: %w", err) | ||
return nil, err | ||
} | ||
|
||
c.log.Infof("Initializing a built-in %s wallet", unbip(assetID)) | ||
|
||
b := make([]byte, len(appSeed)+4) | ||
copy(b, appSeed) | ||
binary.BigEndian.PutUint32(b[len(appSeed):], assetID) | ||
|
||
seed := blake256.Sum256(b) | ||
pw := encode.RandomBytes(32) | ||
if err = asset.CreateWallet(assetID, &asset.CreateWalletParams{ | ||
Type: form.Type, | ||
Seed: seed[:], | ||
Seed: seed, | ||
Pass: pw, | ||
Settings: form.Config, | ||
DataDir: c.assetDataDirectory(assetID), | ||
|
@@ -1830,6 +1818,26 @@ func (c *Core) createSeededWallet(assetID uint32, crypter encrypt.Crypter, form | |
return pw, nil | ||
} | ||
|
||
func (c *Core) assetSeedAndPass(assetID uint32, crypter encrypt.Crypter) (seed, pass []byte, err error) { | ||
creds := c.creds() | ||
if creds == nil { | ||
return nil, nil, errors.New("no v2 credentials stored") | ||
} | ||
|
||
appSeed, err := crypter.Decrypt(creds.EncSeed) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("app seed decryption error: %w", err) | ||
} | ||
|
||
b := make([]byte, len(appSeed)+4) | ||
copy(b, appSeed) | ||
binary.BigEndian.PutUint32(b[len(appSeed):], assetID) | ||
|
||
s := blake256.Sum256(b) | ||
p := blake256.Sum256(seed) | ||
return s[:], p[:], nil | ||
} | ||
|
||
// assetDataDirectory is a directory for a wallet to use for local storage. | ||
func (c *Core) assetDataDirectory(assetID uint32) string { | ||
return filepath.Join(filepath.Dir(c.cfg.DBPath), "assetdb", unbip(assetID)) | ||
|
@@ -2026,7 +2034,7 @@ func (c *Core) ReconfigureWallet(appPW, newWalletPW []byte, form *WalletForm) er | |
assetID, unbip(assetID)) | ||
} | ||
seeded := oldWallet.Info().Seeded | ||
if seeded && len(newWalletPW) > 0 { | ||
if seeded && newWalletPW != nil { | ||
return newError(passwordErr, "cannot set a password on a built-in wallet") | ||
} | ||
oldDepositAddr := oldWallet.currentDepositAddress() | ||
|
@@ -2039,10 +2047,23 @@ func (c *Core) ReconfigureWallet(appPW, newWalletPW []byte, form *WalletForm) er | |
Address: oldDepositAddr, | ||
} | ||
|
||
fmt.Printf("--ReconfigureWallet.0 %+v \n", walletDef) | ||
var restartOnFail bool | ||
|
||
defer func() { | ||
if restartOnFail { | ||
if _, err := c.connectWallet(oldWallet); err != nil { | ||
c.log.Errorf("Failed to reconnect wallet after a failed reconfiguration attempt: %v", err) | ||
} | ||
} | ||
}() | ||
|
||
oldDef, err := walletDefinition(assetID, oldWallet.walletType) | ||
if err != nil { | ||
return fmt.Errorf("failed to locate old wallet definition: %v", err) | ||
} | ||
|
||
if walletDef.Seeded { | ||
if len(newWalletPW) > 0 { | ||
if newWalletPW != nil { | ||
return newError(passwordErr, "cannot set a password on a seeded wallet") | ||
} | ||
|
||
|
@@ -2056,8 +2077,27 @@ func (c *Core) ReconfigureWallet(appPW, newWalletPW []byte, form *WalletForm) er | |
if err != nil { | ||
return newError(createWalletErr, "error creating new %q-type %s wallet: %v", form.Type, unbip(assetID), err) | ||
} | ||
// return newError(existenceCheckErr, "cannot reconfigure wallet that doesn't exist") | ||
} else if oldDef.Seeded { | ||
_, newWalletPW, err = c.assetSeedAndPass(assetID, crypter) | ||
if err != nil { | ||
return newError(authErr, "error retrieving wallet password: %v", err) | ||
} | ||
} | ||
|
||
if oldWallet.connected() { | ||
oldDef, err := walletDefinition(assetID, oldWallet.walletType) | ||
// Error can be normal if the wallet was created before wallet types | ||
// were a thing. Just assume this is an old wallet and therefore not | ||
// seeded. | ||
if err == nil && oldDef.Seeded { | ||
Comment on lines
+2088
to
+2092
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You already have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be good without the if oldDef.Seeded && oldWallet.connected() {
oldWallet.Disconnect()
restartOnFail = true
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NVM, I have some updates that will follow. Going to merge this shortly. |
||
oldWallet.Disconnect() | ||
restartOnFail = true | ||
} | ||
} | ||
} else if newWalletPW == nil && oldDef.Seeded { | ||
// If we're switching from a seeded wallet and no password was provided, | ||
// use empty string = wallet not encrypted. | ||
newWalletPW = []byte{} | ||
} | ||
|
||
// Reload the wallet with the new settings. | ||
|
@@ -2159,6 +2199,8 @@ func (c *Core) ReconfigureWallet(appPW, newWalletPW []byte, form *WalletForm) er | |
c.wallets[assetID] = wallet | ||
c.walletMtx.Unlock() | ||
|
||
restartOnFail = false | ||
|
||
if oldWallet.connected() { | ||
// NOTE: Cannot lock the wallet backend because it may be the same as | ||
// the one just connected. | ||
|
@@ -6235,6 +6277,12 @@ func walletDefinition(assetID uint32, walletType string) (*asset.WalletDefinitio | |
if err != nil { | ||
return nil, newError(assetSupportErr, "asset.Info error: %v", err) | ||
} | ||
if walletType == "" { | ||
if len(winfo.AvailableWallets) <= winfo.LegacyWalletIndex { | ||
return nil, fmt.Errorf("legacy wallet index out of range") | ||
} | ||
return winfo.AvailableWallets[winfo.LegacyWalletIndex], nil | ||
} | ||
var walletDef *asset.WalletDefinition | ||
for _, def := range winfo.AvailableWallets { | ||
if def.Type == walletType { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you still want to increment here.
seems like the only place not to increment is with a non-nil return setting up the logger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I confirmed that the remaining log races go away with this, but then realized that in
createSPVWallet
(the other place wherelogNeutrino
is called), we need adefer unlogNeutrino()
too otherwise it never decrements to zero to close the log rotator.Sadly, this reveals a problem: https://github.com/lightninglabs/neutrino/blob/51686db787e01a3709b1583af3e20e916811d585/neutrino.go#L1136-L1137
The time drain on this logger is unfortunate, and it's looking like only ever calling UseLogger once (somehow), even if we are synchronizing the best we can, is the only actual solution. I'm not even sure a dumb Sleep would do as a workaround, but perhaps it's worth doing that just to save ourselves further wasted time.