diff --git a/lnwire/announcement_signatures.go b/lnwire/announcement_signatures.go new file mode 100644 index 00000000..a7da8414 --- /dev/null +++ b/lnwire/announcement_signatures.go @@ -0,0 +1,106 @@ +package lnwire + +import ( + "io" + + "github.com/roasbeef/btcd/btcec" + "github.com/roasbeef/btcd/wire" +) + +// AnnounceSignatures this is a direct message between two endpoints of a +// channel and serves as an opt-in mechanism to allow the announcement of +// the channel to the rest of the network. It contains the necessary +// signatures by the sender to construct the channel announcement message. +type AnnounceSignatures struct { + // ChannelID is the unique description of the funding transaction. + // Channel id is better for users and debugging and short channel id is + // used for quick test on existence of the particular utxo inside the + // block chain, because it contains information about block. + ChannelID wire.OutPoint + + // ShortChannelID is the unique description of the funding + // transaction. It is constructed with the most significant 3 bytes + // as the block height, the next 3 bytes indicating the transaction + // index within the block, and the least significant two bytes + // indicating the output index which pays to the channel. + ShortChannelID ChannelID + + // NodeSignature is the signature which contains the signed announce + // channel message, by this signature we proof that we posses of the + // node pub key and creating the reference node_key -> bitcoin_key. + NodeSignature *btcec.Signature + + // BitcoinSignature is the signature which contains the signed node + // public key, by this signature we proof that we posses of the + // bitcoin key and and creating the reverse reference bitcoin_key -> + // node_key. + BitcoinSignature *btcec.Signature +} + +// A compile time check to ensure AnnounceSignatures implements the +// lnwire.Message interface. +var _ Message = (*AnnounceSignatures)(nil) + +// Validate performs any necessary sanity checks to ensure all fields present +// on the AnnounceSignatures are valid. +// +// This is part of the lnwire.Message interface. +func (a *AnnounceSignatures) Validate() error { + return nil +} + +// Decode deserializes a serialized AnnounceSignatures stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. +func (a *AnnounceSignatures) Decode(r io.Reader, pver uint32) error { + return readElements(r, + &a.ChannelID, + &a.ShortChannelID, + &a.NodeSignature, + &a.BitcoinSignature, + ) +} + +// Encode serializes the target AnnounceSignatures into the passed io.Writer +// observing the protocol version specified. +// +// This is part of the lnwire.Message interface. +func (a *AnnounceSignatures) Encode(w io.Writer, pver uint32) error { + return writeElements(w, + a.ChannelID, + a.ShortChannelID, + a.NodeSignature, + a.BitcoinSignature, + ) +} + +// Command returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. +func (a *AnnounceSignatures) Command() uint32 { + return CmdAnnounceSignatures +} + +// MaxPayloadLength returns the maximum allowed payload size for this message +// observing the specified protocol version. +// +// This is part of the lnwire.Message interface. +func (a *AnnounceSignatures) MaxPayloadLength(pver uint32) uint32 { + var length uint32 + + // ChannelID - 36 bytes + length += 36 + + // ShortChannelID - 8 bytes + length += 8 + + // NodeSignatures - 64 bytes + length += 64 + + // BitcoinSignatures - 64 bytes + length += 64 + + return length +} diff --git a/lnwire/announcement_signatures_test.go b/lnwire/announcement_signatures_test.go new file mode 100644 index 00000000..a8e05352 --- /dev/null +++ b/lnwire/announcement_signatures_test.go @@ -0,0 +1,34 @@ +package lnwire + +import ( + "bytes" + "reflect" + "testing" +) + +func TestAnnounceSignatureEncodeDecode(t *testing.T) { + ac := &AnnounceSignatures{ + ChannelID: *outpoint1, + ShortChannelID: NewChanIDFromInt(1), + NodeSignature: someSig, + BitcoinSignature: someSig, + } + + // Next encode the message into an empty bytes buffer. + var b bytes.Buffer + if err := ac.Encode(&b, 0); err != nil { + t.Fatalf("unable to encode AnnounceSignatures: %v", err) + } + + // Deserialize the encoded message into a new empty struct. + ac2 := &AnnounceSignatures{} + if err := ac2.Decode(&b, 0); err != nil { + t.Fatalf("unable to decode AnnounceSignatures: %v", err) + } + + // Assert equality of the two instances. + if !reflect.DeepEqual(ac, ac2) { + t.Fatalf("encode/decode error messages don't match %#v vs %#v", + ac, ac2) + } +} diff --git a/lnwire/message.go b/lnwire/message.go index 446dd722..f309eecf 100644 --- a/lnwire/message.go +++ b/lnwire/message.go @@ -55,6 +55,7 @@ const ( CmdChannelAnnoucmentMessage = uint32(5000) CmdChannelUpdateAnnoucmentMessage = uint32(5010) CmdNodeAnnoucmentMessage = uint32(5020) + CmdAnnounceSignatures = uint32(5030) // Commands for connection keep-alive. CmdPing = uint32(6000) @@ -128,6 +129,8 @@ func makeEmptyMessage(command uint32) (Message, error) { msg = &NodeAnnouncement{} case CmdPing: msg = &Ping{} + case CmdAnnounceSignatures: + msg = &AnnounceSignatures{} case CmdPong: msg = &Pong{} default: