keychain: ensure we properly set the KeyLocator for keys from DeriveNextKey
In this commit, we fix a slight bug in the existing implementation of DeriveNextKey for btcwallet. Before this commit, we would only set the public key, and not also the derivation path. It's important that we also set the path information, as in the near future we'll be using the KeyDescriptors returned from this method to create static channel back ups. With these static backups, the key alone may be insufficient to re-derive the private key as we may need to fallback to brute forcing in order to re-derive the key as it's possible we add new key families in the future.
This commit is contained in:
parent
e97e4c1f5d
commit
ad25ae1a07
@ -521,13 +521,13 @@ func (f *fundingManager) Start() error {
|
|||||||
// mined since the channel was initiated reaches
|
// mined since the channel was initiated reaches
|
||||||
// maxWaitNumBlocksFundingConf and we are not the channel
|
// maxWaitNumBlocksFundingConf and we are not the channel
|
||||||
// initiator.
|
// initiator.
|
||||||
|
localBalance := ch.LocalCommitment.LocalBalance.ToSatoshis()
|
||||||
closeInfo := &channeldb.ChannelCloseSummary{
|
closeInfo := &channeldb.ChannelCloseSummary{
|
||||||
ChainHash: ch.ChainHash,
|
ChainHash: ch.ChainHash,
|
||||||
ChanPoint: ch.FundingOutpoint,
|
ChanPoint: ch.FundingOutpoint,
|
||||||
RemotePub: ch.IdentityPub,
|
RemotePub: ch.IdentityPub,
|
||||||
Capacity: ch.Capacity,
|
Capacity: ch.Capacity,
|
||||||
SettledBalance: ch.LocalBalance,
|
SettledBalance: localBalance,
|
||||||
CloseType: channeldb.FundingCanceled,
|
CloseType: channeldb.FundingCanceled,
|
||||||
RemoteCurrentRevocation: ch.RemoteCurrentRevocation,
|
RemoteCurrentRevocation: ch.RemoteCurrentRevocation,
|
||||||
RemoteNextRevocation: ch.RemoteNextRevocation,
|
RemoteNextRevocation: ch.RemoteNextRevocation,
|
||||||
@ -1376,13 +1376,14 @@ func (f *fundingManager) handleFundingCreated(fmsg *fundingCreatedMsg) {
|
|||||||
// we use this convenience method to delete the pending OpenChannel
|
// we use this convenience method to delete the pending OpenChannel
|
||||||
// from the database.
|
// from the database.
|
||||||
deleteFromDatabase := func() {
|
deleteFromDatabase := func() {
|
||||||
|
localBalance := completeChan.LocalCommitment.LocalBalance.ToSatoshis()
|
||||||
closeInfo := &channeldb.ChannelCloseSummary{
|
closeInfo := &channeldb.ChannelCloseSummary{
|
||||||
ChanPoint: completeChan.FundingOutpoint,
|
ChanPoint: completeChan.FundingOutpoint,
|
||||||
ChainHash: completeChan.ChainHash,
|
ChainHash: completeChan.ChainHash,
|
||||||
RemotePub: completeChan.IdentityPub,
|
RemotePub: completeChan.IdentityPub,
|
||||||
CloseType: channeldb.FundingCanceled,
|
CloseType: channeldb.FundingCanceled,
|
||||||
Capacity: completeChan.Capacity,
|
Capacity: completeChan.Capacity,
|
||||||
SettledBalance: completeChan.LocalBalance,
|
SettledBalance: localBalance,
|
||||||
RemoteCurrentRevocation: completeChan.RemoteCurrentRevocation,
|
RemoteCurrentRevocation: completeChan.RemoteCurrentRevocation,
|
||||||
RemoteNextRevocation: completeChan.RemoteNextRevocation,
|
RemoteNextRevocation: completeChan.RemoteNextRevocation,
|
||||||
LocalChanConfig: completeChan.LocalChanCfg,
|
LocalChanConfig: completeChan.LocalChanCfg,
|
||||||
|
@ -139,7 +139,10 @@ func (b *BtcWalletKeyRing) createAccountIfNotExists(
|
|||||||
//
|
//
|
||||||
// NOTE: This is part of the keychain.KeyRing interface.
|
// NOTE: This is part of the keychain.KeyRing interface.
|
||||||
func (b *BtcWalletKeyRing) DeriveNextKey(keyFam KeyFamily) (KeyDescriptor, error) {
|
func (b *BtcWalletKeyRing) DeriveNextKey(keyFam KeyFamily) (KeyDescriptor, error) {
|
||||||
var pubKey *btcec.PublicKey
|
var (
|
||||||
|
pubKey *btcec.PublicKey
|
||||||
|
keyLoc KeyLocator
|
||||||
|
)
|
||||||
|
|
||||||
db := b.wallet.Database()
|
db := b.wallet.Database()
|
||||||
err := walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
|
err := walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
|
||||||
@ -165,7 +168,21 @@ func (b *BtcWalletKeyRing) DeriveNextKey(keyFam KeyFamily) (KeyDescriptor, error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKey = addrs[0].(waddrmgr.ManagedPubKeyAddress).PubKey()
|
// Extract the first address, ensuring that it is of the proper
|
||||||
|
// interface type, otherwise we can't manipulate it below.
|
||||||
|
addr, ok := addrs[0].(waddrmgr.ManagedPubKeyAddress)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("address is not a managed pubkey " +
|
||||||
|
"addr")
|
||||||
|
}
|
||||||
|
|
||||||
|
pubKey = addr.PubKey()
|
||||||
|
|
||||||
|
_, pathInfo, _ := addr.DerivationInfo()
|
||||||
|
keyLoc = KeyLocator{
|
||||||
|
Family: keyFam,
|
||||||
|
Index: pathInfo.Index,
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -174,7 +191,8 @@ func (b *BtcWalletKeyRing) DeriveNextKey(keyFam KeyFamily) (KeyDescriptor, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
return KeyDescriptor{
|
return KeyDescriptor{
|
||||||
PubKey: pubKey,
|
PubKey: pubKey,
|
||||||
|
KeyLocator: keyLoc,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ const (
|
|||||||
// will vary per channel and use case) is the final element which allows us to
|
// will vary per channel and use case) is the final element which allows us to
|
||||||
// deterministically derive keys.
|
// deterministically derive keys.
|
||||||
type KeyLocator struct {
|
type KeyLocator struct {
|
||||||
// TODO(roasbeef); add the key scope as well??
|
// TODO(roasbeef): add the key scope as well??
|
||||||
|
|
||||||
// Family is the family of key being identified.
|
// Family is the family of key being identified.
|
||||||
Family KeyFamily
|
Family KeyFamily
|
||||||
@ -92,8 +92,8 @@ type KeyLocator struct {
|
|||||||
Index uint32
|
Index uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty returns true if a KeyLocator is "empty". This may be the case where we
|
// IsEmpty returns true if a KeyLocator is "empty". This may be the case where
|
||||||
// learn of a key from a remote party for a contract, but don't know the
|
// we learn of a key from a remote party for a contract, but don't know the
|
||||||
// precise details of its derivation (as we don't know the private key!).
|
// precise details of its derivation (as we don't know the private key!).
|
||||||
func (k KeyLocator) IsEmpty() bool {
|
func (k KeyLocator) IsEmpty() bool {
|
||||||
return k.Family == 0 && k.Index == 0
|
return k.Family == 0 && k.Index == 0
|
||||||
|
Loading…
Reference in New Issue
Block a user