mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-18 12:52:25 +02:00
multi: use key locator for lnwallet.MessageSigner
To simplify the message signing API even further, we refactor the lnwallet.MessageSigner interface to use a key locator instead of the public key to identify which key should be signed with.
This commit is contained in:
parent
afa03f22cc
commit
e79d59dd4c
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/batch"
|
"github.com/lightningnetwork/lnd/batch"
|
||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/kvdb"
|
"github.com/lightningnetwork/lnd/kvdb"
|
||||||
"github.com/lightningnetwork/lnd/lnpeer"
|
"github.com/lightningnetwork/lnd/lnpeer"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
@ -316,6 +317,10 @@ type AuthenticatedGossiper struct {
|
|||||||
// selfKey is the identity public key of the backing Lightning node.
|
// selfKey is the identity public key of the backing Lightning node.
|
||||||
selfKey *btcec.PublicKey
|
selfKey *btcec.PublicKey
|
||||||
|
|
||||||
|
// selfKeyLoc is the locator for the identity public key of the backing
|
||||||
|
// Lightning node.
|
||||||
|
selfKeyLoc keychain.KeyLocator
|
||||||
|
|
||||||
// channelMtx is used to restrict the database access to one
|
// channelMtx is used to restrict the database access to one
|
||||||
// goroutine per channel ID. This is done to ensure that when
|
// goroutine per channel ID. This is done to ensure that when
|
||||||
// the gossiper is handling an announcement, the db state stays
|
// the gossiper is handling an announcement, the db state stays
|
||||||
@ -355,9 +360,10 @@ type AuthenticatedGossiper struct {
|
|||||||
|
|
||||||
// New creates a new AuthenticatedGossiper instance, initialized with the
|
// New creates a new AuthenticatedGossiper instance, initialized with the
|
||||||
// passed configuration parameters.
|
// passed configuration parameters.
|
||||||
func New(cfg Config, selfKey *btcec.PublicKey) *AuthenticatedGossiper {
|
func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper {
|
||||||
gossiper := &AuthenticatedGossiper{
|
gossiper := &AuthenticatedGossiper{
|
||||||
selfKey: selfKey,
|
selfKey: selfKeyDesc.PubKey,
|
||||||
|
selfKeyLoc: selfKeyDesc.KeyLocator,
|
||||||
cfg: &cfg,
|
cfg: &cfg,
|
||||||
networkMsgs: make(chan *networkMsg),
|
networkMsgs: make(chan *networkMsg),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
@ -2567,7 +2573,7 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
|
|||||||
// We'll generate a new signature over a digest of the channel
|
// We'll generate a new signature over a digest of the channel
|
||||||
// announcement itself and update the timestamp to ensure it propagate.
|
// announcement itself and update the timestamp to ensure it propagate.
|
||||||
err := netann.SignChannelUpdate(
|
err := netann.SignChannelUpdate(
|
||||||
d.cfg.AnnSigner, d.selfKey, chanUpdate,
|
d.cfg.AnnSigner, d.selfKeyLoc, chanUpdate,
|
||||||
netann.ChanUpdSetTimestamp,
|
netann.ChanUpdSetTimestamp,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/batch"
|
"github.com/lightningnetwork/lnd/batch"
|
||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/kvdb"
|
"github.com/lightningnetwork/lnd/kvdb"
|
||||||
"github.com/lightningnetwork/lnd/lnpeer"
|
"github.com/lightningnetwork/lnd/lnpeer"
|
||||||
"github.com/lightningnetwork/lnd/lntest/mock"
|
"github.com/lightningnetwork/lnd/lntest/mock"
|
||||||
@ -48,9 +49,13 @@ var (
|
|||||||
}
|
}
|
||||||
_, _ = testSig.R.SetString("63724406601629180062774974542967536251589935445068131219452686511677818569431", 10)
|
_, _ = testSig.R.SetString("63724406601629180062774974542967536251589935445068131219452686511677818569431", 10)
|
||||||
_, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10)
|
_, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10)
|
||||||
|
testKeyLoc = keychain.KeyLocator{Family: keychain.KeyFamilyNodeKey}
|
||||||
|
|
||||||
selfKeyPriv, _ = btcec.NewPrivateKey(btcec.S256())
|
selfKeyPriv, _ = btcec.NewPrivateKey(btcec.S256())
|
||||||
selfKeyPub = selfKeyPriv.PubKey()
|
selfKeyDesc = &keychain.KeyDescriptor{
|
||||||
|
PubKey: selfKeyPriv.PubKey(),
|
||||||
|
KeyLocator: testKeyLoc,
|
||||||
|
}
|
||||||
|
|
||||||
bitcoinKeyPriv1, _ = btcec.NewPrivateKey(btcec.S256())
|
bitcoinKeyPriv1, _ = btcec.NewPrivateKey(btcec.S256())
|
||||||
bitcoinKeyPub1 = bitcoinKeyPriv1.PubKey()
|
bitcoinKeyPub1 = bitcoinKeyPriv1.PubKey()
|
||||||
@ -568,7 +573,7 @@ func createNodeAnnouncement(priv *btcec.PrivateKey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
signer := mock.SingleSigner{Privkey: priv}
|
signer := mock.SingleSigner{Privkey: priv}
|
||||||
sig, err := netann.SignAnnouncement(&signer, priv.PubKey(), a)
|
sig, err := netann.SignAnnouncement(&signer, testKeyLoc, a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -618,9 +623,8 @@ func createUpdateAnnouncement(blockHeight uint32,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func signUpdate(nodeKey *btcec.PrivateKey, a *lnwire.ChannelUpdate) error {
|
func signUpdate(nodeKey *btcec.PrivateKey, a *lnwire.ChannelUpdate) error {
|
||||||
pub := nodeKey.PubKey()
|
|
||||||
signer := mock.SingleSigner{Privkey: nodeKey}
|
signer := mock.SingleSigner{Privkey: nodeKey}
|
||||||
sig, err := netann.SignAnnouncement(&signer, pub, a)
|
sig, err := netann.SignAnnouncement(&signer, testKeyLoc, a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -667,9 +671,8 @@ func createChannelAnnouncement(blockHeight uint32, key1, key2 *btcec.PrivateKey,
|
|||||||
|
|
||||||
a := createAnnouncementWithoutProof(blockHeight, key1.PubKey(), key2.PubKey(), extraBytes...)
|
a := createAnnouncementWithoutProof(blockHeight, key1.PubKey(), key2.PubKey(), extraBytes...)
|
||||||
|
|
||||||
pub := key1.PubKey()
|
|
||||||
signer := mock.SingleSigner{Privkey: key1}
|
signer := mock.SingleSigner{Privkey: key1}
|
||||||
sig, err := netann.SignAnnouncement(&signer, pub, a)
|
sig, err := netann.SignAnnouncement(&signer, testKeyLoc, a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -678,9 +681,8 @@ func createChannelAnnouncement(blockHeight uint32, key1, key2 *btcec.PrivateKey,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pub = key2.PubKey()
|
|
||||||
signer = mock.SingleSigner{Privkey: key2}
|
signer = mock.SingleSigner{Privkey: key2}
|
||||||
sig, err = netann.SignAnnouncement(&signer, pub, a)
|
sig, err = netann.SignAnnouncement(&signer, testKeyLoc, a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -689,9 +691,8 @@ func createChannelAnnouncement(blockHeight uint32, key1, key2 *btcec.PrivateKey,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pub = bitcoinKeyPriv1.PubKey()
|
|
||||||
signer = mock.SingleSigner{Privkey: bitcoinKeyPriv1}
|
signer = mock.SingleSigner{Privkey: bitcoinKeyPriv1}
|
||||||
sig, err = netann.SignAnnouncement(&signer, pub, a)
|
sig, err = netann.SignAnnouncement(&signer, testKeyLoc, a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -700,9 +701,8 @@ func createChannelAnnouncement(blockHeight uint32, key1, key2 *btcec.PrivateKey,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pub = bitcoinKeyPriv2.PubKey()
|
|
||||||
signer = mock.SingleSigner{Privkey: bitcoinKeyPriv2}
|
signer = mock.SingleSigner{Privkey: bitcoinKeyPriv2}
|
||||||
sig, err = netann.SignAnnouncement(&signer, pub, a)
|
sig, err = netann.SignAnnouncement(&signer, testKeyLoc, a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -785,7 +785,7 @@ func createTestCtx(startHeight uint32) (*testCtx, func(), error) {
|
|||||||
MinimumBatchSize: 10,
|
MinimumBatchSize: 10,
|
||||||
MaxChannelUpdateBurst: DefaultMaxChannelUpdateBurst,
|
MaxChannelUpdateBurst: DefaultMaxChannelUpdateBurst,
|
||||||
ChannelUpdateInterval: DefaultChannelUpdateInterval,
|
ChannelUpdateInterval: DefaultChannelUpdateInterval,
|
||||||
}, selfKeyPub)
|
}, selfKeyDesc)
|
||||||
|
|
||||||
if err := gossiper.Start(); err != nil {
|
if err := gossiper.Start(); err != nil {
|
||||||
cleanUpDb()
|
cleanUpDb()
|
||||||
@ -1480,7 +1480,10 @@ func TestSignatureAnnouncementRetryAtStartup(t *testing.T) {
|
|||||||
NumActiveSyncers: 3,
|
NumActiveSyncers: 3,
|
||||||
MinimumBatchSize: 10,
|
MinimumBatchSize: 10,
|
||||||
SubBatchDelay: time.Second * 5,
|
SubBatchDelay: time.Second * 5,
|
||||||
}, ctx.gossiper.selfKey)
|
}, &keychain.KeyDescriptor{
|
||||||
|
PubKey: ctx.gossiper.selfKey,
|
||||||
|
KeyLocator: ctx.gossiper.selfKeyLoc,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to recreate gossiper: %v", err)
|
t.Fatalf("unable to recreate gossiper: %v", err)
|
||||||
}
|
}
|
||||||
@ -2056,7 +2059,9 @@ func TestForwardPrivateNodeAnnouncement(t *testing.T) {
|
|||||||
// We'll start off by processing a channel announcement without a proof
|
// We'll start off by processing a channel announcement without a proof
|
||||||
// (i.e., an unadvertised channel), followed by a node announcement for
|
// (i.e., an unadvertised channel), followed by a node announcement for
|
||||||
// this same channel announcement.
|
// this same channel announcement.
|
||||||
chanAnn := createAnnouncementWithoutProof(startingHeight-2, selfKeyPub, remoteKeyPub1)
|
chanAnn := createAnnouncementWithoutProof(
|
||||||
|
startingHeight-2, selfKeyDesc.PubKey, remoteKeyPub1,
|
||||||
|
)
|
||||||
pubKey := remoteKeyPriv1.PubKey()
|
pubKey := remoteKeyPriv1.PubKey()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
@ -3671,8 +3676,12 @@ func TestProcessChannelAnnouncementOptionalMsgFields(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
chanAnn1 := createAnnouncementWithoutProof(100, selfKeyPub, remoteKeyPub1)
|
chanAnn1 := createAnnouncementWithoutProof(
|
||||||
chanAnn2 := createAnnouncementWithoutProof(101, selfKeyPub, remoteKeyPub1)
|
100, selfKeyDesc.PubKey, remoteKeyPub1,
|
||||||
|
)
|
||||||
|
chanAnn2 := createAnnouncementWithoutProof(
|
||||||
|
101, selfKeyDesc.PubKey, remoteKeyPub1,
|
||||||
|
)
|
||||||
|
|
||||||
// assertOptionalMsgFields is a helper closure that ensures the optional
|
// assertOptionalMsgFields is a helper closure that ensures the optional
|
||||||
// message fields were set as intended.
|
// message fields were set as intended.
|
||||||
|
@ -294,6 +294,10 @@ type Config struct {
|
|||||||
// Lightning Network.
|
// Lightning Network.
|
||||||
IDKey *btcec.PublicKey
|
IDKey *btcec.PublicKey
|
||||||
|
|
||||||
|
// IDKeyLoc is the locator for the key that is used to identify this
|
||||||
|
// node within the LightningNetwork.
|
||||||
|
IDKeyLoc keychain.KeyLocator
|
||||||
|
|
||||||
// Wallet handles the parts of the funding process that involves moving
|
// Wallet handles the parts of the funding process that involves moving
|
||||||
// funds from on-chain transaction outputs into Lightning channels.
|
// funds from on-chain transaction outputs into Lightning channels.
|
||||||
Wallet *lnwallet.LightningWallet
|
Wallet *lnwallet.LightningWallet
|
||||||
@ -322,8 +326,8 @@ type Config struct {
|
|||||||
//
|
//
|
||||||
// TODO(roasbeef): should instead pass on this responsibility to a
|
// TODO(roasbeef): should instead pass on this responsibility to a
|
||||||
// distinct sub-system?
|
// distinct sub-system?
|
||||||
SignMessage func(pubKey *btcec.PublicKey,
|
SignMessage func(keyLoc keychain.KeyLocator,
|
||||||
msg []byte) (input.Signature, error)
|
msg []byte) (*btcec.Signature, error)
|
||||||
|
|
||||||
// CurrentNodeAnnouncement should return the latest, fully signed node
|
// CurrentNodeAnnouncement should return the latest, fully signed node
|
||||||
// announcement from the backing Lightning Network node.
|
// announcement from the backing Lightning Network node.
|
||||||
@ -2523,7 +2527,7 @@ func (f *Manager) addToRouterGraph(completeChan *channeldb.OpenChannel,
|
|||||||
|
|
||||||
ann, err := f.newChanAnnouncement(
|
ann, err := f.newChanAnnouncement(
|
||||||
f.cfg.IDKey, completeChan.IdentityPub,
|
f.cfg.IDKey, completeChan.IdentityPub,
|
||||||
completeChan.LocalChanCfg.MultiSigKey.PubKey,
|
&completeChan.LocalChanCfg.MultiSigKey,
|
||||||
completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
|
completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
|
||||||
chanID, fwdMinHTLC, fwdMaxHTLC,
|
chanID, fwdMinHTLC, fwdMaxHTLC,
|
||||||
)
|
)
|
||||||
@ -2686,7 +2690,7 @@ func (f *Manager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
|
|||||||
// public and usable for other nodes for routing.
|
// public and usable for other nodes for routing.
|
||||||
err = f.announceChannel(
|
err = f.announceChannel(
|
||||||
f.cfg.IDKey, completeChan.IdentityPub,
|
f.cfg.IDKey, completeChan.IdentityPub,
|
||||||
completeChan.LocalChanCfg.MultiSigKey.PubKey,
|
&completeChan.LocalChanCfg.MultiSigKey,
|
||||||
completeChan.RemoteChanCfg.MultiSigKey.PubKey,
|
completeChan.RemoteChanCfg.MultiSigKey.PubKey,
|
||||||
*shortChanID, chanID,
|
*shortChanID, chanID,
|
||||||
)
|
)
|
||||||
@ -2826,10 +2830,11 @@ type chanAnnouncement struct {
|
|||||||
// identity pub keys of both parties to the channel, and the second segment is
|
// identity pub keys of both parties to the channel, and the second segment is
|
||||||
// authenticated only by us and contains our directional routing policy for the
|
// authenticated only by us and contains our directional routing policy for the
|
||||||
// channel.
|
// channel.
|
||||||
func (f *Manager) newChanAnnouncement(localPubKey, remotePubKey,
|
func (f *Manager) newChanAnnouncement(localPubKey,
|
||||||
localFundingKey, remoteFundingKey *btcec.PublicKey,
|
remotePubKey *btcec.PublicKey, localFundingKey *keychain.KeyDescriptor,
|
||||||
shortChanID lnwire.ShortChannelID, chanID lnwire.ChannelID,
|
remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
|
||||||
fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi) (*chanAnnouncement, error) {
|
chanID lnwire.ChannelID, fwdMinHTLC,
|
||||||
|
fwdMaxHTLC lnwire.MilliSatoshi) (*chanAnnouncement, error) {
|
||||||
|
|
||||||
chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
|
chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
|
||||||
|
|
||||||
@ -2857,7 +2862,7 @@ func (f *Manager) newChanAnnouncement(localPubKey, remotePubKey,
|
|||||||
if bytes.Compare(selfBytes, remoteBytes) == -1 {
|
if bytes.Compare(selfBytes, remoteBytes) == -1 {
|
||||||
copy(chanAnn.NodeID1[:], localPubKey.SerializeCompressed())
|
copy(chanAnn.NodeID1[:], localPubKey.SerializeCompressed())
|
||||||
copy(chanAnn.NodeID2[:], remotePubKey.SerializeCompressed())
|
copy(chanAnn.NodeID2[:], remotePubKey.SerializeCompressed())
|
||||||
copy(chanAnn.BitcoinKey1[:], localFundingKey.SerializeCompressed())
|
copy(chanAnn.BitcoinKey1[:], localFundingKey.PubKey.SerializeCompressed())
|
||||||
copy(chanAnn.BitcoinKey2[:], remoteFundingKey.SerializeCompressed())
|
copy(chanAnn.BitcoinKey2[:], remoteFundingKey.SerializeCompressed())
|
||||||
|
|
||||||
// If we're the first node then update the chanFlags to
|
// If we're the first node then update the chanFlags to
|
||||||
@ -2867,7 +2872,7 @@ func (f *Manager) newChanAnnouncement(localPubKey, remotePubKey,
|
|||||||
copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
|
copy(chanAnn.NodeID1[:], remotePubKey.SerializeCompressed())
|
||||||
copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
|
copy(chanAnn.NodeID2[:], localPubKey.SerializeCompressed())
|
||||||
copy(chanAnn.BitcoinKey1[:], remoteFundingKey.SerializeCompressed())
|
copy(chanAnn.BitcoinKey1[:], remoteFundingKey.SerializeCompressed())
|
||||||
copy(chanAnn.BitcoinKey2[:], localFundingKey.SerializeCompressed())
|
copy(chanAnn.BitcoinKey2[:], localFundingKey.PubKey.SerializeCompressed())
|
||||||
|
|
||||||
// If we're the second node then update the chanFlags to
|
// If we're the second node then update the chanFlags to
|
||||||
// indicate the "direction" of the update.
|
// indicate the "direction" of the update.
|
||||||
@ -2906,7 +2911,7 @@ func (f *Manager) newChanAnnouncement(localPubKey, remotePubKey,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sig, err := f.cfg.SignMessage(f.cfg.IDKey, chanUpdateMsg)
|
sig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanUpdateMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("unable to generate channel "+
|
return nil, errors.Errorf("unable to generate channel "+
|
||||||
"update announcement signature: %v", err)
|
"update announcement signature: %v", err)
|
||||||
@ -2928,12 +2933,14 @@ func (f *Manager) newChanAnnouncement(localPubKey, remotePubKey,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
nodeSig, err := f.cfg.SignMessage(f.cfg.IDKey, chanAnnMsg)
|
nodeSig, err := f.cfg.SignMessage(f.cfg.IDKeyLoc, chanAnnMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("unable to generate node "+
|
return nil, errors.Errorf("unable to generate node "+
|
||||||
"signature for channel announcement: %v", err)
|
"signature for channel announcement: %v", err)
|
||||||
}
|
}
|
||||||
bitcoinSig, err := f.cfg.SignMessage(localFundingKey, chanAnnMsg)
|
bitcoinSig, err := f.cfg.SignMessage(
|
||||||
|
localFundingKey.KeyLocator, chanAnnMsg,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("unable to generate bitcoin "+
|
return nil, errors.Errorf("unable to generate bitcoin "+
|
||||||
"signature for node public key: %v", err)
|
"signature for node public key: %v", err)
|
||||||
@ -2969,7 +2976,8 @@ func (f *Manager) newChanAnnouncement(localPubKey, remotePubKey,
|
|||||||
// the network during its next trickle.
|
// the network during its next trickle.
|
||||||
// This method is synchronous and will return when all the network requests
|
// This method is synchronous and will return when all the network requests
|
||||||
// finish, either successfully or with an error.
|
// finish, either successfully or with an error.
|
||||||
func (f *Manager) announceChannel(localIDKey, remoteIDKey, localFundingKey,
|
func (f *Manager) announceChannel(localIDKey, remoteIDKey *btcec.PublicKey,
|
||||||
|
localFundingKey *keychain.KeyDescriptor,
|
||||||
remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
|
remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
|
||||||
chanID lnwire.ChannelID) error {
|
chanID lnwire.ChannelID) error {
|
||||||
|
|
||||||
|
@ -110,6 +110,8 @@ var (
|
|||||||
_, _ = testSig.R.SetString("63724406601629180062774974542967536251589935445068131219452686511677818569431", 10)
|
_, _ = testSig.R.SetString("63724406601629180062774974542967536251589935445068131219452686511677818569431", 10)
|
||||||
_, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10)
|
_, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10)
|
||||||
|
|
||||||
|
testKeyLoc = keychain.KeyLocator{Family: keychain.KeyFamilyNodeKey}
|
||||||
|
|
||||||
fundingNetParams = chainreg.BitcoinTestNetParams
|
fundingNetParams = chainreg.BitcoinTestNetParams
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -355,11 +357,12 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
|
|||||||
|
|
||||||
fundingCfg := Config{
|
fundingCfg := Config{
|
||||||
IDKey: privKey.PubKey(),
|
IDKey: privKey.PubKey(),
|
||||||
|
IDKeyLoc: testKeyLoc,
|
||||||
Wallet: lnw,
|
Wallet: lnw,
|
||||||
Notifier: chainNotifier,
|
Notifier: chainNotifier,
|
||||||
FeeEstimator: estimator,
|
FeeEstimator: estimator,
|
||||||
SignMessage: func(pubKey *btcec.PublicKey,
|
SignMessage: func(_ keychain.KeyLocator,
|
||||||
msg []byte) (input.Signature, error) {
|
_ []byte) (*btcec.Signature, error) {
|
||||||
|
|
||||||
return testSig, nil
|
return testSig, nil
|
||||||
},
|
},
|
||||||
@ -502,11 +505,13 @@ func recreateAliceFundingManager(t *testing.T, alice *testNode) {
|
|||||||
|
|
||||||
f, err := NewFundingManager(Config{
|
f, err := NewFundingManager(Config{
|
||||||
IDKey: oldCfg.IDKey,
|
IDKey: oldCfg.IDKey,
|
||||||
|
IDKeyLoc: oldCfg.IDKeyLoc,
|
||||||
Wallet: oldCfg.Wallet,
|
Wallet: oldCfg.Wallet,
|
||||||
Notifier: oldCfg.Notifier,
|
Notifier: oldCfg.Notifier,
|
||||||
FeeEstimator: oldCfg.FeeEstimator,
|
FeeEstimator: oldCfg.FeeEstimator,
|
||||||
SignMessage: func(pubKey *btcec.PublicKey,
|
SignMessage: func(_ keychain.KeyLocator,
|
||||||
msg []byte) (input.Signature, error) {
|
_ []byte) (*btcec.Signature, error) {
|
||||||
|
|
||||||
return testSig, nil
|
return testSig, nil
|
||||||
},
|
},
|
||||||
SendAnnouncement: func(msg lnwire.Message,
|
SendAnnouncement: func(msg lnwire.Message,
|
||||||
|
@ -211,6 +211,10 @@ type SingleKeyMessageSigner interface {
|
|||||||
// PubKey returns the public key of the wrapped private key.
|
// PubKey returns the public key of the wrapped private key.
|
||||||
PubKey() *btcec.PublicKey
|
PubKey() *btcec.PublicKey
|
||||||
|
|
||||||
|
// KeyLocator returns the locator that describes the wrapped private
|
||||||
|
// key.
|
||||||
|
KeyLocator() KeyLocator
|
||||||
|
|
||||||
// SignMessage signs the given message, single or double SHA256 hashing
|
// SignMessage signs the given message, single or double SHA256 hashing
|
||||||
// it first, with the wrapped private key.
|
// it first, with the wrapped private key.
|
||||||
SignMessage(message []byte, doubleHash bool) (*btcec.Signature, error)
|
SignMessage(message []byte, doubleHash bool) (*btcec.Signature, error)
|
||||||
|
@ -25,6 +25,10 @@ func (p *PubKeyMessageSigner) PubKey() *btcec.PublicKey {
|
|||||||
return p.pubKey
|
return p.pubKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PubKeyMessageSigner) KeyLocator() KeyLocator {
|
||||||
|
return p.keyLoc
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PubKeyMessageSigner) SignMessage(message []byte,
|
func (p *PubKeyMessageSigner) SignMessage(message []byte,
|
||||||
doubleHash bool) (*btcec.Signature, error) {
|
doubleHash bool) (*btcec.Signature, error) {
|
||||||
|
|
||||||
@ -37,12 +41,26 @@ func (p *PubKeyMessageSigner) SignMessageCompact(msg []byte,
|
|||||||
return p.digestSigner.SignMessageCompact(p.keyLoc, msg, doubleHash)
|
return p.digestSigner.SignMessageCompact(p.keyLoc, msg, doubleHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewPrivKeyMessageSigner(privKey *btcec.PrivateKey,
|
||||||
|
keyLoc KeyLocator) *PrivKeyMessageSigner {
|
||||||
|
|
||||||
|
return &PrivKeyMessageSigner{
|
||||||
|
privKey: privKey,
|
||||||
|
keyLoc: keyLoc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type PrivKeyMessageSigner struct {
|
type PrivKeyMessageSigner struct {
|
||||||
PrivKey *btcec.PrivateKey
|
keyLoc KeyLocator
|
||||||
|
privKey *btcec.PrivateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PrivKeyMessageSigner) PubKey() *btcec.PublicKey {
|
func (p *PrivKeyMessageSigner) PubKey() *btcec.PublicKey {
|
||||||
return p.PrivKey.PubKey()
|
return p.privKey.PubKey()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrivKeyMessageSigner) KeyLocator() KeyLocator {
|
||||||
|
return p.keyLoc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PrivKeyMessageSigner) SignMessage(msg []byte,
|
func (p *PrivKeyMessageSigner) SignMessage(msg []byte,
|
||||||
@ -54,7 +72,7 @@ func (p *PrivKeyMessageSigner) SignMessage(msg []byte,
|
|||||||
} else {
|
} else {
|
||||||
digest = chainhash.HashB(msg)
|
digest = chainhash.HashB(msg)
|
||||||
}
|
}
|
||||||
return p.PrivKey.Sign(digest)
|
return p.privKey.Sign(digest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PrivKeyMessageSigner) SignMessageCompact(msg []byte,
|
func (p *PrivKeyMessageSigner) SignMessageCompact(msg []byte,
|
||||||
@ -66,7 +84,7 @@ func (p *PrivKeyMessageSigner) SignMessageCompact(msg []byte,
|
|||||||
} else {
|
} else {
|
||||||
digest = chainhash.HashB(msg)
|
digest = chainhash.HashB(msg)
|
||||||
}
|
}
|
||||||
return btcec.SignCompact(btcec.S256(), p.PrivKey, digest, true)
|
return btcec.SignCompact(btcec.S256(), p.privKey, digest, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ SingleKeyMessageSigner = (*PubKeyMessageSigner)(nil)
|
var _ SingleKeyMessageSigner = (*PubKeyMessageSigner)(nil)
|
||||||
|
@ -7,8 +7,12 @@ import (
|
|||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
idKeyLoc = keychain.KeyLocator{Family: keychain.KeyFamilyNodeKey}
|
||||||
)
|
)
|
||||||
|
|
||||||
// DummySignature is a dummy Signature implementation.
|
// DummySignature is a dummy Signature implementation.
|
||||||
@ -46,6 +50,7 @@ func (d *DummySigner) ComputeInputScript(tx *wire.MsgTx,
|
|||||||
// everything with a single private key.
|
// everything with a single private key.
|
||||||
type SingleSigner struct {
|
type SingleSigner struct {
|
||||||
Privkey *btcec.PrivateKey
|
Privkey *btcec.PrivateKey
|
||||||
|
KeyLoc keychain.KeyLocator
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignOutputRaw generates a signature for the passed transaction using the
|
// SignOutputRaw generates a signature for the passed transaction using the
|
||||||
@ -110,10 +115,15 @@ func (s *SingleSigner) ComputeInputScript(tx *wire.MsgTx,
|
|||||||
|
|
||||||
// SignMessage takes a public key and a message and only signs the message
|
// SignMessage takes a public key and a message and only signs the message
|
||||||
// with the stored private key if the public key matches the private key.
|
// with the stored private key if the public key matches the private key.
|
||||||
func (s *SingleSigner) SignMessage(pubKey *btcec.PublicKey,
|
func (s *SingleSigner) SignMessage(keyLoc keychain.KeyLocator,
|
||||||
msg []byte) (input.Signature, error) {
|
msg []byte) (*btcec.Signature, error) {
|
||||||
|
|
||||||
if !pubKey.IsEqual(s.Privkey.PubKey()) {
|
mockKeyLoc := s.KeyLoc
|
||||||
|
if s.KeyLoc.IsEmpty() {
|
||||||
|
mockKeyLoc = idKeyLoc
|
||||||
|
}
|
||||||
|
|
||||||
|
if keyLoc != mockKeyLoc {
|
||||||
return nil, fmt.Errorf("unknown public key")
|
return nil, fmt.Errorf("unknown public key")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,11 +126,13 @@ func (b *BtcWallet) deriveKeyByLocator(keyLoc keychain.KeyLocator) (*btcec.Priva
|
|||||||
|
|
||||||
// fetchPrivKey attempts to retrieve the raw private key corresponding to the
|
// fetchPrivKey attempts to retrieve the raw private key corresponding to the
|
||||||
// passed public key if populated, or the key descriptor path (if non-empty).
|
// passed public key if populated, or the key descriptor path (if non-empty).
|
||||||
func (b *BtcWallet) fetchPrivKey(keyDesc *keychain.KeyDescriptor) (*btcec.PrivateKey, error) {
|
func (b *BtcWallet) fetchPrivKey(
|
||||||
|
keyDesc *keychain.KeyDescriptor) (*btcec.PrivateKey, error) {
|
||||||
|
|
||||||
// If the key locator within the descriptor *isn't* empty, then we can
|
// If the key locator within the descriptor *isn't* empty, then we can
|
||||||
// directly derive the keys raw.
|
// directly derive the keys raw.
|
||||||
emptyLocator := keyDesc.KeyLocator.IsEmpty()
|
emptyLocator := keyDesc.KeyLocator.IsEmpty()
|
||||||
if !emptyLocator {
|
if !emptyLocator || keyDesc.PubKey == nil {
|
||||||
return b.deriveKeyByLocator(keyDesc.KeyLocator)
|
return b.deriveKeyByLocator(keyDesc.KeyLocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,18 +261,18 @@ func (b *BtcWallet) ComputeInputScript(tx *wire.MsgTx,
|
|||||||
var _ input.Signer = (*BtcWallet)(nil)
|
var _ input.Signer = (*BtcWallet)(nil)
|
||||||
|
|
||||||
// SignMessage attempts to sign a target message with the private key that
|
// SignMessage attempts to sign a target message with the private key that
|
||||||
// corresponds to the passed public key. If the target private key is unable to
|
// corresponds to the passed key locator. If the target private key is unable to
|
||||||
// be found, then an error will be returned. The actual digest signed is the
|
// be found, then an error will be returned. The actual digest signed is the
|
||||||
// double SHA-256 of the passed message.
|
// double SHA-256 of the passed message.
|
||||||
//
|
//
|
||||||
// NOTE: This is a part of the MessageSigner interface.
|
// NOTE: This is a part of the MessageSigner interface.
|
||||||
func (b *BtcWallet) SignMessage(pubKey *btcec.PublicKey,
|
func (b *BtcWallet) SignMessage(keyLoc keychain.KeyLocator,
|
||||||
msg []byte) (input.Signature, error) {
|
msg []byte) (*btcec.Signature, error) {
|
||||||
|
|
||||||
// First attempt to fetch the private key which corresponds to the
|
// First attempt to fetch the private key which corresponds to the
|
||||||
// specified public key.
|
// specified public key.
|
||||||
privKey, err := b.fetchPrivKey(&keychain.KeyDescriptor{
|
privKey, err := b.fetchPrivKey(&keychain.KeyDescriptor{
|
||||||
PubKey: pubKey,
|
KeyLocator: keyLoc,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/btcsuite/btcwallet/waddrmgr"
|
"github.com/btcsuite/btcwallet/waddrmgr"
|
||||||
"github.com/btcsuite/btcwallet/wallet/txauthor"
|
"github.com/btcsuite/btcwallet/wallet/txauthor"
|
||||||
"github.com/btcsuite/btcwallet/wtxmgr"
|
"github.com/btcsuite/btcwallet/wtxmgr"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -440,10 +440,11 @@ type BlockChainIO interface {
|
|||||||
// to attest to some message.
|
// to attest to some message.
|
||||||
type MessageSigner interface {
|
type MessageSigner interface {
|
||||||
// SignMessage attempts to sign a target message with the private key
|
// SignMessage attempts to sign a target message with the private key
|
||||||
// that corresponds to the passed public key. If the target private key
|
// described in the key locator. If the target private key is unable to
|
||||||
// is unable to be found, then an error will be returned. The actual
|
// be found, then an error will be returned. The actual digest signed is
|
||||||
// digest signed is the double SHA-256 of the passed message.
|
// the double SHA-256 of the passed message.
|
||||||
SignMessage(pubKey *btcec.PublicKey, msg []byte) (input.Signature, error)
|
SignMessage(keyLoc keychain.KeyLocator, msg []byte) (*btcec.Signature,
|
||||||
|
error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WalletDriver represents a "driver" for a particular concrete
|
// WalletDriver represents a "driver" for a particular concrete
|
||||||
|
@ -70,6 +70,12 @@ func NewSigFromSignature(e input.Signature) (Sig, error) {
|
|||||||
return Sig{}, fmt.Errorf("cannot decode empty signature")
|
return Sig{}, fmt.Errorf("cannot decode empty signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nil is still a valid interface, apparently. So we need a more
|
||||||
|
// explicit check here.
|
||||||
|
if ecsig, ok := e.(*btcec.Signature); ok && ecsig == nil {
|
||||||
|
return Sig{}, fmt.Errorf("cannot decode empty signature")
|
||||||
|
}
|
||||||
|
|
||||||
// Serialize the signature with all the checks that entails.
|
// Serialize the signature with all the checks that entails.
|
||||||
return NewSigFromRawSignature(e.Serialize())
|
return NewSigFromRawSignature(e.Serialize())
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
)
|
)
|
||||||
@ -43,6 +44,10 @@ type ChanStatusConfig struct {
|
|||||||
// OurPubKey is the public key identifying this node on the network.
|
// OurPubKey is the public key identifying this node on the network.
|
||||||
OurPubKey *btcec.PublicKey
|
OurPubKey *btcec.PublicKey
|
||||||
|
|
||||||
|
// OurKeyLoc is the locator for the public key identifying this node on
|
||||||
|
// the network.
|
||||||
|
OurKeyLoc keychain.KeyLocator
|
||||||
|
|
||||||
// MessageSigner signs messages that validate under OurPubKey.
|
// MessageSigner signs messages that validate under OurPubKey.
|
||||||
MessageSigner lnwallet.MessageSigner
|
MessageSigner lnwallet.MessageSigner
|
||||||
|
|
||||||
@ -621,7 +626,7 @@ func (m *ChanStatusManager) signAndSendNextUpdate(outpoint wire.OutPoint,
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = SignChannelUpdate(
|
err = SignChannelUpdate(
|
||||||
m.cfg.MessageSigner, m.cfg.OurPubKey, chanUpdate,
|
m.cfg.MessageSigner, m.cfg.OurKeyLoc, chanUpdate,
|
||||||
ChanUpdSetDisable(disabled), ChanUpdSetTimestamp,
|
ChanUpdSetDisable(disabled), ChanUpdSetTimestamp,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,6 +19,10 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/netann"
|
"github.com/lightningnetwork/lnd/netann"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
testKeyLoc = keychain.KeyLocator{Family: keychain.KeyFamilyNodeKey}
|
||||||
|
)
|
||||||
|
|
||||||
// randOutpoint creates a random wire.Outpoint.
|
// randOutpoint creates a random wire.Outpoint.
|
||||||
func randOutpoint(t *testing.T) wire.OutPoint {
|
func randOutpoint(t *testing.T) wire.OutPoint {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
@ -310,7 +314,7 @@ func newManagerCfg(t *testing.T, numChannels int,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to generate key pair: %v", err)
|
t.Fatalf("unable to generate key pair: %v", err)
|
||||||
}
|
}
|
||||||
privKeySigner := &keychain.PrivKeyMessageSigner{PrivKey: privKey}
|
privKeySigner := keychain.NewPrivKeyMessageSigner(privKey, testKeyLoc)
|
||||||
|
|
||||||
graph := newMockGraph(
|
graph := newMockGraph(
|
||||||
t, numChannels, startEnabled, startEnabled, privKey.PubKey(),
|
t, numChannels, startEnabled, startEnabled, privKey.PubKey(),
|
||||||
@ -322,6 +326,7 @@ func newManagerCfg(t *testing.T, numChannels int,
|
|||||||
ChanEnableTimeout: 500 * time.Millisecond,
|
ChanEnableTimeout: 500 * time.Millisecond,
|
||||||
ChanDisableTimeout: time.Second,
|
ChanDisableTimeout: time.Second,
|
||||||
OurPubKey: privKey.PubKey(),
|
OurPubKey: privKey.PubKey(),
|
||||||
|
OurKeyLoc: testKeyLoc,
|
||||||
MessageSigner: netann.NewNodeSigner(privKeySigner),
|
MessageSigner: netann.NewNodeSigner(privKeySigner),
|
||||||
IsChannelActive: htlcSwitch.HasActiveLink,
|
IsChannelActive: htlcSwitch.HasActiveLink,
|
||||||
ApplyChannelUpdate: graph.ApplyChannelUpdate,
|
ApplyChannelUpdate: graph.ApplyChannelUpdate,
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
)
|
)
|
||||||
@ -55,7 +56,7 @@ func ChanUpdSetTimestamp(update *lnwire.ChannelUpdate) {
|
|||||||
// monotonically increase from the prior.
|
// monotonically increase from the prior.
|
||||||
//
|
//
|
||||||
// NOTE: This method modifies the given update.
|
// NOTE: This method modifies the given update.
|
||||||
func SignChannelUpdate(signer lnwallet.MessageSigner, pubKey *btcec.PublicKey,
|
func SignChannelUpdate(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator,
|
||||||
update *lnwire.ChannelUpdate, mods ...ChannelUpdateModifier) error {
|
update *lnwire.ChannelUpdate, mods ...ChannelUpdateModifier) error {
|
||||||
|
|
||||||
// Apply the requested changes to the channel update.
|
// Apply the requested changes to the channel update.
|
||||||
@ -64,7 +65,7 @@ func SignChannelUpdate(signer lnwallet.MessageSigner, pubKey *btcec.PublicKey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the DER-encoded ECDSA signature over the message digest.
|
// Create the DER-encoded ECDSA signature over the message digest.
|
||||||
sig, err := SignAnnouncement(signer, pubKey, update)
|
sig, err := SignAnnouncement(signer, keyLoc, update)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
|
||||||
"github.com/lightningnetwork/lnd/keychain"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
@ -18,8 +17,8 @@ type mockSigner struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockSigner) SignMessage(pk *btcec.PublicKey,
|
func (m *mockSigner) SignMessage(_ keychain.KeyLocator,
|
||||||
msg []byte) (input.Signature, error) {
|
_ []byte) (*btcec.Signature, error) {
|
||||||
|
|
||||||
if m.err != nil {
|
if m.err != nil {
|
||||||
return nil, m.err
|
return nil, m.err
|
||||||
@ -32,7 +31,7 @@ var _ lnwallet.MessageSigner = (*mockSigner)(nil)
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
privKey, _ = btcec.NewPrivateKey(btcec.S256())
|
privKey, _ = btcec.NewPrivateKey(btcec.S256())
|
||||||
privKeySigner = &keychain.PrivKeyMessageSigner{PrivKey: privKey}
|
privKeySigner = keychain.NewPrivKeyMessageSigner(privKey, testKeyLoc)
|
||||||
|
|
||||||
pubKey = privKey.PubKey()
|
pubKey = privKey.PubKey()
|
||||||
|
|
||||||
@ -130,7 +129,7 @@ func TestUpdateDisableFlag(t *testing.T) {
|
|||||||
// Attempt to update and sign the new update, specifying
|
// Attempt to update and sign the new update, specifying
|
||||||
// disabled or enabled as prescribed in the test case.
|
// disabled or enabled as prescribed in the test case.
|
||||||
err := netann.SignChannelUpdate(
|
err := netann.SignChannelUpdate(
|
||||||
tc.signer, pubKey, newUpdate,
|
tc.signer, testKeyLoc, newUpdate,
|
||||||
netann.ChanUpdSetDisable(tc.disable),
|
netann.ChanUpdSetDisable(tc.disable),
|
||||||
netann.ChanUpdSetTimestamp,
|
netann.ChanUpdSetTimestamp,
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
)
|
)
|
||||||
@ -40,7 +40,7 @@ func NodeAnnSetTimestamp(nodeAnn *lnwire.NodeAnnouncement) {
|
|||||||
// update should be the most recent, valid update, otherwise the timestamp may
|
// update should be the most recent, valid update, otherwise the timestamp may
|
||||||
// not monotonically increase from the prior.
|
// not monotonically increase from the prior.
|
||||||
func SignNodeAnnouncement(signer lnwallet.MessageSigner,
|
func SignNodeAnnouncement(signer lnwallet.MessageSigner,
|
||||||
pubKey *btcec.PublicKey, nodeAnn *lnwire.NodeAnnouncement,
|
keyLoc keychain.KeyLocator, nodeAnn *lnwire.NodeAnnouncement,
|
||||||
mods ...NodeAnnModifier) error {
|
mods ...NodeAnnModifier) error {
|
||||||
|
|
||||||
// Apply the requested changes to the node announcement.
|
// Apply the requested changes to the node announcement.
|
||||||
@ -49,7 +49,7 @@ func SignNodeAnnouncement(signer lnwallet.MessageSigner,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the DER-encoded ECDSA signature over the message digest.
|
// Create the DER-encoded ECDSA signature over the message digest.
|
||||||
sig, err := SignAnnouncement(signer, pubKey, nodeAnn)
|
sig, err := SignAnnouncement(signer, keyLoc, nodeAnn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
|
||||||
"github.com/lightningnetwork/lnd/keychain"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
)
|
)
|
||||||
@ -24,15 +23,15 @@ func NewNodeSigner(keySigner keychain.SingleKeyMessageSigner) *NodeSigner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SignMessage signs a double-sha256 digest of the passed msg under the
|
// SignMessage signs a double-sha256 digest of the passed msg under the
|
||||||
// resident node's private key. If the target public key is _not_ the node's
|
// resident node's private key described in the key locator. If the target key
|
||||||
// private key, then an error will be returned.
|
// locator is _not_ the node's private key, then an error will be returned.
|
||||||
func (n *NodeSigner) SignMessage(pubKey *btcec.PublicKey,
|
func (n *NodeSigner) SignMessage(keyLoc keychain.KeyLocator,
|
||||||
msg []byte) (input.Signature, error) {
|
msg []byte) (*btcec.Signature, error) {
|
||||||
|
|
||||||
// If this isn't our identity public key, then we'll exit early with an
|
// If this isn't our identity public key, then we'll exit early with an
|
||||||
// error as we can't sign with this key.
|
// error as we can't sign with this key.
|
||||||
if !pubKey.IsEqual(n.keySigner.PubKey()) {
|
if keyLoc != n.keySigner.KeyLocator() {
|
||||||
return nil, fmt.Errorf("unknown public key")
|
return nil, fmt.Errorf("unknown public key locator")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we'll sign the double-sha256 of the target message.
|
// Otherwise, we'll sign the double-sha256 of the target message.
|
||||||
|
@ -3,15 +3,15 @@ package netann
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignAnnouncement signs any type of gossip message that is announced on the
|
// SignAnnouncement signs any type of gossip message that is announced on the
|
||||||
// network.
|
// network.
|
||||||
func SignAnnouncement(signer lnwallet.MessageSigner, pubKey *btcec.PublicKey,
|
func SignAnnouncement(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator,
|
||||||
msg lnwire.Message) (input.Signature, error) {
|
msg lnwire.Message) (input.Signature, error) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -33,5 +33,5 @@ func SignAnnouncement(signer lnwallet.MessageSigner, pubKey *btcec.PublicKey,
|
|||||||
return nil, fmt.Errorf("unable to get data to sign: %v", err)
|
return nil, fmt.Errorf("unable to get data to sign: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return signer.SignMessage(pubKey, data)
|
return signer.SignMessage(keyLoc, data)
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,8 @@ const (
|
|||||||
var (
|
var (
|
||||||
// Just use some arbitrary bytes as delivery script.
|
// Just use some arbitrary bytes as delivery script.
|
||||||
dummyDeliveryScript = channels.AlicesPrivKey
|
dummyDeliveryScript = channels.AlicesPrivKey
|
||||||
|
|
||||||
|
testKeyLoc = keychain.KeyLocator{Family: keychain.KeyFamilyNodeKey}
|
||||||
)
|
)
|
||||||
|
|
||||||
// noUpdate is a function which can be used as a parameter in createTestPeer to
|
// noUpdate is a function which can be used as a parameter in createTestPeer to
|
||||||
@ -58,10 +60,15 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
|
|||||||
mockSwitch *mockMessageSwitch) (
|
mockSwitch *mockMessageSwitch) (
|
||||||
*Brontide, *lnwallet.LightningChannel, func(), error) {
|
*Brontide, *lnwallet.LightningChannel, func(), error) {
|
||||||
|
|
||||||
|
nodeKeyLocator := keychain.KeyLocator{
|
||||||
|
Family: keychain.KeyFamilyNodeKey,
|
||||||
|
}
|
||||||
aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(
|
aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(
|
||||||
btcec.S256(), channels.AlicesPrivKey,
|
btcec.S256(), channels.AlicesPrivKey,
|
||||||
)
|
)
|
||||||
aliceKeySigner := &keychain.PrivKeyMessageSigner{PrivKey: aliceKeyPriv}
|
aliceKeySigner := keychain.NewPrivKeyMessageSigner(
|
||||||
|
aliceKeyPriv, nodeKeyLocator,
|
||||||
|
)
|
||||||
bobKeyPriv, bobKeyPub := btcec.PrivKeyFromBytes(
|
bobKeyPriv, bobKeyPub := btcec.PrivKeyFromBytes(
|
||||||
btcec.S256(), channels.BobsPrivKey,
|
btcec.S256(), channels.BobsPrivKey,
|
||||||
)
|
)
|
||||||
@ -325,6 +332,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
|
|||||||
Graph: dbAlice.ChannelGraph(),
|
Graph: dbAlice.ChannelGraph(),
|
||||||
MessageSigner: nodeSignerAlice,
|
MessageSigner: nodeSignerAlice,
|
||||||
OurPubKey: aliceKeyPub,
|
OurPubKey: aliceKeyPub,
|
||||||
|
OurKeyLoc: testKeyLoc,
|
||||||
IsChannelActive: func(lnwire.ChannelID) bool { return true },
|
IsChannelActive: func(lnwire.ChannelID) bool { return true },
|
||||||
ApplyChannelUpdate: func(*lnwire.ChannelUpdate) error { return nil },
|
ApplyChannelUpdate: func(*lnwire.ChannelUpdate) error { return nil },
|
||||||
})
|
})
|
||||||
|
32
server.go
32
server.go
@ -157,6 +157,9 @@ type server struct {
|
|||||||
// to authenticate any incoming connections.
|
// to authenticate any incoming connections.
|
||||||
identityECDH keychain.SingleKeyECDH
|
identityECDH keychain.SingleKeyECDH
|
||||||
|
|
||||||
|
// identityKeyLoc is the key locator for the above wrapped identity key.
|
||||||
|
identityKeyLoc keychain.KeyLocator
|
||||||
|
|
||||||
// nodeSigner is an implementation of the MessageSigner implementation
|
// nodeSigner is an implementation of the MessageSigner implementation
|
||||||
// that's backed by the identity private key of the running lnd node.
|
// that's backed by the identity private key of the running lnd node.
|
||||||
nodeSigner *netann.NodeSigner
|
nodeSigner *netann.NodeSigner
|
||||||
@ -473,7 +476,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var serializedPubKey [33]byte
|
var serializedPubKey [33]byte
|
||||||
copy(serializedPubKey[:], nodeKeyECDH.PubKey().SerializeCompressed())
|
copy(serializedPubKey[:], nodeKeyDesc.PubKey.SerializeCompressed())
|
||||||
|
|
||||||
// Initialize the sphinx router.
|
// Initialize the sphinx router.
|
||||||
replayLog := htlcswitch.NewDecayedLog(
|
replayLog := htlcswitch.NewDecayedLog(
|
||||||
@ -539,6 +542,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
),
|
),
|
||||||
|
|
||||||
identityECDH: nodeKeyECDH,
|
identityECDH: nodeKeyECDH,
|
||||||
|
identityKeyLoc: nodeKeyDesc.KeyLocator,
|
||||||
nodeSigner: netann.NewNodeSigner(nodeKeySigner),
|
nodeSigner: netann.NewNodeSigner(nodeKeySigner),
|
||||||
|
|
||||||
listenAddrs: listenAddrs,
|
listenAddrs: listenAddrs,
|
||||||
@ -633,7 +637,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
ChanStatusSampleInterval: cfg.ChanStatusSampleInterval,
|
ChanStatusSampleInterval: cfg.ChanStatusSampleInterval,
|
||||||
ChanEnableTimeout: cfg.ChanEnableTimeout,
|
ChanEnableTimeout: cfg.ChanEnableTimeout,
|
||||||
ChanDisableTimeout: cfg.ChanDisableTimeout,
|
ChanDisableTimeout: cfg.ChanDisableTimeout,
|
||||||
OurPubKey: nodeKeyECDH.PubKey(),
|
OurPubKey: nodeKeyDesc.PubKey,
|
||||||
|
OurKeyLoc: nodeKeyDesc.KeyLocator,
|
||||||
MessageSigner: s.nodeSigner,
|
MessageSigner: s.nodeSigner,
|
||||||
IsChannelActive: s.htlcSwitch.HasActiveLink,
|
IsChannelActive: s.htlcSwitch.HasActiveLink,
|
||||||
ApplyChannelUpdate: s.applyChannelUpdate,
|
ApplyChannelUpdate: s.applyChannelUpdate,
|
||||||
@ -761,7 +766,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
Features: s.featureMgr.Get(feature.SetNodeAnn),
|
Features: s.featureMgr.Get(feature.SetNodeAnn),
|
||||||
Color: color,
|
Color: color,
|
||||||
}
|
}
|
||||||
copy(selfNode.PubKeyBytes[:], nodeKeyECDH.PubKey().SerializeCompressed())
|
copy(selfNode.PubKeyBytes[:], nodeKeyDesc.PubKey.SerializeCompressed())
|
||||||
|
|
||||||
// Based on the disk representation of the node announcement generated
|
// Based on the disk representation of the node announcement generated
|
||||||
// above, we'll generate a node announcement that can go out on the
|
// above, we'll generate a node announcement that can go out on the
|
||||||
@ -774,7 +779,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
// With the announcement generated, we'll sign it to properly
|
// With the announcement generated, we'll sign it to properly
|
||||||
// authenticate the message on the network.
|
// authenticate the message on the network.
|
||||||
authSig, err := netann.SignAnnouncement(
|
authSig, err := netann.SignAnnouncement(
|
||||||
s.nodeSigner, nodeKeyECDH.PubKey(), nodeAnn,
|
s.nodeSigner, nodeKeyDesc.KeyLocator, nodeAnn,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to generate signature for "+
|
return nil, fmt.Errorf("unable to generate signature for "+
|
||||||
@ -945,9 +950,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
PinnedSyncers: cfg.Gossip.PinnedSyncers,
|
PinnedSyncers: cfg.Gossip.PinnedSyncers,
|
||||||
MaxChannelUpdateBurst: cfg.Gossip.MaxChannelUpdateBurst,
|
MaxChannelUpdateBurst: cfg.Gossip.MaxChannelUpdateBurst,
|
||||||
ChannelUpdateInterval: cfg.Gossip.ChannelUpdateInterval,
|
ChannelUpdateInterval: cfg.Gossip.ChannelUpdateInterval,
|
||||||
},
|
}, nodeKeyDesc)
|
||||||
nodeKeyECDH.PubKey(),
|
|
||||||
)
|
|
||||||
|
|
||||||
s.localChanMgr = &localchans.Manager{
|
s.localChanMgr = &localchans.Manager{
|
||||||
ForAllOutgoingChannels: s.chanRouter.ForAllOutgoingChannels,
|
ForAllOutgoingChannels: s.chanRouter.ForAllOutgoingChannels,
|
||||||
@ -1153,7 +1156,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
|
|
||||||
s.fundingMgr, err = funding.NewFundingManager(funding.Config{
|
s.fundingMgr, err = funding.NewFundingManager(funding.Config{
|
||||||
NoWumboChans: !cfg.ProtocolOptions.Wumbo(),
|
NoWumboChans: !cfg.ProtocolOptions.Wumbo(),
|
||||||
IDKey: nodeKeyECDH.PubKey(),
|
IDKey: nodeKeyDesc.PubKey,
|
||||||
|
IDKeyLoc: nodeKeyDesc.KeyLocator,
|
||||||
Wallet: cc.Wallet,
|
Wallet: cc.Wallet,
|
||||||
PublishTransaction: cc.Wallet.PublishTransaction,
|
PublishTransaction: cc.Wallet.PublishTransaction,
|
||||||
UpdateLabel: func(hash chainhash.Hash, label string) error {
|
UpdateLabel: func(hash chainhash.Hash, label string) error {
|
||||||
@ -1161,15 +1165,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
},
|
},
|
||||||
Notifier: cc.ChainNotifier,
|
Notifier: cc.ChainNotifier,
|
||||||
FeeEstimator: cc.FeeEstimator,
|
FeeEstimator: cc.FeeEstimator,
|
||||||
SignMessage: func(pubKey *btcec.PublicKey,
|
SignMessage: cc.MsgSigner.SignMessage,
|
||||||
msg []byte) (input.Signature, error) {
|
|
||||||
|
|
||||||
if pubKey.IsEqual(nodeKeyECDH.PubKey()) {
|
|
||||||
return s.nodeSigner.SignMessage(pubKey, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return cc.MsgSigner.SignMessage(pubKey, msg)
|
|
||||||
},
|
|
||||||
CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement, error) {
|
CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement, error) {
|
||||||
return s.genNodeAnnouncement(true)
|
return s.genNodeAnnouncement(true)
|
||||||
},
|
},
|
||||||
@ -2616,7 +2612,7 @@ func (s *server) genNodeAnnouncement(refresh bool,
|
|||||||
// Otherwise, we'll sign a new update after applying all of the passed
|
// Otherwise, we'll sign a new update after applying all of the passed
|
||||||
// modifiers.
|
// modifiers.
|
||||||
err := netann.SignNodeAnnouncement(
|
err := netann.SignNodeAnnouncement(
|
||||||
s.nodeSigner, s.identityECDH.PubKey(), s.currentNodeAnn,
|
s.nodeSigner, s.identityKeyLoc, s.currentNodeAnn,
|
||||||
modifiers...,
|
modifiers...,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user