diff --git a/lnwire/accept_channel.go b/lnwire/accept_channel.go new file mode 100644 index 00000000..3cd0e1fb --- /dev/null +++ b/lnwire/accept_channel.go @@ -0,0 +1,154 @@ +package lnwire + +import ( + "io" + + "github.com/roasbeef/btcd/btcec" + "github.com/roasbeef/btcutil" +) + +// AcceptChannel is the message Bob sends to Alice after she initiates the +// single funder channel workflow via a AcceptChannel message. Once Alice +// receives Bob's response, then she has all the items necessary to construct +// the funding transaction, and both commitment transactions. +type AcceptChannel struct { + // PendingChannelID serves to uniquely identify the future channel + // created by the initiated single funder workflow. + PendingChannelID [32]byte + + // DustLimit is the specific dust limit the sender of this message + // would like enforced on their version of the commitment transaction. + // Any output below this value will be "trimmed" from the commitment + // transaction, with the amount of the HTLC going to dust. + DustLimit btcutil.Amount + + // MaxValueInFlight represents the maximum amount of coins that can be + // pending within the channel at any given time. If the amount of funds + // in limbo exceeds this amount, then the channel will be failed. + // + // TODO(roasbeef): is msat + MaxValueInFlight btcutil.Amount + + // ChannelReserve is the amount of BTC that the receiving party MUST + // maintain a balance above at all times. This is a safety mechanism to + // ensure that both sides always have skin in the game during the + // channel's lifetime. + ChannelReserve btcutil.Amount + + // MinAcceptDepth is the minimum depth that the initiator of the + // channel should wait before considering the channel open. + MinAcceptDepth uint32 + + // HtlcMinimum is the smallest HTLC that the sender of this message + // will accept. + // + // TODO(roasbeef): is msat + HtlcMinimum uint32 + + // CsvDelay is the number of blocks to use for the relative time lock + // in the pay-to-self output of both commitment transactions. + CsvDelay uint16 + + // MaxAcceptedHTLCs is the total number of incoming HTLC's that the + // sender of this channel will accept. + // + // TODO(roasbeef): acks the initiator's, same with max in flight? + MaxAcceptedHTLCs uint16 + + // FundingKey is the key that should be used on behalf of the sender + // within the 2-of-2 multi-sig output that it contained within the + // funding transaction. + FundingKey *btcec.PublicKey + + // RevocationPoint is the base revocation point for the sending party. + // Any commitment transaction belonging to the receiver of this message + // should use this key and their per-commitment point to derive the + // revocation key for the commitment transaction. + RevocationPoint *btcec.PublicKey + + // PaymentPoint is the base payment point for the sending party. This + // key should be combined with the per commitment point for a + // particular commitment state in order to create the key that should + // be used in any output that pays directly to the sending party, and + // also within the HTLC covenant transactions. + PaymentPoint *btcec.PublicKey + + // DelayedPaymentPoint is the delay point for the sending party. This + // key should be combined with the per commitment point to derive the + // keys that are used in outputs of the sender's commitment transaction + // where they claim funds. + DelayedPaymentPoint *btcec.PublicKey + + // FirstCommitmentPoint is the first commitment point for the sending + // party. This value should be combined with the receiver's revocation + // base point in order to derive the revocation keys that are placed + // within the commitment transaction of the sender. + FirstCommitmentPoint *btcec.PublicKey +} + +// A compile time check to ensure AcceptChannel implements the lnwire.Message +// interface. +var _ Message = (*AcceptChannel)(nil) + +// Encode serializes the target AcceptChannel into the passed io.Writer +// implementation. Serialization will observe the rules defined by the passed +// protocol version. +// +// This is part of the lnwire.Message interface. +func (a *AcceptChannel) Encode(w io.Writer, pver uint32) error { + return writeElements(w, + a.PendingChannelID[:], + a.DustLimit, + a.MaxValueInFlight, + a.ChannelReserve, + a.MinAcceptDepth, + a.HtlcMinimum, + a.CsvDelay, + a.MaxAcceptedHTLCs, + a.FundingKey, + a.RevocationPoint, + a.PaymentPoint, + a.DelayedPaymentPoint, + a.FirstCommitmentPoint, + ) +} + +// Decode deserializes the serialized AcceptChannel stored in the passed +// io.Reader into the target AcceptChannel using the deserialization rules +// defined by the passed protocol version. +// +// This is part of the lnwire.Message interface. +func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error { + return readElements(r, + a.PendingChannelID[:], + &a.DustLimit, + &a.MaxValueInFlight, + &a.ChannelReserve, + &a.MinAcceptDepth, + &a.HtlcMinimum, + &a.CsvDelay, + &a.MaxAcceptedHTLCs, + &a.FundingKey, + &a.RevocationPoint, + &a.PaymentPoint, + &a.DelayedPaymentPoint, + &a.FirstCommitmentPoint, + ) +} + +// MsgType returns the MessageType code which uniquely identifies this message +// as a AcceptChannel on the wire. +// +// This is part of the lnwire.Message interface. +func (a *AcceptChannel) MsgType() MessageType { + return MsgAcceptChannel +} + +// MaxPayloadLength returns the maximum allowed payload length for a +// AcceptChannel message. +// +// This is part of the lnwire.Message interface. +func (a *AcceptChannel) MaxPayloadLength(uint32) uint32 { + // 32 + (8 * 3) + (4 * 2) + (2 * 2) + (33 * 5) + return 233 +} diff --git a/lnwire/funding_created.go b/lnwire/funding_created.go new file mode 100644 index 00000000..b9481ebf --- /dev/null +++ b/lnwire/funding_created.go @@ -0,0 +1,67 @@ +package lnwire + +import ( + "io" + + "github.com/roasbeef/btcd/btcec" + "github.com/roasbeef/btcd/wire" +) + +// FundingCreated is sent from Alice (the initiator) to Bob (the responder), +// once Alice receives Bob's contributions as well as his channel constraints. +// Once bob receives this message, he'll gain access to an immediately +// broadcastable commitment transaction and will reply with a signature for +// Alice's version of the commitment transaction. +type FundingCreated struct { + // PendingChannelID serves to uniquely identify the future channel + // created by the initiated single funder workflow. + PendingChannelID [32]byte + + // FundingPoint is the outpoint of the funding transaction created by + // Alice. With this, Bob is able to generate both his version and + // Alice's version of the commitment transaction. + FundingPoint wire.OutPoint + + // CommitSig is Alice's signature from Bob's version of the commitment + // transaction. + CommitSig *btcec.Signature +} + +// A compile time check to ensure FundingCreated implements the lnwire.Message +// interface. +var _ Message = (*FundingCreated)(nil) + +// Encode serializes the target FundingCreated into the passed io.Writer +// implementation. Serialization will observe the rules defined by the passed +// protocol version. +// +// This is part of the lnwire.Message interface. +func (f *FundingCreated) Encode(w io.Writer, pver uint32) error { + return writeElements(w, f.PendingChannelID[:], f.FundingPoint, f.CommitSig) +} + +// Decode deserializes the serialized FundingCreated stored in the passed +// io.Reader into the target FundingCreated using the deserialization rules +// defined by the passed protocol version. +// +// This is part of the lnwire.Message interface. +func (f *FundingCreated) Decode(r io.Reader, pver uint32) error { + return readElements(r, f.PendingChannelID[:], &f.FundingPoint, &f.CommitSig) +} + +// MsgType returns the uint32 code which uniquely identifies this message as a +// FundingCreated on the wire. +// +// This is part of the lnwire.Message interface. +func (f *FundingCreated) MsgType() MessageType { + return MsgFundingCreated +} + +// MaxPayloadLength returns the maximum allowed payload length for a +// FundingCreated message. +// +// This is part of the lnwire.Message interface. +func (f *FundingCreated) MaxPayloadLength(uint32) uint32 { + // 32 + 32 + 2 + 64 + return 130 +} diff --git a/lnwire/funding_signed.go b/lnwire/funding_signed.go new file mode 100644 index 00000000..7e795986 --- /dev/null +++ b/lnwire/funding_signed.go @@ -0,0 +1,59 @@ +package lnwire + +import ( + "io" + + "github.com/roasbeef/btcd/btcec" +) + +// FundingSigned is sent from Bob (the responder) to Alice (the initiator) +// after receiving the funding outpoint and her signature for Bob's version of +// the commitment transaction. +type FundingSigned struct { + // ChannelPoint is the particular active channel that this + // FundingSigned is bound to. + ChanID ChannelID + + // CommitSig is Bob's signature for Alice's version of the commitment + // transaction. + CommitSig *btcec.Signature +} + +// A compile time check to ensure FundingSigned implements the lnwire.Message +// interface. +var _ Message = (*FundingSigned)(nil) + +// Encode serializes the target FundingSigned into the passed io.Writer +// implementation. Serialization will observe the rules defined by the passed +// protocol version. +// +// This is part of the lnwire.Message interface. +func (f *FundingSigned) Encode(w io.Writer, pver uint32) error { + return writeElements(w, f.ChanID, f.CommitSig) +} + +// Decode deserializes the serialized FundingSigned stored in the passed +// io.Reader into the target FundingSigned using the deserialization rules +// defined by the passed protocol version. +// +// This is part of the lnwire.Message interface. +func (f *FundingSigned) Decode(r io.Reader, pver uint32) error { + return readElements(r, &f.ChanID, &f.CommitSig) +} + +// MsgType returns the uint32 code which uniquely identifies this message as a +// FundingSigned on the wire. +// +// This is part of the lnwire.Message interface. +func (f *FundingSigned) MsgType() MessageType { + return MsgFundingSigned +} + +// MaxPayloadLength returns the maximum allowed payload length for a +// FundingSigned message. +// +// This is part of the lnwire.Message interface. +func (f *FundingSigned) MaxPayloadLength(uint32) uint32 { + // 32 + 64 + return 96 +} diff --git a/lnwire/open_channel.go b/lnwire/open_channel.go new file mode 100644 index 00000000..74e1ac29 --- /dev/null +++ b/lnwire/open_channel.go @@ -0,0 +1,184 @@ +package lnwire + +import ( + "io" + + "github.com/roasbeef/btcd/btcec" + "github.com/roasbeef/btcd/chaincfg/chainhash" + "github.com/roasbeef/btcutil" +) + +// OpenChannel is the message Alice sends to Bob if we should like to create a +// channel with Bob where she's the sole provider of funds to the channel. +// Single funder channels simplify the initial funding workflow, are supported +// by nodes backed by SPV Bitcoin clients, and have a simpler security models +// than dual funded channels. +type OpenChannel struct { + // ChainHash is the target chain that the initiator wishes to open a + // channel within. + ChainHash chainhash.Hash + + // PendingChannelID serves to uniquely identify the future channel + // created by the initiated single funder workflow. + PendingChannelID [32]byte + + // FundingAmount is the amount of satoshis that the initiator of the + // channel wishes to use as the total capacity of the channel. The + // initial balance of the funding will be this value minus the push + // amount (if set). + FundingAmount btcutil.Amount + + // PushAmount is the value that the initiating party wishes to "push" + // to the responding as part of the first commitment state. If the + // responder accepts, then this will be their initial balance. + // + // TODO(roasbeef): is msat + PushAmount btcutil.Amount + + // DustLimit is the specific dust limit the sender of this message + // would like enforced on their version of the commitment transaction. + // Any output below this value will be "trimmed" from the commitment + // transaction, with the amount of the HTLC going to dust. + DustLimit btcutil.Amount + + // MaxValueInFlight represents the maximum amount of coins that can be + // pending within the channel at any given time. If the amount of funds + // in limbo exceeds this amount, then the channel will be failed. + MaxValueInFlight btcutil.Amount + + // ChannelReserve is the amount of BTC that the receiving party MUST + // maintain a balance above at all times. This is a safety mechanism to + // ensure that both sides always have skin in the game during the + // channel's lifetime. + ChannelReserve btcutil.Amount + + // HtlcMinimum is the smallest HTLC that the sender of this message + // will accept. + // + // TODO(roasbeef): is msat + HtlcMinimum uint32 + + // FeePerKiloWeight is the initial fee rate that the initiator suggests + // for both commitment transaction. This value is expressed in sat per + // kilo-weight. + FeePerKiloWeight uint32 + + // CsvDelay is the number of blocks to use for the relative time lock + // in the pay-to-self output of both commitment transactions. + CsvDelay uint16 + + // MaxAcceptedHTLCs is the total number of incoming HTLC's that the + // sender of this channel will accept. + MaxAcceptedHTLCs uint16 + + // FundingKey is the key that should be used on behalf of the sender + // within the 2-of-2 multi-sig output that it contained within the + // funding transaction. + FundingKey *btcec.PublicKey + + // RevocationPoint is the base revocation point for the sending party. + // Any commitment transaction belonging to the receiver of this message + // should use this key and their per-commitment point to derive the + // revocation key for the commitment transaction. + RevocationPoint *btcec.PublicKey + + // PaymentPoint is the base payment point for the sending party. This + // key should be combined with the per commitment point for a + // particular commitment state in order to create the key that should + // be used in any output that pays directly to the sending party, and + // also within the HTLC covenant transactions. + PaymentPoint *btcec.PublicKey + + // DelayedPaymentPoint is the delay point for the sending party. This + // key should be combined with the per commitment point to derive the + // keys that are used in outputs of the sender's commitment transaction + // where they claim funds. + DelayedPaymentPoint *btcec.PublicKey + + // FirstCommitmentPoint is the first commitment point for the sending + // party. This value should be combined with the receiver's revocation + // base point in order to derive the revocation keys that are placed + // within the commitment transaction of the sender. + FirstCommitmentPoint *btcec.PublicKey + + // ChannelFlags is a bit-field which allows the initiator of the + // channel to specify further behavior surrounding the channel. + // Currently, the least significant bit of this bit field indicates the + // initiator of the channel wishes to advertise this channel publicly. + ChannelFlags byte +} + +// A compile time check to ensure OpenChannel implements the lnwire.Message +// interface. +var _ Message = (*OpenChannel)(nil) + +// Encode serializes the target OpenChannel into the passed io.Writer +// implementation. Serialization will observe the rules defined by the passed +// protocol version. +// +// This is part of the lnwire.Message interface. +func (o *OpenChannel) Encode(w io.Writer, pver uint32) error { + return writeElements(w, + o.ChainHash[:], + o.PendingChannelID[:], + o.FundingAmount, + o.PushAmount, + o.DustLimit, + o.MaxValueInFlight, + o.ChannelReserve, + o.HtlcMinimum, + o.FeePerKiloWeight, + o.CsvDelay, + o.MaxAcceptedHTLCs, + o.FundingKey, + o.RevocationPoint, + o.PaymentPoint, + o.DelayedPaymentPoint, + o.FirstCommitmentPoint, + o.ChannelFlags, + ) +} + +// Decode deserializes the serialized OpenChannel stored in the passed +// io.Reader into the target OpenChannel using the deserialization rules +// defined by the passed protocol version. +// +// This is part of the lnwire.Message interface. +func (o *OpenChannel) Decode(r io.Reader, pver uint32) error { + return readElements(r, + o.ChainHash[:], + o.PendingChannelID[:], + &o.FundingAmount, + &o.PushAmount, + &o.DustLimit, + &o.MaxValueInFlight, + &o.ChannelReserve, + &o.HtlcMinimum, + &o.FeePerKiloWeight, + &o.CsvDelay, + &o.MaxAcceptedHTLCs, + &o.FundingKey, + &o.RevocationPoint, + &o.PaymentPoint, + &o.DelayedPaymentPoint, + &o.FirstCommitmentPoint, + &o.ChannelFlags, + ) +} + +// MsgType returns the MessageType code which uniquely identifies this message +// as a OpenChannel on the wire. +// +// This is part of the lnwire.Message interface. +func (o *OpenChannel) MsgType() MessageType { + return MsgOpenChannel +} + +// MaxPayloadLength returns the maximum allowed payload length for a +// OpenChannel message. +// +// This is part of the lnwire.Message interface. +func (o *OpenChannel) MaxPayloadLength(uint32) uint32 { + // (32 * 2) + (8 * 5) + (4 * 2) + (2 * 2) + (33 * 5) + 1 + return 282 +}