diff --git a/lnwire/close_complete.go b/lnwire/close_complete.go index a802989c7..f235d02ec 100644 --- a/lnwire/close_complete.go +++ b/lnwire/close_complete.go @@ -2,28 +2,41 @@ package lnwire import ( "fmt" + "github.com/roasbeef/btcd/btcec" - "github.com/roasbeef/btcd/wire" "io" ) +// CloseComplete is sent by Bob signalling a fufillment and completion of +// Alice's prior CloseRequest message. After Alice receives Bob's CloseComplete +// message, she is able to broadcast the fully signed transaction executing a +// cooperative closure of the channel. +// +// NOTE: The responder is able to only send a signature without any additional +// message as all transactions are assembled observing BIP 69 which defines a +// cannonical ordering for input/outputs. Therefore, both sides are able to +// arrive at an identical closure transaction as they know the order of the +// inputs/outputs. type CloseComplete struct { - ReservationID uint64 + // ChannelID serves to identify which channel is to be closed. + ChannelID uint64 - ResponderCloseSig *btcec.Signature // Requester's Commitment - CloseShaHash *wire.ShaHash // TxID of the Close Tx + // ResponderCloseSig is the signature of the responder for the + // transaction which closes the previously active channel. + ResponderCloseSig *btcec.Signature } +// Decode deserializes a serialized CloseComplete message stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *CloseComplete) Decode(r io.Reader, pver uint32) error { - // ReservationID (8) + // ChannelID (8) // ResponderCloseSig (73) - // First byte length then sig - // CloseShaHash (32) err := readElements(r, - &c.ReservationID, - &c.ResponderCloseSig, - &c.CloseShaHash) + &c.ChannelID, + &c.ResponderCloseSig) if err != nil { return err } @@ -31,21 +44,26 @@ func (c *CloseComplete) Decode(r io.Reader, pver uint32) error { return nil } -// Creates a new CloseComplete +// NewCloseComplete creates a new empty CloseComplete message. +// TODO(roasbeef): add params to all constructors... func NewCloseComplete() *CloseComplete { return &CloseComplete{} } -// Serializes the item from the CloseComplete struct -// Writes the data to w +// A compile time check to ensure CloseComplete implements the lnwire.Message +// interface. +var _ Message = (*CloseComplete)(nil) + +// Encode serializes the target CloseComplete into the passed io.Writer observing +// the protocol version specified. +// +// This is part of the lnwire.Message interface. func (c *CloseComplete) Encode(w io.Writer, pver uint32) error { - // ReservationID - // ResponderCloseSig - // CloseShaHash + // ChannelID (8) + // ResponderCloseSig (73) err := writeElements(w, - c.ReservationID, - c.ResponderCloseSig, - c.CloseShaHash) + c.ChannelID, + c.ResponderCloseSig) if err != nil { return err } @@ -53,34 +71,43 @@ func (c *CloseComplete) Encode(w io.Writer, pver uint32) error { return nil } +// Command returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. func (c *CloseComplete) Command() uint32 { return CmdCloseComplete } +// MaxPayloadLength returns the maximum allowed payload size for a CloseComplete +// complete message observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *CloseComplete) MaxPayloadLength(uint32) uint32 { // 8 + 73 + 32 return 113 } -// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) +// Validate performs any necessary sanity checks to ensure all fields present +// on the CloseComplete are valid. +// +// This is part of the lnwire.Message interface. func (c *CloseComplete) Validate() error { // We're good! return nil } +// String returns the string representation of the target CloseComplete. +// +// This is part of the lnwire.Message interface. func (c *CloseComplete) String() string { var serializedSig []byte - var shaString string - if c.ResponderCloseSig != nil && c.ResponderCloseSig.R != nil { + if c.ResponderCloseSig != nil { serializedSig = c.ResponderCloseSig.Serialize() } - if c.CloseShaHash != nil { - shaString = (*c).CloseShaHash.String() - } return fmt.Sprintf("\n--- Begin CloseComplete ---\n") + - fmt.Sprintf("ReservationID:\t\t%d\n", c.ReservationID) + + fmt.Sprintf("ReservationID:\t\t%d\n", c.ChannelID) + fmt.Sprintf("ResponderCloseSig:\t%x\n", serializedSig) + - fmt.Sprintf("CloseShaHash:\t\t%s\n", shaString) + fmt.Sprintf("--- End CloseComplete ---\n") } diff --git a/lnwire/close_complete_test.go b/lnwire/close_complete_test.go index c3708cf98..4500bf3b4 100644 --- a/lnwire/close_complete_test.go +++ b/lnwire/close_complete_test.go @@ -1,15 +1,13 @@ package lnwire import ( - // "github.com/roasbeef/btcutil" "testing" ) var ( closeComplete = &CloseComplete{ - ReservationID: uint64(12345678), + ChannelID: uint64(12345678), ResponderCloseSig: commitSig, - CloseShaHash: shaHash1, } closeCompleteSerializedString = "0000000000bc614e4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1dfe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" closeCompleteSerializedMessage = "0709110b000001360000006f0000000000bc614e4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1dfe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" diff --git a/lnwire/close_request.go b/lnwire/close_request.go index 37de2b9af..3ab8ae00f 100644 --- a/lnwire/close_request.go +++ b/lnwire/close_request.go @@ -2,26 +2,48 @@ package lnwire import ( "fmt" + "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcutil" "io" ) +// CloseRequest is sent by either side in order to initiate the cooperative +// closure of a channel. This message is rather sparse as both side implicitly +// know to craft a transaction sending the settled funds of both parties to the +// final delivery addresses negotiated during the funding workflow. +// +// NOTE: The requester is able to only send a signature to initiate the +// cooperative channel closure as all transactions are assembled observing +// BIP 69 which defines a cannonical ordering for input/outputs. Therefore, +// both sides are able to arrive at an identical closure transaction as they +// know the order of the inputs/outputs. type CloseRequest struct { - ReservationID uint64 + // ChannelID serves to identify which channel is to be closed. + ChannelID uint64 - RequesterCloseSig *btcec.Signature // Requester's Commitment - Fee btcutil.Amount + // RequesterCloseSig is the signature of the requester for the fully + // assembled closing transaction. + RequesterCloseSig *btcec.Signature + + // Fee is the required fee-per-KB the closing transaction must have. + // It is recommended that a "sufficient" fee be paid in order to achieve + // timely channel closure. + Fee btcutil.Amount } +// Decode deserializes a serialized CloseRequest stored in the passed io.Reader +// observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *CloseRequest) Decode(r io.Reader, pver uint32) error { - // ReservationID (8) + // ChannelID (8) // RequesterCloseSig (73) // First byte length then sig // Fee (8) err := readElements(r, - &c.ReservationID, + &c.ChannelID, &c.RequesterCloseSig, &c.Fee) if err != nil { @@ -31,19 +53,25 @@ func (c *CloseRequest) Decode(r io.Reader, pver uint32) error { return nil } -// Creates a new CloseRequest +// NewCloseRequest creates a new CloseRequest. func NewCloseRequest() *CloseRequest { return &CloseRequest{} } -// Serializes the item from the CloseRequest struct -// Writes the data to w +// A compile time check to ensure CloseRequest implements the lnwire.Message +// interface. +var _ Message = (*CloseRequest)(nil) + +// Encode serializes the target CloseRequest into the passed io.Writer observing +// the protocol version specified. +// +// This is part of the lnwire.Message interface. func (c *CloseRequest) Encode(w io.Writer, pver uint32) error { - // ReservationID + // ChannelID // RequesterCloseSig // Fee err := writeElements(w, - c.ReservationID, + c.ChannelID, c.RequesterCloseSig, c.Fee) if err != nil { @@ -53,25 +81,40 @@ func (c *CloseRequest) Encode(w io.Writer, pver uint32) error { return nil } +// Command returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. func (c *CloseRequest) Command() uint32 { return CmdCloseRequest } -func (c *CloseRequest) MaxPayloadLength(uint32) uint32 { +// MaxPayloadLength returns the maximum allowed payload size for this message +// observing the specified protocol version. +// +// This is part of the lnwire.Message interface. +func (c *CloseRequest) MaxPayloadLength(pver uint32) uint32 { // 8 + 73 + 8 return 89 } -// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) +// Validate performs any necessary sanity checks to ensure all fields present +// on the CloseRequest are valid. +// +// This is part of the lnwire.Message interface. func (c *CloseRequest) Validate() error { - // Fee must be greater than 0 + // Fee must be greater than 0. if c.Fee < 0 { return fmt.Errorf("Fee must be greater than zero.") } + // We're good! return nil } +// String returns the string representation of the target CloseRequest. +// +// This is part of the lnwire.Message interface. func (c *CloseRequest) String() string { var serializedSig []byte if c.RequesterCloseSig != nil && c.RequesterCloseSig.R != nil { @@ -79,7 +122,7 @@ func (c *CloseRequest) String() string { } return fmt.Sprintf("\n--- Begin CloseRequest ---\n") + - fmt.Sprintf("ReservationID:\t\t%d\n", c.ReservationID) + + fmt.Sprintf("ChannelID:\t\t%d\n", c.ChannelID) + fmt.Sprintf("CloseSig\t\t%x\n", serializedSig) + fmt.Sprintf("Fee:\t\t\t%d\n", c.Fee) + fmt.Sprintf("--- End CloseRequest ---\n") diff --git a/lnwire/close_request_test.go b/lnwire/close_request_test.go index 3f1c4e24f..e4d15b9f5 100644 --- a/lnwire/close_request_test.go +++ b/lnwire/close_request_test.go @@ -1,13 +1,14 @@ package lnwire import ( - "github.com/roasbeef/btcutil" "testing" + + "github.com/roasbeef/btcutil" ) var ( closeRequest = &CloseRequest{ - ReservationID: uint64(12345678), + ChannelID: uint64(12345678), RequesterCloseSig: commitSig, Fee: btcutil.Amount(12345), } diff --git a/lnwire/commit_revocation.go b/lnwire/commit_revocation.go index 69f55c925..114e4c17f 100644 --- a/lnwire/commit_revocation.go +++ b/lnwire/commit_revocation.go @@ -5,17 +5,38 @@ import ( "io" ) -// Multiple Clearing Requests are possible by putting this inside an array of -// clearing requests +// CommitRevocation is sent by either side once a CommitSignature message has +// been received, and validated. This message serves to revoke the prior +// commitment transaction, which was the most up to date version until a +// CommitSignature message referencing the specified ChannelID was received. +// Additionally, this message also piggyback's the next revocation hash that +// Alice should use when constructing the Bob's version of the next commitment +// transaction (which would be done before sending a CommitSignature message). +// This piggybacking allows Alice to send the next CommitSignature message +// modifying Bob's commitment transaction without first asking for a revocation +// hash initially. type CommitRevocation struct { - //Next revocation to use + // ChannelID uniquely identifies to which currently active channel this + // CommitRevocation applies to. + ChannelID uint64 + + // Revocation is the pre-image to the revocation hash of the now prior + // commitment transaction. + Revocation [20]byte + + // NextRevocationHash is the next revocation hash to use to create the + // next commitment transaction which is to be created upon receipt of a + // CommitSignature message. NextRevocationHash [20]byte - Revocation [20]byte } +// Decode deserializes a serialized CommitRevocation message stored in the +// passed io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *CommitRevocation) Decode(r io.Reader, pver uint32) error { - // NextRevocationHash(20) - // Revocation(20) + // NextRevocationHash (20) + // Revocation (20) err := readElements(r, &c.NextRevocationHash, &c.Revocation, @@ -27,13 +48,19 @@ func (c *CommitRevocation) Decode(r io.Reader, pver uint32) error { return nil } -// Creates a new CommitRevocation +// NewCommitRevocation creates a new CommitRevocation message. func NewCommitRevocation() *CommitRevocation { return &CommitRevocation{} } -// Serializes the item from the CommitRevocation struct -// Writes the data to w +// A compile time check to ensure CommitRevocation implements the lnwire.Message +// interface. +var _ Message = (*CommitRevocation)(nil) + +// Encode serializes the target CommitRevocation into the passed io.Writer +// observing the protocol version specified. +// +// This is part of the lnwire.Message interface. func (c *CommitRevocation) Encode(w io.Writer, pver uint32) error { err := writeElements(w, c.NextRevocationHash, @@ -46,22 +73,38 @@ func (c *CommitRevocation) Encode(w io.Writer, pver uint32) error { return nil } +// Command returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. func (c *CommitRevocation) Command() uint32 { return CmdCommitRevocation } +// MaxPayloadLength returns the maximum allowed payload size for a +// CommitRevocation complete message observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *CommitRevocation) MaxPayloadLength(uint32) uint32 { + // 8 + 20 + 20 return 48 } -// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) +// Validate performs any necessary sanity checks to ensure all fields present +// on the CommitRevocation are valid. +// +// This is part of the lnwire.Message interface. func (c *CommitRevocation) Validate() error { // We're good! return nil } +// String returns the string representation of the target CommitRevocation. +// +// This is part of the lnwire.Message interface. func (c *CommitRevocation) String() string { return fmt.Sprintf("\n--- Begin CommitRevocation ---\n") + + fmt.Sprintf("ChannelID:\t%d\n", c.ChannelID) + fmt.Sprintf("NextRevocationHash:\t%x\n", c.NextRevocationHash) + fmt.Sprintf("Revocation:\t%x\n", c.Revocation) + fmt.Sprintf("--- End CommitRevocation ---\n") diff --git a/lnwire/commit_revocation_test.go b/lnwire/commit_revocation_test.go index 8340ce73b..0f62c7797 100644 --- a/lnwire/commit_revocation_test.go +++ b/lnwire/commit_revocation_test.go @@ -11,7 +11,7 @@ var ( commitRevocation = &CommitRevocation{ ChannelID: uint64(12345678), - RevocationProof: revocationHash, // technically it's not a hash... fix later + Revocation: revocationHash, // technically it's not a hash... fix later NextRevocationHash: nextHop, // technically it's not a hash... fix later } commitRevocationSerializedString = "0000000000bc614e4132b6b48371f7b022a16eacb9b2b0ebee134d4194a9ded5a30fc5944cb1e2cbcd980f30616a1440" diff --git a/lnwire/commit_signature.go b/lnwire/commit_signature.go index 2d155a87b..acf10248c 100644 --- a/lnwire/commit_signature.go +++ b/lnwire/commit_signature.go @@ -2,33 +2,47 @@ package lnwire import ( "fmt" + "io" + "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcutil" - "io" ) -// Multiple Clearing Requests are possible by putting this inside an array of -// clearing requests +// CommitSignature is sent by either side to stage any pending HTLC's in the +// reciever's pending set which has not explcitly been rejected via an +// HTLCAddReject message. Implictly, the new commitment transaction constructed +// which has been signed by CommitSig includes all HTLC's in the remote node's +// pending set. A CommitSignature message may be sent after a series of HTLCAdd +// messages in order to batch add several HTLC's with a single signature +// covering all implicitly accepted HTLC's. type CommitSignature struct { - // List of HTLC Keys which are updated from all parties - //UpdatedHTLCKeys []uint64 - HighestPosition uint64 + // ChannelID uniquely identifies to which currently active channel this + // CommitSignature applies to. + ChannelID uint64 - // Total miners' fee that was used + // Fee represents the total miner's fee that was used when constructing + // the new commitment transaction. + // TODO(roasbeef): is the above comment correct? Fee btcutil.Amount - // Signature for the new Commitment - CommitSig *btcec.Signature // Requester's Commitment + // CommitSig is Alice's signature for Bob's new commitment transaction. + // Alice is able to send this signature without requesting any additional + // data due to the piggybacking of Bob's next revocation hash in his + // prior CommitRevocation message, as well as the cannonical ordering + // used for all inputs/outputs within commitment transactions. + CommitSig *btcec.Signature } +// Decode deserializes a serialized CommitSignature message stored in the +// passed io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *CommitSignature) Decode(r io.Reader, pver uint32) error { // ChannelID(8) - // CommitmentHeight(8) - // RevocationHash(20) // Fee(8) // RequesterCommitSig(73max+2) err := readElements(r, - &c.HighestPosition, + &c.ChannelID, &c.Fee, &c.CommitSig, ) @@ -39,59 +53,68 @@ func (c *CommitSignature) Decode(r io.Reader, pver uint32) error { return nil } -// Creates a new CommitSignature +// NewCommitSignature creates a new empty CommitSignature message. func NewCommitSignature() *CommitSignature { return &CommitSignature{} } -// Serializes the item from the CommitSignature struct -// Writes the data to w -func (c *CommitSignature) Encode(w io.Writer, pver uint32) error { - err := writeElements(w, - c.HighestPosition, - c.Fee, - c.CommitSig, - ) - if err != nil { - return err - } +// A compile time check to ensure CommitSignature implements the lnwire.Message +// interface. +var _ Message = (*CommitSignature)(nil) - return nil +// Encode serializes the target CommitSignature into the passed io.Writer +// observing the protocol version specified. +// +// This is part of the lnwire.Message interface. +func (c *CommitSignature) Encode(w io.Writer, pver uint32) error { + // TODO(roasbeef): make similar modificaiton to all other encode/decode + // messags + return writeElements(w, c.ChannelID, c.Fee, c.CommitSig) } +// Command returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. func (c *CommitSignature) Command() uint32 { return CmdCommitSignature } +// MaxPayloadLength returns the maximum allowed payload size for a +// CommitSignature complete message observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *CommitSignature) MaxPayloadLength(uint32) uint32 { - return 8192 + // 8 + 8 + 73 + return 89 } -// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) +// Validate performs any necessary sanity checks to ensure all fields present +// on the CommitSignature are valid. +// +// This is part of the lnwire.Message interface. func (c *CommitSignature) Validate() error { if c.Fee < 0 { // While fees can be negative, it's too confusing to allow // negative payments. Maybe for some wallets, but not this one! return fmt.Errorf("Amount paid cannot be negative.") } + // We're good! return nil } +// String returns the string representation of the target CommitSignature. +// +// This is part of the lnwire.Message interface. func (c *CommitSignature) String() string { - // c.ChannelID, - // c.CommitmentHeight, - // c.RevocationHash, - // c.UpdatedHTLCKeys, - // c.Fee, - // c.CommitSig, var serializedSig []byte - if c.CommitSig != nil && c.CommitSig.R != nil { + if c.CommitSig != nil { serializedSig = c.CommitSig.Serialize() } return fmt.Sprintf("\n--- Begin CommitSignature ---\n") + - fmt.Sprintf("HighestPosition:\t%d\n", c.HighestPosition) + + fmt.Sprintf("ChannelID:\t%d\n", c.ChannelID) + fmt.Sprintf("Fee:\t\t\t%s\n", c.Fee.String()) + fmt.Sprintf("CommitSig:\t\t%x\n", serializedSig) + fmt.Sprintf("--- End CommitSignature ---\n") diff --git a/lnwire/commit_signature_test.go b/lnwire/commit_signature_test.go index c90e12aa1..20a6fe199 100644 --- a/lnwire/commit_signature_test.go +++ b/lnwire/commit_signature_test.go @@ -1,8 +1,9 @@ package lnwire import ( - "github.com/roasbeef/btcutil" "testing" + + "github.com/roasbeef/btcutil" ) var ( @@ -10,13 +11,9 @@ var ( _ = copy(revocationHash[:], revocationHashBytes) commitSignature = &CommitSignature{ - ChannelID: uint64(12345678), - CommitmentHeight: uint64(12345), - LastCommittedKeyAlice: HTLCKey(12345), - LastCommittedKeyBob: HTLCKey(54321), - RevocationHash: revocationHash, - Fee: btcutil.Amount(10000), - CommitSig: commitSig, + ChannelID: uint64(12345678), + Fee: btcutil.Amount(10000), + CommitSig: commitSig, } commitSignatureSerializedString = "0000000000bc614e00000000000030390000000000003039000000000000d4314132b6b48371f7b022a16eacb9b2b0ebee134d4100000000000027104630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df" commitSignatureSerializedMessage = "0709110b000007d0000000830000000000bc614e00000000000030390000000000003039000000000000d4314132b6b48371f7b022a16eacb9b2b0ebee134d4100000000000027104630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df" diff --git a/lnwire/error_generic.go b/lnwire/error_generic.go index 4f7bdfa17..c7ab6bfa0 100644 --- a/lnwire/error_generic.go +++ b/lnwire/error_generic.go @@ -5,16 +5,30 @@ import ( "io" ) -// Multiple Clearing Requests are possible by putting this inside an array of -// clearing requests +// ErrorGeneric represents a generic error bound to an exact channel. The +// message format is purposefully general in order to allow expressino of a wide +// array of possible errors. Each ErrorGeneric message is directed at a particular +// open channel referenced by ChannelID. type ErrorGeneric struct { - // We can use a different data type for this if necessary... + // ChannelID references the active channel in which the error occured + // within. ChannelID uint64 - // Some kind of message - // Max length 8192 + + // TODO(roasbeef): uint16 for problem type? + // ErrorID uint16 + + // Problem is a human-readable string further elaborating upon the + // nature of the exact error. The maxmium allowed length of this + // message is 8192 bytes. Problem string + + // TODO(roasbeef): add SerializeSize? } +// Decode deserializes a serialized ErrorGeneric message stored in the +// passed io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *ErrorGeneric) Decode(r io.Reader, pver uint32) error { // ChannelID(8) // Problem @@ -29,13 +43,19 @@ func (c *ErrorGeneric) Decode(r io.Reader, pver uint32) error { return nil } -// Creates a new ErrorGeneric +// NewErrorGeneric creates a new ErrorGeneric message. func NewErrorGeneric() *ErrorGeneric { return &ErrorGeneric{} } -// Serializes the item from the ErrorGeneric struct -// Writes the data to w +// A compile time check to ensure ErrorGeneric implements the lnwire.Message +// interface. +var _ Message = (*ErrorGeneric)(nil) + +// Encode serializes the target ErrorGeneric into the passed io.Writer +// observing the protocol version specified. +// +// This is part of the lnwire.Message interface. func (c *ErrorGeneric) Encode(w io.Writer, pver uint32) error { err := writeElements(w, c.ChannelID, @@ -48,24 +68,39 @@ func (c *ErrorGeneric) Encode(w io.Writer, pver uint32) error { return nil } +// Command returns the integer uniquely identifying an ErrorGeneric message on +// the wire. +// +// This is part of the lnwire.Message interface. func (c *ErrorGeneric) Command() uint32 { return CmdErrorGeneric } +// MaxPayloadLength returns the maximum allowed payload size for a +// ErrorGeneric complete message observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *ErrorGeneric) MaxPayloadLength(uint32) uint32 { // 8+8192 return 8208 } -// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) +// Validate performs any necessary sanity checks to ensure all fields present +// on the ErrorGeneric are valid. +// +// This is part of the lnwire.Message interface. func (c *ErrorGeneric) Validate() error { if len(c.Problem) > 8192 { - return fmt.Errorf("Problem string length too long") + return fmt.Errorf("problem string length too long") } + // We're good! return nil } +// String returns the string representation of the target ErrorGeneric. +// +// This is part of the lnwire.Message interface. func (c *ErrorGeneric) String() string { return fmt.Sprintf("\n--- Begin ErrorGeneric ---\n") + fmt.Sprintf("ChannelID:\t%d\n", c.ChannelID) + diff --git a/lnwire/funding_request.go b/lnwire/funding_request.go index 98b6a9c2a..279acd4b2 100644 --- a/lnwire/funding_request.go +++ b/lnwire/funding_request.go @@ -2,10 +2,11 @@ package lnwire import ( "fmt" + "io" + "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/wire" "github.com/roasbeef/btcutil" - "io" ) type FundingRequest struct { @@ -150,8 +151,6 @@ func (c *FundingRequest) MaxPayloadLength(uint32) uint32 { // Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) func (c *FundingRequest) Validate() error { - var err error - // No negative values if c.RequesterFundingAmount < 0 { return fmt.Errorf("RequesterFundingAmount cannot be negative") @@ -187,15 +186,16 @@ func (c *FundingRequest) Validate() error { } // DeliveryPkScript is either P2SH or P2PKH - err = ValidatePkScript(c.DeliveryPkScript) - if err != nil { - return err + if !isValidPkScript(c.DeliveryPkScript) { + // TODO(roasbeef): move into actual error + return fmt.Errorf("Valid delivery public key scripts MUST be: " + + "P2PKH, P2WKH, P2SH, or P2WSH.") } // ChangePkScript is either P2SH or P2PKH - err = ValidatePkScript(c.ChangePkScript) - if err != nil { - return err + if !isValidPkScript(c.ChangePkScript) { + return fmt.Errorf("Valid change public key script MUST be: " + + "P2PKH, P2WKH, P2SH, or P2WSH.") } // We're good! diff --git a/lnwire/funding_request_test.go b/lnwire/funding_request_test.go index 38f473d07..e8f504068 100644 --- a/lnwire/funding_request_test.go +++ b/lnwire/funding_request_test.go @@ -1,8 +1,9 @@ package lnwire import ( - "github.com/roasbeef/btcutil" "testing" + + "github.com/roasbeef/btcutil" ) var ( diff --git a/lnwire/funding_response.go b/lnwire/funding_response.go index b6e37240b..90416728f 100644 --- a/lnwire/funding_response.go +++ b/lnwire/funding_response.go @@ -2,10 +2,11 @@ package lnwire import ( "fmt" + "io" + "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/wire" "github.com/roasbeef/btcutil" - "io" ) type FundingResponse struct { @@ -134,8 +135,6 @@ func (c *FundingResponse) MaxPayloadLength(uint32) uint32 { // Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) func (c *FundingResponse) Validate() error { - var err error - // No negative values if c.ResponderFundingAmount < 0 { return fmt.Errorf("ResponderFundingAmount cannot be negative") @@ -160,15 +159,16 @@ func (c *FundingResponse) Validate() error { } // Delivery PkScript is either P2SH or P2PKH - err = ValidatePkScript(c.DeliveryPkScript) - if err != nil { - return err + if !isValidPkScript(c.DeliveryPkScript) { + return fmt.Errorf("Valid delivery public key scripts MUST be: " + + "P2PKH, P2WKH, P2SH, or P2WSH.") } // Change PkScript is either P2SH or P2PKH - err = ValidatePkScript(c.ChangePkScript) - if err != nil { - return err + if !isValidPkScript(c.ChangePkScript) { + // TODO(roasbeef): move into actual error + return fmt.Errorf("Valid change public key scripts MUST be: " + + "P2PKH, P2WKH, P2SH, or P2WSH.") } // We're good! diff --git a/lnwire/funding_response_test.go b/lnwire/funding_response_test.go index 0ba635309..30fb90da7 100644 --- a/lnwire/funding_response_test.go +++ b/lnwire/funding_response_test.go @@ -1,8 +1,9 @@ package lnwire import ( - "github.com/roasbeef/btcutil" "testing" + + "github.com/roasbeef/btcutil" ) var ( diff --git a/lnwire/funding_signaccept.go b/lnwire/funding_signaccept.go index 84820ca83..42042bbf4 100644 --- a/lnwire/funding_signaccept.go +++ b/lnwire/funding_signaccept.go @@ -2,8 +2,9 @@ package lnwire import ( "fmt" - "github.com/roasbeef/btcd/btcec" "io" + + "github.com/roasbeef/btcd/btcec" ) type FundingSignAccept struct { diff --git a/lnwire/funding_signcomplete.go b/lnwire/funding_signcomplete.go index f3a1bba3c..ce81a9af5 100644 --- a/lnwire/funding_signcomplete.go +++ b/lnwire/funding_signcomplete.go @@ -2,9 +2,10 @@ package lnwire import ( "fmt" + "io" + "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/wire" - "io" ) type FundingSignComplete struct { diff --git a/lnwire/htlc_addreject.go b/lnwire/htlc_addreject.go index dadfb390b..b93c9c775 100644 --- a/lnwire/htlc_addreject.go +++ b/lnwire/htlc_addreject.go @@ -5,17 +5,28 @@ import ( "io" ) +// HTLCAddReject is sent by Bob when he wishes to reject a particular HTLC that +// Alice attempted to add via an HTLCAddRequest message. The rejected HTLC is +// referenced by its unique HTLCKey ID. An HTLCAddReject message is bound to a +// single active channel, referenced by a unique ChannelID. Additionally, the +// HTLCKey of the rejected HTLC is present type HTLCAddReject struct { + // ChannelID references the particular active channel to which this + // HTLCAddReject message is binded to. ChannelID uint64 - HTLCKey HTLCKey + + // HTLCKey is used to identify which HTLC previously attempted to be + // added via an HTLCAddRequest message is being declined. + HTLCKey HTLCKey } +// Decode deserializes a serialized HTLCAddReject message stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddReject) Decode(r io.Reader, pver uint32) error { - // ChannelID(8) - // CommitmentHeight(8) - // NextResponderCommitmentRevocationHash(20) - // ResponderRevocationPreimage(20) - // ResponderCommitSig(2+73max) + // ChannelID (8) + // HTLCKey (8) err := readElements(r, &c.ChannelID, &c.HTLCKey, @@ -27,13 +38,19 @@ func (c *HTLCAddReject) Decode(r io.Reader, pver uint32) error { return nil } -// Creates a new HTLCAddReject +// NewHTLCAddReject returns a new empty HTLCAddReject message. func NewHTLCAddReject() *HTLCAddReject { return &HTLCAddReject{} } -// Serializes the item from the HTLCAddReject struct -// Writes the data to w +// A compile time check to ensure HTLCAddReject implements the lnwire.Message +// interface. +var _ Message = (*HTLCAddReject)(nil) + +// Encode serializes the target HTLCAddReject into the passed io.Writer observing +// the protocol version specified. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddReject) Encode(w io.Writer, pver uint32) error { err := writeElements(w, c.ChannelID, @@ -47,21 +64,35 @@ func (c *HTLCAddReject) Encode(w io.Writer, pver uint32) error { return nil } +// Command returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddReject) Command() uint32 { return CmdHTLCAddReject } +// MaxPayloadLength returns the maximum allowed payload size for a HTLCAddReject +// complete message observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddReject) MaxPayloadLength(uint32) uint32 { - // 16 base size + // 8 + 8 return 16 } -// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) +// Validate performs any necessary sanity checks to ensure all fields present +// on the HTLCAddReject are valid. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddReject) Validate() error { // We're good! return nil } +// String returns the string representation of the target HTLCAddReject. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddReject) String() string { return fmt.Sprintf("\n--- Begin HTLCAddReject ---\n") + fmt.Sprintf("ChannelID:\t\t%d\n", c.ChannelID) + diff --git a/lnwire/htlc_addreject_test.go b/lnwire/htlc_addreject_test.go index 6be29732e..09f10449f 100644 --- a/lnwire/htlc_addreject_test.go +++ b/lnwire/htlc_addreject_test.go @@ -7,7 +7,7 @@ import ( var ( htlcAddReject = &HTLCAddReject{ ChannelID: uint64(12345678), - HTLCKey: HTLCKey(12345), + HTLCKey: HTLCKey(12345), } htlcAddRejectSerializedString = "0000000000bc614e0000000000003039" htlcAddRejectSerializedMessage = "0709110b000003fc000000100000000000bc614e0000000000003039" diff --git a/lnwire/htlc_addrequest.go b/lnwire/htlc_addrequest.go index 3a3e2f90d..e7eca7aec 100644 --- a/lnwire/htlc_addrequest.go +++ b/lnwire/htlc_addrequest.go @@ -5,56 +5,83 @@ import ( "io" ) -// Multiple Clearing Requests are possible by putting this inside an array of -// clearing requests +// HTLCAddRequest is the message sent by Alice to Bob when she wishes to add an +// HTLC to his remote commitment transaction. In addition to information +// detailing the value, and contract type of the HTLC, and onion blob is also +// included which allows Bob to derive the next hop in the route. The HTLC +// added by this message is to be added to the remote node's "pending" HTLC's. +// A subsequent CommitSignature message will move the pending HTLC to the newly +// created commitment transaction, marking them as "staged". type HTLCAddRequest struct { - // We can use a different data type for this if necessary... + // ChannelID is the particular active channel that this HTLCAddRequest + // is binded to. ChannelID uint64 - // ID of this request - // implicit - // HTLCKey HTLCKey - - // When the HTLC expires + // Expiry is the number of blocks after which this HTLC should expire. + // It is the receiver's duty to ensure that the outgoing HTLC has a + // sufficient expiry value to allow her to redeem the incmoing HTLC. Expiry uint32 // Amount to pay in the hop // Difference between hop and first item in blob is the fee to complete + + // Amount is the number of credits this HTLC is worth. Amount CreditsAmount // RefundContext is for payment cancellation - // TODO (j): not currently in use, add later + // TODO(j): not currently in use, add later RefundContext HTLCKey - // Contract Type - // first 4 bits is n, second for is m, in n-of-m "multisig" - // default is 0. + // ContractType defines the particular output script to be used for + // this HTLC. This value defaults to zero for regular HTLCs. For + // multi-sig HTLCs, then first 4 bit represents N, while the second 4 + // bits are M, within the N-of-M multi-sig. ContractType uint8 - // Redemption Hashes - RedemptionHashes []*[20]byte + // RedemptionHashes are the hashes to be used within the HTLC script. + // An HTLC is only fufilled once Bob is provided with the required + // number of pre-images for each of the listed hashes. For regular HTLC's + // this slice only has one hash. However, for "multi-sig" HTLC's, the + // length of this slice should be N. + RedemptionHashes [][20]byte // Data to parse&pass on to the next node // Nested HTLCAddRequests with a uint32 in front for the size Blob []byte + + // OnionBlob is the raw serialized mix header used to route an HTLC in + // a privacy-preserving manner. The mix header is defined currently to + // be parsed as a 4-tuple: (groupElement, routingInfo, headerMAC, body). + // First the receiving node should use the groupElement, and its current + // onion key to derive a shared secret with the source. Once the shared + // secret has been derived, the headerMAC should be checked FIRST. Note + // that the MAC only covers the routingInfo field. If the MAC matches, + // and the shared secret is fresh, then the node should stip off a layer + // of encryption, exposing the next hop to be used in the subsequent + // HTLCAddRequest message. + OnionBlob []byte } +// Decode deserializes a serialized HTLCAddRequest message stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddRequest) Decode(r io.Reader, pver uint32) error { // ChannelID(8) - // HTLCKey(8) // Expiry(4) // Amount(4) // ContractType(1) // RedemptionHashes (numOfHashes * 20 + numOfHashes) // Blob(2+blobsize) + // OnionBlog err := readElements(r, &c.ChannelID, - &c.HTLCKey, &c.Expiry, &c.Amount, &c.ContractType, &c.RedemptionHashes, &c.Blob, + &c.OnionBlob, ) if err != nil { return err @@ -63,22 +90,28 @@ func (c *HTLCAddRequest) Decode(r io.Reader, pver uint32) error { return nil } -// Creates a new HTLCAddRequest +// NewHTLCAddRequest returns a new empty HTLCAddRequest message. func NewHTLCAddRequest() *HTLCAddRequest { return &HTLCAddRequest{} } -// Serializes the item from the HTLCAddRequest struct -// Writes the data to w +// A compile time check to ensure HTLCAddRequest implements the lnwire.Message +// interface. +var _ Message = (*HTLCAddRequest)(nil) + +// Encode serializes the target HTLCAddRequest into the passed io.Writer observing +// the protocol version specified. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddRequest) Encode(w io.Writer, pver uint32) error { err := writeElements(w, c.ChannelID, - c.HTLCKey, c.Expiry, c.Amount, c.ContractType, c.RedemptionHashes, c.Blob, + c.OnionBlob, ) if err != nil { return err @@ -87,17 +120,28 @@ func (c *HTLCAddRequest) Encode(w io.Writer, pver uint32) error { return nil } +// Command returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddRequest) Command() uint32 { return CmdHTLCAddRequest } +// MaxPayloadLength returns the maximum allowed payload size for a HTLCAddRequest +// complete message observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddRequest) MaxPayloadLength(uint32) uint32 { // base size ~110, but blob can be variable. // shouldn't be bigger than 8K though... return 8192 } -// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) +// Validate performs any necessary sanity checks to ensure all fields present +// on the HTLCAddRequest are valid. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddRequest) Validate() error { if c.Amount < 0 { // While fees can be negative, it's too confusing to allow @@ -108,21 +152,24 @@ func (c *HTLCAddRequest) Validate() error { return nil } +// String returns the string representation of the target HTLCAddRequest. +// +// This is part of the lnwire.Message interface. func (c *HTLCAddRequest) String() string { var redemptionHashes string for i, rh := range c.RedemptionHashes { redemptionHashes += fmt.Sprintf("\n\tSlice\t%d\n", i) - redemptionHashes += fmt.Sprintf("\t\tRedemption Hash: %x\n", *rh) + redemptionHashes += fmt.Sprintf("\t\tRedemption Hash: %x\n", rh) } return fmt.Sprintf("\n--- Begin HTLCAddRequest ---\n") + fmt.Sprintf("ChannelID:\t%d\n", c.ChannelID) + - fmt.Sprintf("HTLCKey:\t%d\n", c.HTLCKey) + fmt.Sprintf("Expiry:\t\t%d\n", c.Expiry) + fmt.Sprintf("Amount\t\t%d\n", c.Amount) + fmt.Sprintf("ContractType:\t%d (%b)\n", c.ContractType, c.ContractType) + fmt.Sprintf("RedemptionHashes:") + redemptionHashes + fmt.Sprintf("Blob:\t\t\t\t%x\n", c.Blob) + + fmt.Sprintf("OnionBlob:\t\t\t\t%x\n", c.OnionBlob) + fmt.Sprintf("--- End HTLCAddRequest ---\n") } diff --git a/lnwire/htlc_addrequest_test.go b/lnwire/htlc_addrequest_test.go index 3e14e9157..74a3d922d 100644 --- a/lnwire/htlc_addrequest_test.go +++ b/lnwire/htlc_addrequest_test.go @@ -8,18 +8,16 @@ var ( // Need to to do this here _ = copy(revocationHash[:], revocationHashBytes) _ = copy(redemptionHash[:], redemptionHashBytes) - emptyRedemptionHashes = []*[20]byte{} - redemptionHashes = append(emptyRedemptionHashes, &redemptionHash) + emptyRedemptionHashes = [][20]byte{} + redemptionHashes = append(emptyRedemptionHashes, redemptionHash) htlcAddRequest = &HTLCAddRequest{ ChannelID: uint64(12345678), - HTLCKey: HTLCKey(12345), Expiry: uint32(144), Amount: CreditsAmount(123456000), ContractType: uint8(17), RedemptionHashes: redemptionHashes, - - Blob: []byte{255, 0, 255, 0, 255, 0, 255, 0}, + Blob: []byte{255, 0, 255, 0, 255, 0, 255, 0}, } htlcAddRequestSerializedString = "0000000000bc614e00000000000030390000009000000000075bca001100015b315ebabb0d8c0d94281caa2dfee69a1a00436e0008ff00ff00ff00ff00" diff --git a/lnwire/htlc_settlerequest.go b/lnwire/htlc_settlerequest.go index 5eb9e2f85..015d24d19 100644 --- a/lnwire/htlc_settlerequest.go +++ b/lnwire/htlc_settlerequest.go @@ -5,19 +5,32 @@ import ( "io" ) -// Multiple Clearing Requests are possible by putting this inside an array of -// clearing requests +// HTLCSettleRequest is sent by Alice to Bob when she wishes to settle a +// particular HTLC referenced by its HTLCKey within a specific active channel +// referenced by ChannelID. The message allows multiple hash preimages to be +// presented in order to support N-of-M HTLC contracts. A subsequent +// CommitSignature message will be sent by Alice to "lock-in" the removal of the +// specified HTLC, possible containing a batch signature covering several settled +// HTLC's. type HTLCSettleRequest struct { - // We can use a different data type for this if necessary... + // ChannelID references an active channel which holds the HTLC to be + // settled. ChannelID uint64 - // ID of this request + // HTLCKey denotes the exact HTLC stage within the receiving node's + // commitment transaction to be removed. HTLCKey HTLCKey - // Redemption Proofs (R-Values) - RedemptionProofs []*[20]byte + // RedemptionProofs are the R-value preimages required to fully settle + // an HTLC. The number of preimages in the slice will depend on the + // specific ContractType of the referenced HTLC. + RedemptionProofs [][20]byte } +// Decode deserializes a serialized HTLCSettleRequest message stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *HTLCSettleRequest) Decode(r io.Reader, pver uint32) error { // ChannelID(8) // HTLCKey(8) @@ -39,11 +52,15 @@ func (c *HTLCSettleRequest) Decode(r io.Reader, pver uint32) error { return nil } -// Creates a new HTLCSettleRequest +// NewHTLCSettleRequest returns a new empty HTLCSettleRequest. func NewHTLCSettleRequest() *HTLCSettleRequest { return &HTLCSettleRequest{} } +// A compile time check to ensure HTLCSettleRequest implements the lnwire.Message +// interface. +var _ Message = (*HTLCSettleRequest)(nil) + // Serializes the item from the HTLCSettleRequest struct // Writes the data to w func (c *HTLCSettleRequest) Encode(w io.Writer, pver uint32) error { @@ -59,26 +76,40 @@ func (c *HTLCSettleRequest) Encode(w io.Writer, pver uint32) error { return nil } +// Command returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. func (c *HTLCSettleRequest) Command() uint32 { return CmdHTLCSettleRequest } +// MaxPayloadLength returns the maximum allowed payload size for a HTLCSettleRequest +// complete message observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *HTLCSettleRequest) MaxPayloadLength(uint32) uint32 { - // 21*15+16 + // 8 + 8 + (21 * 15) return 331 } -// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) +// Validate performs any necessary sanity checks to ensure all fields present +// on the HTLCSettleRequest are valid. +// +// This is part of the lnwire.Message interface. func (c *HTLCSettleRequest) Validate() error { // We're good! return nil } +// String returns the string representation of the target HTLCSettleRequest. +// +// This is part of the lnwire.Message interface. func (c *HTLCSettleRequest) String() string { var redemptionProofs string for i, rh := range c.RedemptionProofs { redemptionProofs += fmt.Sprintf("\n\tSlice\t%d\n", i) - redemptionProofs += fmt.Sprintf("\t\tRedemption Proof: %x\n", *rh) + redemptionProofs += fmt.Sprintf("\t\tRedemption Proof: %x\n", rh) } return fmt.Sprintf("\n--- Begin HTLCSettleRequest ---\n") + diff --git a/lnwire/htlc_settlerequest_test.go b/lnwire/htlc_settlerequest_test.go index 3f79d871b..51018d8c5 100644 --- a/lnwire/htlc_settlerequest_test.go +++ b/lnwire/htlc_settlerequest_test.go @@ -7,8 +7,8 @@ import ( var ( // Need to to do this here _ = copy(redemptionHash[:], redemptionHashBytes) - emptyRedemptionProofs = []*[20]byte{} - redemptionProofs = append(emptyRedemptionProofs, &redemptionHash) + emptyRedemptionProofs = [][20]byte{} + redemptionProofs = append(emptyRedemptionProofs, redemptionHash) htlcSettleRequest = &HTLCSettleRequest{ ChannelID: uint64(12345678), diff --git a/lnwire/htlc_timeoutrequest.go b/lnwire/htlc_timeoutrequest.go index 3a27194c3..3c0f3573d 100644 --- a/lnwire/htlc_timeoutrequest.go +++ b/lnwire/htlc_timeoutrequest.go @@ -5,16 +5,24 @@ import ( "io" ) -// Multiple Clearing Requests are possible by putting this inside an array of -// clearing requests +// HTLCTimeoutRequest is sent by Alice to Bob in order to timeout a previously +// added HTLC. Upon receipt of an HTLCTimeoutRequest the HTLC should be removed +// from the next commitment transaction, with the HTLCTimeoutRequest propgated +// backwards in the route to fully clear the HTLC. type HTLCTimeoutRequest struct { - // We can use a different data type for this if necessary... + // ChannelID is the particular active channel that this HTLCTimeoutRequest + // is binded to. ChannelID uint64 - // ID of this request + // HTLCKey references which HTLC on the remote node's commitment + // transaction has timed out. HTLCKey HTLCKey } +// Decode deserializes a serialized HTLCTimeoutRequest message stored in the passed +// io.Reader observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *HTLCTimeoutRequest) Decode(r io.Reader, pver uint32) error { // ChannelID(8) // HTLCKey(8) @@ -29,13 +37,19 @@ func (c *HTLCTimeoutRequest) Decode(r io.Reader, pver uint32) error { return nil } -// Creates a new HTLCTimeoutRequest +// NewHTLCTimeoutRequest creates a new HTLCTimeoutRequest message. func NewHTLCTimeoutRequest() *HTLCTimeoutRequest { return &HTLCTimeoutRequest{} } -// Serializes the item from the HTLCTimeoutRequest struct -// Writes the data to w +// A compile time check to ensure HTLCTimeoutRequest implements the lnwire.Message +// interface. +var _ Message = (*HTLCTimeoutRequest)(nil) + +// Encode serializes the target HTLCTimeoutRequest into the passed io.Writer observing +// the protocol version specified. +// +// This is part of the lnwire.Message interface. func (c *HTLCTimeoutRequest) Encode(w io.Writer, pver uint32) error { err := writeElements(w, c.ChannelID, @@ -48,21 +62,34 @@ func (c *HTLCTimeoutRequest) Encode(w io.Writer, pver uint32) error { return nil } +// Command returns the integer uniquely identifying this message type on the +// wire. +// +// This is part of the lnwire.Message interface. func (c *HTLCTimeoutRequest) Command() uint32 { return CmdHTLCTimeoutRequest } +// MaxPayloadLength returns the maximum allowed payload size for a HTLCTimeoutRequest +// complete message observing the specified protocol version. +// +// This is part of the lnwire.Message interface. func (c *HTLCTimeoutRequest) MaxPayloadLength(uint32) uint32 { // 16 return 16 } -// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts) +// Validate performs any necessary sanity checks to ensure all fields present +// on the HTLCTimeoutRequest are valid. +// +// This is part of the lnwire.Message interface. func (c *HTLCTimeoutRequest) Validate() error { // We're good! return nil } +// String returns the string representation of the target HTLCTimeoutRequest. // +// This is part of the lnwire.Message interface. func (c *HTLCTimeoutRequest) String() string { return fmt.Sprintf("\n--- Begin HTLCTimeoutRequest ---\n") + fmt.Sprintf("ChannelID:\t%d\n", c.ChannelID) + diff --git a/lnwire/htlc_timeoutrequest_test.go b/lnwire/htlc_timeoutrequest_test.go index 3325f88bc..97c20c292 100644 --- a/lnwire/htlc_timeoutrequest_test.go +++ b/lnwire/htlc_timeoutrequest_test.go @@ -7,7 +7,7 @@ import ( var ( htlcTimeoutRequest = &HTLCTimeoutRequest{ ChannelID: uint64(12345678), - HTLCKey: HTLCKey(12345), + HTLCKey: HTLCKey(12345), } htlcTimeoutRequestSerializedString = "0000000000bc614e0000000000003039" htlcTimeoutRequestSerializedMessage = "0709110b00000514000000100000000000bc614e0000000000003039" diff --git a/server.go b/server.go index 97aabdda2..fe67771c6 100644 --- a/server.go +++ b/server.go @@ -209,6 +209,8 @@ func (s *server) listener(l net.Listener) { srvrLog.Tracef("New inbound connection from %v", conn.RemoteAddr()) peer := newPeer(conn, s) peer.Start() + + s.newPeers <- peer } s.wg.Done()