diff --git a/lnwire/channel_announcement.go b/lnwire/channel_announcement.go index 1854dc7c8..3595fda7b 100644 --- a/lnwire/channel_announcement.go +++ b/lnwire/channel_announcement.go @@ -3,35 +3,13 @@ package lnwire import ( "bytes" "fmt" + "io" + "github.com/go-errors/errors" "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/wire" - "io" ) -// ChannelID represent the set of data which is needed to retrieve all -// necessary data to validate the channel existance. -type ChannelID struct { - // BlockHeight is the height of the block where funding - // transaction located. - // NOTE: This field is limited to 3 bytes. - BlockHeight uint32 - - // TxIndex is a position of funding transaction within a block. - // NOTE: This field is limited to 3 bytes. - TxIndex uint32 - - // TxPosition indicating transaction output which pays to the - // channel. - TxPosition uint16 -} - -func (c *ChannelID) String() string { - return fmt.Sprintf("BlockHeight:\t\t\t%v\n", c.BlockHeight) + - fmt.Sprintf("TxIndex:\t\t\t%v\n", c.TxIndex) + - fmt.Sprintf("TxPosition:\t\t\t%v\n", c.TxPosition) -} - // ChannelAnnouncement message is used to announce the existence of a channel // between two peers in the overlay, which is propagated by the discovery // service over broadcast handler. @@ -200,7 +178,7 @@ func (c *ChannelAnnouncement) String() string { return fmt.Sprintf("\n--- Begin ChannelAnnouncement ---\n") + fmt.Sprintf("FirstNodeSig:\t\t%v\n", c.FirstNodeSig) + fmt.Sprintf("SecondNodeSig:\t\t%v\n", c.SecondNodeSig) + - fmt.Sprintf("ChannelID:\t\t%v\n", c.ChannelID.String()) + + fmt.Sprintf("ChannelID:\t\t%v\n", c.ChannelID.ToUint64()) + fmt.Sprintf("FirstBitcoinSig:\t\t%v\n", c.FirstBitcoinSig) + fmt.Sprintf("SecondBitcoinSig:\t\t%v\n", c.SecondBitcoinSig) + fmt.Sprintf("FirstNodeSig:\t\t%v\n", c.FirstNodeSig) + diff --git a/lnwire/channel_announcement_test.go b/lnwire/channel_announcement_test.go index a0009d070..abcb22a7c 100644 --- a/lnwire/channel_announcement_test.go +++ b/lnwire/channel_announcement_test.go @@ -2,10 +2,11 @@ package lnwire import ( "bytes" - "github.com/roasbeef/btcd/btcec" - "github.com/roasbeef/btcd/wire" "reflect" "testing" + + "github.com/roasbeef/btcd/btcec" + "github.com/roasbeef/btcd/wire" ) func TestChannelAnnoucementEncodeDecode(t *testing.T) { diff --git a/lnwire/channel_id.go b/lnwire/channel_id.go new file mode 100644 index 000000000..030cbcf0e --- /dev/null +++ b/lnwire/channel_id.go @@ -0,0 +1,40 @@ +package lnwire + +// ChannelID represent the set of data which is needed to retrieve all +// necessary data to validate the channel existence. +type ChannelID struct { + // BlockHeight is the height of the block where funding transaction + // located. + // + // NOTE: This field is limited to 3 bytes. + BlockHeight uint32 + + // TxIndex is a position of funding transaction within a block. + // + // NOTE: This field is limited to 3 bytes. + TxIndex uint32 + + // TxPosition indicating transaction output which pays to the + // channel. + TxPosition uint16 +} + +// NewChanIDFromInt returns a new ChannelID which is the decoded version of the +// compact channel ID encoded within the uint64. The format of the compact +// channel ID is as follows: 3 bytes for the block height, 3 bytes for the +// transaction index, and 2 bytes for the output index. +func NewChanIDFromInt(chanID uint64) ChannelID { + return ChannelID{ + BlockHeight: uint32(chanID >> 40), + TxIndex: uint32(chanID>>16) & 0xFFFFFF, + TxPosition: uint16(chanID), + } +} + +// ToUint64 converts the ChannelID into a compact format encoded within a +// uint64 (8 bytes). +func (c *ChannelID) ToUint64() uint64 { + // TODO(roasbeef): explicit error on overflow? + return ((uint64(c.BlockHeight) << 40) | (uint64(c.TxIndex) << 16) | + (uint64(c.TxPosition))) +} diff --git a/lnwire/channel_id_test.go b/lnwire/channel_id_test.go new file mode 100644 index 000000000..e2c235ff7 --- /dev/null +++ b/lnwire/channel_id_test.go @@ -0,0 +1,39 @@ +package lnwire + +import ( + "reflect" + "testing" + + "github.com/davecgh/go-spew/spew" +) + +func TestChannelIDEncoding(t *testing.T) { + var testCases = []ChannelID{ + { + BlockHeight: (1 << 24) - 1, + TxIndex: (1 << 24) - 1, + TxPosition: (1 << 16) - 1, + }, + { + BlockHeight: 2304934, + TxIndex: 2345, + TxPosition: 5, + }, + { + BlockHeight: 9304934, + TxIndex: 2345, + TxPosition: 5233, + }, + } + + for _, testCase := range testCases { + chanInt := testCase.ToUint64() + + newChanID := NewChanIDFromInt(chanInt) + + if !reflect.DeepEqual(testCase, newChanID) { + t.Fatalf("chan ID's don't match: expected %v got %v", + spew.Sdump(testCase), spew.Sdump(newChanID)) + } + } +} diff --git a/lnwire/channel_update_announcement.go b/lnwire/channel_update_announcement.go index 363d65708..a4358bc17 100644 --- a/lnwire/channel_update_announcement.go +++ b/lnwire/channel_update_announcement.go @@ -158,7 +158,7 @@ func (c *ChannelUpdateAnnouncement) MaxPayloadLength(pver uint32) uint32 { func (c *ChannelUpdateAnnouncement) String() string { return fmt.Sprintf("\n--- Begin ChannelUpdateAnnouncement ---\n") + fmt.Sprintf("Signature:\t\t%v\n", c.Signature) + - fmt.Sprintf("ChannelID:\t\t%v\n", c.ChannelID.String()) + + fmt.Sprintf("ChannelID:\t\t%v\n", c.ChannelID.ToUint64()) + fmt.Sprintf("Timestamp:\t\t%v\n", c.Timestamp) + fmt.Sprintf("Flags:\t\t%v\n", c.Flags) + fmt.Sprintf("Expiry:\t\t%v\n", c.Expiry) + diff --git a/lnwire/node_announcement.go b/lnwire/node_announcement.go index 33829ec78..43e484695 100644 --- a/lnwire/node_announcement.go +++ b/lnwire/node_announcement.go @@ -3,11 +3,12 @@ package lnwire import ( "bytes" "fmt" + "io" + "net" + "github.com/go-errors/errors" "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/wire" - "io" - "net" ) var ( @@ -72,7 +73,7 @@ type NodeAnnouncement struct { // the node is accepting incoming connections. Address *net.TCPAddr - // NodeID is a public key which is used as node identificator. + // NodeID is a public key which is used as node identification. NodeID *btcec.PublicKey // RGBColor is used to customize their node's appearance in maps and graphs