You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
3.1 KiB
91 lines
3.1 KiB
package lnwire |
|
|
|
import ( |
|
"encoding/binary" |
|
"encoding/hex" |
|
"math" |
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash" |
|
"github.com/btcsuite/btcd/wire" |
|
) |
|
|
|
const ( |
|
// MaxFundingTxOutputs is the maximum number of allowed outputs on a |
|
// funding transaction within the protocol. This is due to the fact |
|
// that we use 2-bytes to encode the index within the funding output |
|
// during the funding workflow. Funding transaction with more outputs |
|
// than this are considered invalid within the protocol. |
|
MaxFundingTxOutputs = math.MaxUint16 |
|
) |
|
|
|
// ChannelID is a series of 32-bytes that uniquely identifies all channels |
|
// within the network. The ChannelID is computed using the outpoint of the |
|
// funding transaction (the txid, and output index). Given a funding output the |
|
// ChannelID can be calculated by XOR'ing the big-endian serialization of the |
|
// txid and the big-endian serialization of the output index, truncated to |
|
// 2 bytes. |
|
type ChannelID [32]byte |
|
|
|
// ConnectionWideID is an all-zero ChannelID, which is used to represent a |
|
// message intended for all channels to specific peer. |
|
var ConnectionWideID = ChannelID{} |
|
|
|
// String returns the string representation of the ChannelID. This is just the |
|
// hex string encoding of the ChannelID itself. |
|
func (c ChannelID) String() string { |
|
return hex.EncodeToString(c[:]) |
|
} |
|
|
|
// NewChanIDFromOutPoint converts a target OutPoint into a ChannelID that is |
|
// usable within the network. In order to convert the OutPoint into a ChannelID, |
|
// we XOR the lower 2-bytes of the txid within the OutPoint with the big-endian |
|
// serialization of the Index of the OutPoint, truncated to 2-bytes. |
|
func NewChanIDFromOutPoint(op *wire.OutPoint) ChannelID { |
|
// First we'll copy the txid of the outpoint into our channel ID slice. |
|
var cid ChannelID |
|
copy(cid[:], op.Hash[:]) |
|
|
|
// With the txid copied over, we'll now XOR the lower 2-bytes of the |
|
// partial channelID with big-endian serialization of output index. |
|
xorTxid(&cid, uint16(op.Index)) |
|
|
|
return cid |
|
} |
|
|
|
// xorTxid performs the transformation needed to transform an OutPoint into a |
|
// ChannelID. To do this, we expect the cid parameter to contain the txid |
|
// unaltered and the outputIndex to be the output index |
|
func xorTxid(cid *ChannelID, outputIndex uint16) { |
|
var buf [2]byte |
|
binary.BigEndian.PutUint16(buf[:], outputIndex) |
|
|
|
cid[30] ^= buf[0] |
|
cid[31] ^= buf[1] |
|
} |
|
|
|
// GenPossibleOutPoints generates all the possible outputs given a channel ID. |
|
// In order to generate these possible outpoints, we perform a brute-force |
|
// search through the candidate output index space, performing a reverse |
|
// mapping from channelID back to OutPoint. |
|
func (c *ChannelID) GenPossibleOutPoints() [MaxFundingTxOutputs]wire.OutPoint { |
|
var possiblePoints [MaxFundingTxOutputs]wire.OutPoint |
|
for i := uint16(0); i < MaxFundingTxOutputs; i++ { |
|
cidCopy := *c |
|
xorTxid(&cidCopy, i) |
|
|
|
possiblePoints[i] = wire.OutPoint{ |
|
Hash: chainhash.Hash(cidCopy), |
|
Index: uint32(i), |
|
} |
|
} |
|
|
|
return possiblePoints |
|
} |
|
|
|
// IsChanPoint returns true if the OutPoint passed corresponds to the target |
|
// ChannelID. |
|
func (c ChannelID) IsChanPoint(op *wire.OutPoint) bool { |
|
candidateCid := NewChanIDFromOutPoint(op) |
|
|
|
return candidateCid == c |
|
}
|
|
|