discovery: add new set of tests to ensure we validate w/ extra data
This commit is contained in:
parent
841e24399c
commit
88aa74be57
@ -372,10 +372,9 @@ func createAnnouncements(blockHeight uint32) (*annBatch, error) {
|
||||
}
|
||||
|
||||
func createNodeAnnouncement(priv *btcec.PrivateKey,
|
||||
timestamp uint32) (*lnwire.NodeAnnouncement,
|
||||
error) {
|
||||
var err error
|
||||
timestamp uint32, extraBytes ...[]byte) (*lnwire.NodeAnnouncement, error) {
|
||||
|
||||
var err error
|
||||
k := hex.EncodeToString(priv.Serialize())
|
||||
alias, err := lnwire.NewNodeAlias("kek" + k[:10])
|
||||
if err != nil {
|
||||
@ -389,6 +388,9 @@ func createNodeAnnouncement(priv *btcec.PrivateKey,
|
||||
Features: testFeatures,
|
||||
}
|
||||
copy(a.NodeID[:], priv.PubKey().SerializeCompressed())
|
||||
if len(extraBytes) == 1 {
|
||||
a.ExtraOpaqueData = extraBytes[0]
|
||||
}
|
||||
|
||||
signer := mockSigner{priv}
|
||||
sig, err := SignAnnouncement(&signer, priv.PubKey(), a)
|
||||
@ -405,8 +407,8 @@ func createNodeAnnouncement(priv *btcec.PrivateKey,
|
||||
}
|
||||
|
||||
func createUpdateAnnouncement(blockHeight uint32, flags lnwire.ChanUpdateFlag,
|
||||
nodeKey *btcec.PrivateKey, timestamp uint32) (*lnwire.ChannelUpdate,
|
||||
error) {
|
||||
nodeKey *btcec.PrivateKey, timestamp uint32,
|
||||
extraBytes ...[]byte) (*lnwire.ChannelUpdate, error) {
|
||||
|
||||
var err error
|
||||
|
||||
@ -421,6 +423,9 @@ func createUpdateAnnouncement(blockHeight uint32, flags lnwire.ChanUpdateFlag,
|
||||
FeeRate: uint32(prand.Int31()),
|
||||
BaseFee: uint32(prand.Int31()),
|
||||
}
|
||||
if len(extraBytes) == 1 {
|
||||
a.ExtraOpaqueData = extraBytes[0]
|
||||
}
|
||||
|
||||
pub := nodeKey.PubKey()
|
||||
signer := mockSigner{nodeKey}
|
||||
@ -437,7 +442,8 @@ func createUpdateAnnouncement(blockHeight uint32, flags lnwire.ChanUpdateFlag,
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func createRemoteChannelAnnouncement(blockHeight uint32) (*lnwire.ChannelAnnouncement, error) {
|
||||
func createRemoteChannelAnnouncement(blockHeight uint32,
|
||||
extraBytes ...[]byte) (*lnwire.ChannelAnnouncement, error) {
|
||||
|
||||
var err error
|
||||
a := &lnwire.ChannelAnnouncement{
|
||||
@ -452,6 +458,9 @@ func createRemoteChannelAnnouncement(blockHeight uint32) (*lnwire.ChannelAnnounc
|
||||
copy(a.NodeID2[:], nodeKeyPub2.SerializeCompressed())
|
||||
copy(a.BitcoinKey1[:], bitcoinKeyPub1.SerializeCompressed())
|
||||
copy(a.BitcoinKey2[:], bitcoinKeyPub2.SerializeCompressed())
|
||||
if len(extraBytes) == 1 {
|
||||
a.ExtraOpaqueData = extraBytes[0]
|
||||
}
|
||||
|
||||
pub := nodeKeyPriv1.PubKey()
|
||||
signer := mockSigner{nodeKeyPriv1}
|
||||
@ -1736,7 +1745,6 @@ func TestDeDuplicatedAnnouncements(t *testing.T) {
|
||||
// same channel ID. Adding this shouldn't cause an increase in the
|
||||
// number of items as they should be de-duplicated.
|
||||
ca2, err := createRemoteChannelAnnouncement(0)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("can't create remote channel announcement: %v", err)
|
||||
}
|
||||
@ -2146,6 +2154,143 @@ func TestReceiveRemoteChannelUpdateFirst(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestExtraDataChannelAnnouncementValidation tests that we're able to properly
|
||||
// validate a ChannelAnnouncement that includes opaque bytes that we don't
|
||||
// currently know of.
|
||||
func TestExtraDataChannelAnnouncementValidation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx, cleanup, err := createTestCtx(0)
|
||||
if err != nil {
|
||||
t.Fatalf("can't create context: %v", err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
remotePeer := &mockPeer{nodeKeyPriv1.PubKey(), nil, nil}
|
||||
|
||||
// We'll now create an announcement that contains an extra set of bytes
|
||||
// that we don't know of ourselves, but should still include in the
|
||||
// final signature check.
|
||||
extraBytes := []byte("gotta validate this stil!")
|
||||
ca, err := createRemoteChannelAnnouncement(0, extraBytes)
|
||||
if err != nil {
|
||||
t.Fatalf("can't create channel announcement: %v", err)
|
||||
}
|
||||
|
||||
// We'll now send the announcement to the main gossiper. We should be
|
||||
// able to validate this announcement to problem.
|
||||
select {
|
||||
case err = <-ctx.gossiper.ProcessRemoteAnnouncement(ca, remotePeer):
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("did not process remote announcement")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("unable to process :%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestExtraDataChannelUpdateValidation tests that we're able to properly
|
||||
// validate a ChannelUpdate that includes opaque bytes that we don't currently
|
||||
// know of.
|
||||
func TestExtraDataChannelUpdateValidation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx, cleanup, err := createTestCtx(0)
|
||||
if err != nil {
|
||||
t.Fatalf("can't create context: %v", err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
remotePeer := &mockPeer{nodeKeyPriv1.PubKey(), nil, nil}
|
||||
timestamp := uint32(123456)
|
||||
|
||||
// In this scenario, we'll create two announcements, one regular
|
||||
// channel announcement, and another channel update announcement, that
|
||||
// has additional data that we won't be interpreting.
|
||||
chanAnn, err := createRemoteChannelAnnouncement(0)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create chan ann: %v", err)
|
||||
}
|
||||
chanUpdAnn1, err := createUpdateAnnouncement(
|
||||
0, 0, nodeKeyPriv1, timestamp,
|
||||
[]byte("must also validate"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create chan up: %v", err)
|
||||
}
|
||||
chanUpdAnn2, err := createUpdateAnnouncement(
|
||||
0, 1, nodeKeyPriv2, timestamp,
|
||||
[]byte("must also validate"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create chan up: %v", err)
|
||||
}
|
||||
|
||||
// We should be able to properly validate all three messages without
|
||||
// any issue.
|
||||
select {
|
||||
case err = <-ctx.gossiper.ProcessRemoteAnnouncement(chanAnn, remotePeer):
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("did not process remote announcement")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("unable to process announcement: %v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case err = <-ctx.gossiper.ProcessRemoteAnnouncement(chanUpdAnn1, remotePeer):
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("did not process remote announcement")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("unable to process announcement: %v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case err = <-ctx.gossiper.ProcessRemoteAnnouncement(chanUpdAnn2, remotePeer):
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("did not process remote announcement")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("unable to process announcement: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestExtraDataNodeAnnouncementValidation tests that we're able to properly
|
||||
// validate a NodeAnnouncement that includes opaque bytes that we don't
|
||||
// currently know of.
|
||||
func TestExtraDataNodeAnnouncementValidation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx, cleanup, err := createTestCtx(0)
|
||||
if err != nil {
|
||||
t.Fatalf("can't create context: %v", err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
remotePeer := &mockPeer{nodeKeyPriv1.PubKey(), nil, nil}
|
||||
timestamp := uint32(123456)
|
||||
|
||||
// We'll create a node announcement that includes a set of opaque data
|
||||
// which we don't know of, but will store anyway in order to ensure
|
||||
// upgrades can flow smoothly in the future.
|
||||
nodeAnn, err := createNodeAnnouncement(
|
||||
nodeKeyPriv1, timestamp, []byte("gotta validate"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("can't create node announcement: %v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case err = <-ctx.gossiper.ProcessRemoteAnnouncement(nodeAnn, remotePeer):
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("did not process remote announcement")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("unable to process announcement: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// mockPeer implements the lnpeer.Peer interface and is used to test the
|
||||
// gossiper's interaction with peers.
|
||||
type mockPeer struct {
|
||||
|
Loading…
Reference in New Issue
Block a user