2017-04-17 00:19:39 +02:00
|
|
|
package lnwire
|
|
|
|
|
2017-10-24 00:50:26 +02:00
|
|
|
import (
|
|
|
|
"fmt"
|
2022-04-04 21:25:16 +02:00
|
|
|
"io"
|
|
|
|
|
|
|
|
"github.com/lightningnetwork/lnd/tlv"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// AliasScidRecordType is the type of the experimental record to denote
|
|
|
|
// the alias being used in an option_scid_alias channel.
|
|
|
|
AliasScidRecordType tlv.Type = 1
|
2017-10-24 00:50:26 +02:00
|
|
|
)
|
|
|
|
|
2017-09-08 03:25:43 +02:00
|
|
|
// ShortChannelID represents the set of data which is needed to retrieve all
|
2017-04-17 00:19:39 +02:00
|
|
|
// necessary data to validate the channel existence.
|
|
|
|
type ShortChannelID 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
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewShortChanIDFromInt returns a new ShortChannelID 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 NewShortChanIDFromInt(chanID uint64) ShortChannelID {
|
|
|
|
return ShortChannelID{
|
|
|
|
BlockHeight: uint32(chanID >> 40),
|
|
|
|
TxIndex: uint32(chanID>>16) & 0xFFFFFF,
|
|
|
|
TxPosition: uint16(chanID),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ToUint64 converts the ShortChannelID into a compact format encoded within a
|
|
|
|
// uint64 (8 bytes).
|
2018-04-06 02:59:50 +02:00
|
|
|
func (c ShortChannelID) ToUint64() uint64 {
|
2017-04-17 00:19:39 +02:00
|
|
|
// TODO(roasbeef): explicit error on overflow?
|
|
|
|
return ((uint64(c.BlockHeight) << 40) | (uint64(c.TxIndex) << 16) |
|
|
|
|
(uint64(c.TxPosition)))
|
|
|
|
}
|
2017-10-24 00:50:26 +02:00
|
|
|
|
|
|
|
// String generates a human-readable representation of the channel ID.
|
|
|
|
func (c ShortChannelID) String() string {
|
|
|
|
return fmt.Sprintf("%d:%d:%d", c.BlockHeight, c.TxIndex, c.TxPosition)
|
|
|
|
}
|
2022-04-04 21:25:16 +02:00
|
|
|
|
|
|
|
// Record returns a TLV record that can be used to encode/decode a
|
|
|
|
// ShortChannelID to/from a TLV stream.
|
|
|
|
func (c *ShortChannelID) Record() tlv.Record {
|
|
|
|
return tlv.MakeStaticRecord(
|
|
|
|
AliasScidRecordType, c, 8, EShortChannelID, DShortChannelID,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-09-13 18:23:05 +02:00
|
|
|
// IsDefault returns true if the ShortChannelID represents the zero value for
|
|
|
|
// its type.
|
|
|
|
func (c ShortChannelID) IsDefault() bool {
|
|
|
|
return c == ShortChannelID{}
|
|
|
|
}
|
|
|
|
|
2022-04-04 21:25:16 +02:00
|
|
|
// EShortChannelID is an encoder for ShortChannelID. It is exported so other
|
|
|
|
// packages can use the encoding scheme.
|
|
|
|
func EShortChannelID(w io.Writer, val interface{}, buf *[8]byte) error {
|
|
|
|
if v, ok := val.(*ShortChannelID); ok {
|
|
|
|
return tlv.EUint64T(w, v.ToUint64(), buf)
|
|
|
|
}
|
|
|
|
return tlv.NewTypeForEncodingErr(val, "lnwire.ShortChannelID")
|
|
|
|
}
|
|
|
|
|
|
|
|
// DShortChannelID is a decoder for ShortChannelID. It is exported so other
|
|
|
|
// packages can use the decoding scheme.
|
|
|
|
func DShortChannelID(r io.Reader, val interface{}, buf *[8]byte,
|
|
|
|
l uint64) error {
|
|
|
|
|
|
|
|
if v, ok := val.(*ShortChannelID); ok {
|
|
|
|
var scid uint64
|
|
|
|
err := tlv.DUint64(r, &scid, buf, 8)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
*v = NewShortChanIDFromInt(scid)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return tlv.NewTypeForDecodingErr(val, "lnwire.ShortChannelID", l, 8)
|
|
|
|
}
|