lnwire: add DustLimit to SingleFundingRequest and SingleFundingResponse

This commit is contained in:
Andrey Samokhvalov authored and Olaoluwa Osuntokun committed 2016-12-13 11:01:57 -08:00
1 parent 202fce5501
commit c731156ac8
4 files changed
+57 -20

No files matched your search

+25 -8
View File
@@ -68,13 +68,19 @@ type SingleFundingRequest struct {
// supported: P2PKH, P2WKH, P2SH, and P2WSH. // supported: P2PKH, P2WKH, P2SH, and P2WSH.
DeliveryPkScript PkScript DeliveryPkScript PkScript
// DustLimit is the threshold below which no HTLC output should be
// generated for our commitment transaction; ie. HTLCs below
// this amount are not enforceable onchain from our point view.
DustLimit btcutil.Amount
// TODO(roasbeef): confirmation depth // TODO(roasbeef): confirmation depth
} }
// NewSingleFundingRequest creates, and returns a new empty SingleFundingRequest. // NewSingleFundingRequest creates, and returns a new empty SingleFundingRequest.
func NewSingleFundingRequest(chanID uint64, chanType uint8, coinType uint64, func NewSingleFundingRequest(chanID uint64, chanType uint8, coinType uint64,
fee btcutil.Amount, amt btcutil.Amount, delay uint32, ck, fee btcutil.Amount, amt btcutil.Amount, delay uint32, ck,
cdp *btcec.PublicKey, deliveryScript PkScript) *SingleFundingRequest { cdp *btcec.PublicKey, deliveryScript PkScript,
dustLimit btcutil.Amount) *SingleFundingRequest {
return &SingleFundingRequest{ return &SingleFundingRequest{
ChannelID: chanID, ChannelID: chanID,
@@ -86,6 +92,7 @@ func NewSingleFundingRequest(chanID uint64, chanType uint8, coinType uint64,
CommitmentKey: ck, CommitmentKey: ck,
ChannelDerivationPoint: cdp, ChannelDerivationPoint: cdp,
DeliveryPkScript: deliveryScript, DeliveryPkScript: deliveryScript,
DustLimit: dustLimit,
} }
} }
@@ -104,6 +111,7 @@ func (c *SingleFundingRequest) Decode(r io.Reader, pver uint32) error {
// Pubkey (33) // Pubkey (33)
// Pubkey (33) // Pubkey (33)
// DeliveryPkScript (final delivery) // DeliveryPkScript (final delivery)
// DustLimit (8)
err := readElements(r, err := readElements(r,
&c.ChannelID, &c.ChannelID,
&c.ChannelType, &c.ChannelType,
@@ -113,7 +121,8 @@ func (c *SingleFundingRequest) Decode(r io.Reader, pver uint32) error {
&c.CsvDelay, &c.CsvDelay,
&c.CommitmentKey, &c.CommitmentKey,
&c.ChannelDerivationPoint, &c.ChannelDerivationPoint,
&c.DeliveryPkScript) &c.DeliveryPkScript,
&c.DustLimit)
if err != nil { if err != nil {
return err return err
} }
@@ -136,6 +145,7 @@ func (c *SingleFundingRequest) Encode(w io.Writer, pver uint32) error {
// Pubkey (33) // Pubkey (33)
// Pubkey (33) // Pubkey (33)
// DeliveryPkScript (final delivery) // DeliveryPkScript (final delivery)
// DustLimit (8)
err := writeElements(w, err := writeElements(w,
c.ChannelID, c.ChannelID,
c.ChannelType, c.ChannelType,
@@ -145,7 +155,8 @@ func (c *SingleFundingRequest) Encode(w io.Writer, pver uint32) error {
c.CsvDelay, c.CsvDelay,
c.CommitmentKey, c.CommitmentKey,
c.ChannelDerivationPoint, c.ChannelDerivationPoint,
c.DeliveryPkScript) c.DeliveryPkScript,
c.DustLimit)
if err != nil { if err != nil {
return err return err
} }
@@ -165,11 +176,12 @@ func (c *SingleFundingRequest) Command() uint32 {
// SingleFundingRequest. This is calculated by summing the max length of all // SingleFundingRequest. This is calculated by summing the max length of all
// the fields within a SingleFundingRequest. To enforce a maximum // the fields within a SingleFundingRequest. To enforce a maximum
// DeliveryPkScript size, the size of a P2PKH public key script is used. // DeliveryPkScript size, the size of a P2PKH public key script is used.
// Therefore, the final breakdown is: 8 + 1 + 8 + 8 + 8 + 4 + 33 + 33 + 25 = 158. // Therefore, the final breakdown is: 8 + 1 + 8 + 8 + 8 + 4 + 33 + 33 + 25 + 8 =
// 166.
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *SingleFundingRequest) MaxPayloadLength(uint32) uint32 { func (c *SingleFundingRequest) MaxPayloadLength(uint32) uint32 {
return 158 return 166
} }
// Validate examines each populated field within the SingleFundingRequest for // Validate examines each populated field within the SingleFundingRequest for
@@ -210,6 +222,10 @@ func (c *SingleFundingRequest) Validate() error {
"P2PKH, P2WKH, P2SH, or P2WSH.") "P2PKH, P2WKH, P2SH, or P2WSH.")
} }
if c.DustLimit <= 0 {
return fmt.Errorf("Dust limit should be greater than zero.")
}
// We're good! // We're good!
return nil return nil
} }
@@ -231,8 +247,9 @@ func (c *SingleFundingRequest) String() string {
fmt.Sprintf("CoinType:\t\t\t%d\n", c.CoinType) + fmt.Sprintf("CoinType:\t\t\t%d\n", c.CoinType) +
fmt.Sprintf("FeePerKb:\t\t\t%s\n", c.FeePerKb.String()) + fmt.Sprintf("FeePerKb:\t\t\t%s\n", c.FeePerKb.String()) +
fmt.Sprintf("FundingAmount:\t\t\t%s\n", c.FundingAmount.String()) + fmt.Sprintf("FundingAmount:\t\t\t%s\n", c.FundingAmount.String()) +
fmt.Sprintf("CsvDelay\t\t\t%d\n", c.CsvDelay) + fmt.Sprintf("CsvDelay:\t\t\t%d\n", c.CsvDelay) +
fmt.Sprintf("ChannelDerivationPoint\t\t\t\t%x\n", serializedPubkey) + fmt.Sprintf("ChannelDerivationPoint:\t\t\t%x\n", serializedPubkey) +
fmt.Sprintf("DeliveryPkScript\t\t%x\n", c.DeliveryPkScript) + fmt.Sprintf("DeliveryPkScript:\t\t\t%x\n", c.DeliveryPkScript) +
fmt.Sprintf("DustLimit:\t\t\t%d\n", c.DustLimit) +
fmt.Sprintf("--- End SingleFundingRequest ---\n") fmt.Sprintf("--- End SingleFundingRequest ---\n")
} }
+2 -1
View File
@@ -10,7 +10,8 @@ func TestSingleFundingRequestWire(t *testing.T) {
// First create a new SFR message. // First create a new SFR message.
cdp := pubKey cdp := pubKey
delivery := PkScript(bytes.Repeat([]byte{0x02}, 25)) delivery := PkScript(bytes.Repeat([]byte{0x02}, 25))
sfr := NewSingleFundingRequest(20, 21, 22, 23, 5, 5, cdp, cdp, delivery) sfr := NewSingleFundingRequest(20, 21, 22, 23, 5, 5, cdp, cdp,
delivery, 540)
// Next encode the SFR message into an empty bytes buffer. // Next encode the SFR message into an empty bytes buffer.
var b bytes.Buffer var b bytes.Buffer
+28 -10
View File
@@ -5,6 +5,7 @@ import (
"io" "io"
"github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/btcec"
"github.com/roasbeef/btcutil"
) )
// SingleFundingResponse is the message Bob sends to Alice after she initiates // SingleFundingResponse is the message Bob sends to Alice after she initiates
@@ -45,12 +46,18 @@ type SingleFundingResponse struct {
// cooperative close. Only the following script templates are // cooperative close. Only the following script templates are
// supported: P2PKH, P2WKH, P2SH, and P2WSH. // supported: P2PKH, P2WKH, P2SH, and P2WSH.
DeliveryPkScript PkScript DeliveryPkScript PkScript
// DustLimit is the threshold below which no HTLC output should be
// generated for remote commitment transaction; ie. HTLCs below
// this amount are not enforceable onchain for their point of view.
DustLimit btcutil.Amount
} }
// NewSingleFundingResponse creates, and returns a new empty // NewSingleFundingResponse creates, and returns a new empty
// SingleFundingResponse. // SingleFundingResponse.
func NewSingleFundingResponse(chanID uint64, rk, ck, cdp *btcec.PublicKey, func NewSingleFundingResponse(chanID uint64, rk, ck, cdp *btcec.PublicKey,
delay uint32, deliveryScript PkScript) *SingleFundingResponse { delay uint32, deliveryScript PkScript,
dustLimit btcutil.Amount) *SingleFundingResponse {
return &SingleFundingResponse{ return &SingleFundingResponse{
ChannelID: chanID, ChannelID: chanID,
@@ -59,6 +66,7 @@ func NewSingleFundingResponse(chanID uint64, rk, ck, cdp *btcec.PublicKey,
RevocationKey: rk, RevocationKey: rk,
CsvDelay: delay, CsvDelay: delay,
DeliveryPkScript: deliveryScript, DeliveryPkScript: deliveryScript,
DustLimit: dustLimit,
} }
} }
@@ -78,13 +86,15 @@ func (c *SingleFundingResponse) Decode(r io.Reader, pver uint32) error {
// RevocationKey (33) // RevocationKey (33)
// CsvDelay (4) // CsvDelay (4)
// DeliveryPkScript (final delivery) // DeliveryPkScript (final delivery)
// DustLimit (8)
err := readElements(r, err := readElements(r,
&c.ChannelID, &c.ChannelID,
&c.ChannelDerivationPoint, &c.ChannelDerivationPoint,
&c.CommitmentKey, &c.CommitmentKey,
&c.RevocationKey, &c.RevocationKey,
&c.CsvDelay, &c.CsvDelay,
&c.DeliveryPkScript) &c.DeliveryPkScript,
&c.DustLimit)
if err != nil { if err != nil {
return err return err
} }
@@ -104,13 +114,15 @@ func (c *SingleFundingResponse) Encode(w io.Writer, pver uint32) error {
// RevocationKey (33) // RevocationKey (33)
// CsvDelay (4) // CsvDelay (4)
// DeliveryPkScript (final delivery) // DeliveryPkScript (final delivery)
// DustLimit (8)
err := writeElements(w, err := writeElements(w,
c.ChannelID, c.ChannelID,
c.ChannelDerivationPoint, c.ChannelDerivationPoint,
c.CommitmentKey, c.CommitmentKey,
c.RevocationKey, c.RevocationKey,
c.CsvDelay, c.CsvDelay,
c.DeliveryPkScript) c.DeliveryPkScript,
c.DustLimit)
if err != nil { if err != nil {
return err return err
} }
@@ -130,11 +142,11 @@ func (c *SingleFundingResponse) Command() uint32 {
// SingleFundingResponse. This is calculated by summing the max length of all // SingleFundingResponse. This is calculated by summing the max length of all
// the fields within a SingleFundingResponse. To enforce a maximum // the fields within a SingleFundingResponse. To enforce a maximum
// DeliveryPkScript size, the size of a P2PKH public key script is used. // DeliveryPkScript size, the size of a P2PKH public key script is used.
// Therefore, the final breakdown is: 8 + (33 * 3) + 8 + 25 // Therefore, the final breakdown is: 8 + (33 * 3) + 8 + 25 + 8
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *SingleFundingResponse) MaxPayloadLength(uint32) uint32 { func (c *SingleFundingResponse) MaxPayloadLength(uint32) uint32 {
return 140 return 148
} }
// Validate examines each populated field within the SingleFundingResponse for // Validate examines each populated field within the SingleFundingResponse for
@@ -160,6 +172,11 @@ func (c *SingleFundingResponse) Validate() error {
"P2PKH, P2WKH, P2SH, or P2WSH.") "P2PKH, P2WKH, P2SH, or P2WSH.")
} }
if c.DustLimit <= 0 {
return fmt.Errorf("Dust limit shouldn't be below or equal to " +
"zero.")
}
// We're good! // We're good!
return nil return nil
} }
@@ -183,10 +200,11 @@ func (c *SingleFundingResponse) String() string {
return fmt.Sprintf("\n--- Begin SingleFundingResponse ---\n") + return fmt.Sprintf("\n--- Begin SingleFundingResponse ---\n") +
fmt.Sprintf("ChannelID:\t\t\t%d\n", c.ChannelID) + fmt.Sprintf("ChannelID:\t\t\t%d\n", c.ChannelID) +
fmt.Sprintf("ChannelDerivationPoint\t\t\t\t%x\n", cdp) + fmt.Sprintf("ChannelDerivationPoint:\t\t\t\t%x\n", cdp) +
fmt.Sprintf("CommitmentKey\t\t\t\t%x\n", ck) + fmt.Sprintf("CommitmentKey:\t\t\t\t%x\n", ck) +
fmt.Sprintf("RevocationKey\t\t\t\t%x\n", rk) + fmt.Sprintf("RevocationKey:\t\t\t\t%x\n", rk) +
fmt.Sprintf("CsvDelay\t\t%d\n", c.CsvDelay) + fmt.Sprintf("CsvDelay:\t\t%d\n", c.CsvDelay) +
fmt.Sprintf("DeliveryPkScript\t\t%x\n", c.DeliveryPkScript) + fmt.Sprintf("DeliveryPkScript:\t\t%x\n", c.DeliveryPkScript) +
fmt.Sprintf("DustLimit:\t\t\t%d\n", c.DustLimit) +
fmt.Sprintf("--- End SingleFundingResponse ---\n") fmt.Sprintf("--- End SingleFundingResponse ---\n")
} }
+2 -1
View File
@@ -9,7 +9,8 @@ import (
func TestSingleFundingResponseWire(t *testing.T) { func TestSingleFundingResponseWire(t *testing.T) {
// First create a new SFR message. // First create a new SFR message.
delivery := PkScript(bytes.Repeat([]byte{0x02}, 25)) delivery := PkScript(bytes.Repeat([]byte{0x02}, 25))
sfr := NewSingleFundingResponse(22, pubKey, pubKey, pubKey, 5, delivery) sfr := NewSingleFundingResponse(22, pubKey, pubKey, pubKey, 5,
delivery, 540)
// Next encode the SFR message into an empty bytes buffer. // Next encode the SFR message into an empty bytes buffer.
var b bytes.Buffer var b bytes.Buffer