mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-28 14:40:51 +02:00
Funding request serialize/deserialize (io reader/writer and pointers
were very confusing -_-;)
This commit is contained in:
223
lnwire/lnwire.go
223
lnwire/lnwire.go
@@ -1,6 +1,7 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
@@ -12,11 +13,21 @@ import (
|
||||
//Actual pkScript, not redeemScript
|
||||
type PkScript []byte
|
||||
|
||||
//Subsatoshi amount
|
||||
type MicroSatoshi int32
|
||||
|
||||
type CreateChannel struct {
|
||||
ChannelType uint8
|
||||
OurFundingAmount btcutil.Amount
|
||||
OurReserveAmount btcutil.Amount
|
||||
MinFeePerKb btcutil.Amount //higher of both parties
|
||||
ChannelType uint8
|
||||
|
||||
OurFundingAmount btcutil.Amount
|
||||
TheirFundingAmount btcutil.Amount
|
||||
OurReserveAmount btcutil.Amount
|
||||
TheirReserveAmount btcutil.Amount
|
||||
OurMinFeePerKb btcutil.Amount
|
||||
TheirMinFeePerKb btcutil.Amount
|
||||
|
||||
//Either party can change.
|
||||
//Should double-check the total funding later
|
||||
MinTotalFundingAmount btcutil.Amount
|
||||
|
||||
//CLTV lock-time to use
|
||||
@@ -28,11 +39,12 @@ type CreateChannel struct {
|
||||
//2: channel responder
|
||||
FeePayer uint8
|
||||
|
||||
OurRevocationHash [20]byte
|
||||
TheirRevocationHash [20]byte
|
||||
OurPubkey *btcec.PublicKey
|
||||
TheirPubkey *btcec.PublicKey
|
||||
DeliveryPkScript PkScript //*MUST* be either P2PKH or P2SH
|
||||
OurRevocationHash [20]byte
|
||||
TheirRevocationHash [20]byte
|
||||
OurPubkey *btcec.PublicKey
|
||||
TheirPubkey *btcec.PublicKey
|
||||
OurDeliveryPkScript PkScript //*MUST* be either P2PKH or P2SH
|
||||
TheirDeliveryPkScript PkScript //*MUST* be either P2PKH or P2SH
|
||||
|
||||
OurInputs []*wire.TxIn
|
||||
TheirInputs []*wire.TxIn
|
||||
@@ -42,7 +54,7 @@ type CreateChannel struct {
|
||||
//Unified function to call when writing different types
|
||||
//Pre-allocate a byte-array of the correct size for cargo-cult security
|
||||
//More copies but whatever...
|
||||
func writeElement(w io.Writer, element interface{}) error {
|
||||
func writeElement(w *bytes.Buffer, element interface{}) error {
|
||||
var err error
|
||||
switch e := element.(type) {
|
||||
case uint8:
|
||||
@@ -136,6 +148,11 @@ func writeElement(w io.Writer, element interface{}) error {
|
||||
func readElement(r io.Reader, element interface{}) error {
|
||||
var err error
|
||||
switch e := element.(type) {
|
||||
case *uint8:
|
||||
err = binary.Read(r, binary.BigEndian, *e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *uint32:
|
||||
var b [4]byte
|
||||
_, err = io.ReadFull(r, b[:])
|
||||
@@ -143,6 +160,173 @@ func readElement(r io.Reader, element interface{}) error {
|
||||
return err
|
||||
}
|
||||
*e = binary.BigEndian.Uint32(b[:])
|
||||
case *btcutil.Amount:
|
||||
var b [8]byte
|
||||
_, err = io.ReadFull(r, b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = btcutil.Amount(binary.BigEndian.Uint64(b[:]))
|
||||
case *btcec.PublicKey:
|
||||
var b [33]byte
|
||||
_, err = io.ReadFull(r, b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e, err = btcec.ParsePubKey(b[:], btcec.S256())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *[20]byte:
|
||||
_, err = io.ReadFull(r, e[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *PkScript:
|
||||
//Get the script length first
|
||||
var scriptLength uint8
|
||||
err = binary.Read(r, binary.BigEndian, scriptLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if scriptLength > 25 {
|
||||
return fmt.Errorf("PkScript too long!")
|
||||
}
|
||||
|
||||
//Read the script length
|
||||
l := io.LimitReader(r, int64(scriptLength))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.Read(*e)
|
||||
case []*wire.TxIn:
|
||||
//Read the size (1-byte number of txins)
|
||||
var numScripts uint8
|
||||
err = binary.Read(r, binary.BigEndian, numScripts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if numScripts > 127 {
|
||||
return fmt.Errorf("Too many txins")
|
||||
}
|
||||
|
||||
//Append the actual TxIns
|
||||
var txins []*wire.TxIn
|
||||
for i := uint8(0); i < numScripts; i++ {
|
||||
//Hash
|
||||
var h [32]byte
|
||||
_, err = io.ReadFull(r, h[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
shaHash, err := wire.NewShaHash(h[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Index
|
||||
var idxBytes [4]byte
|
||||
_, err = io.ReadFull(r, idxBytes[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
index := binary.BigEndian.Uint32(idxBytes[:])
|
||||
outPoint := wire.NewOutPoint(shaHash, index)
|
||||
|
||||
//Create TxIn
|
||||
txins = append(txins, wire.NewTxIn(outPoint, nil))
|
||||
}
|
||||
e = txins
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Unknown type in readElement: %T", e)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CreateChannel) DeserializeFundingRequest(r io.Reader) error {
|
||||
var err error
|
||||
|
||||
//Message Type
|
||||
var messageType uint8
|
||||
err = readElement(r, messageType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if messageType != 0x30 {
|
||||
return fmt.Errorf("Message type does not match FundingRequest")
|
||||
}
|
||||
|
||||
//Channel Type
|
||||
err = readElement(r, c.ChannelType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Their Funding Amount
|
||||
err = readElement(r, c.TheirFundingAmount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Their Channel Minimum Capacity
|
||||
var theirMinimumFunding btcutil.Amount
|
||||
err = readElement(r, theirMinimumFunding)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Replace with their minimum if it's greater than ours
|
||||
//We still need to locally validate that info
|
||||
if theirMinimumFunding > c.MinTotalFundingAmount {
|
||||
c.MinTotalFundingAmount = theirMinimumFunding
|
||||
}
|
||||
|
||||
//Their Revocation Hash
|
||||
err = readElement(r, c.TheirRevocationHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Their Commitment Pubkey
|
||||
err = readElement(r, c.TheirPubkey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Their Reserve Amount
|
||||
err = readElement(r, c.TheirReserveAmount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Minimum Transaction Fee Per Kb
|
||||
err = readElement(r, c.TheirMinFeePerKb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//LockTime
|
||||
err = readElement(r, c.LockTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//FeePayer
|
||||
err = readElement(r, c.FeePayer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Their Delivery PkScript
|
||||
err = readElement(r, c.TheirDeliveryPkScript)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Create the TxIns
|
||||
err = readElement(r, c.TheirInputs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -150,11 +334,11 @@ func readElement(r io.Reader, element interface{}) error {
|
||||
|
||||
//Serializes the fundingRequest from the CreateChannel struct
|
||||
//Writes the data to w
|
||||
func (c *CreateChannel) SerializeFundingRequest(w io.Writer) error {
|
||||
func (c *CreateChannel) SerializeFundingRequest(w *bytes.Buffer) error {
|
||||
var err error
|
||||
|
||||
//Fund request byte
|
||||
err = binary.Write(w, binary.BigEndian, uint8(0x30))
|
||||
err = writeElement(w, uint8(0x30))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -190,12 +374,6 @@ func (c *CreateChannel) SerializeFundingRequest(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
//Our Delivery PkHash
|
||||
err = writeElement(w, c.OurRevocationHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Our Reserve Amount
|
||||
err = writeElement(w, c.OurReserveAmount)
|
||||
if err != nil {
|
||||
@@ -203,7 +381,7 @@ func (c *CreateChannel) SerializeFundingRequest(w io.Writer) error {
|
||||
}
|
||||
|
||||
//Minimum Transaction Fee Per KB
|
||||
err = writeElement(w, c.MinFeePerKb)
|
||||
err = writeElement(w, c.OurMinFeePerKb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -220,13 +398,16 @@ func (c *CreateChannel) SerializeFundingRequest(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
//Delivery PkScript
|
||||
err = writeElement(w, c.DeliveryPkScript)
|
||||
//Our Delivery PkScript
|
||||
//First byte length then pkscript
|
||||
err = writeElement(w, c.OurDeliveryPkScript)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Append the actual Txins
|
||||
//First byte is number of inputs
|
||||
//For each input, it's 32bytes txin & 4bytes index
|
||||
err = writeElement(w, c.OurInputs)
|
||||
if err != nil {
|
||||
return err
|
||||
|
Reference in New Issue
Block a user