Refactor funding request, will separate to multiple files later
This commit is contained in:
parent
a4762b818f
commit
fc9ebb52f3
236
lnwire/lnwire.go
Normal file
236
lnwire/lnwire.go
Normal file
@ -0,0 +1,236 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"io"
|
||||
)
|
||||
|
||||
//Actual pkScript, not redeemScript
|
||||
type PkScript []byte
|
||||
|
||||
type CreateChannel struct {
|
||||
ChannelType uint8
|
||||
OurFundingAmount btcutil.Amount
|
||||
OurReserveAmount btcutil.Amount
|
||||
MinFeePerKb btcutil.Amount //higher of both parties
|
||||
MinTotalFundingAmount btcutil.Amount
|
||||
|
||||
//CLTV lock-time to use
|
||||
LockTime uint32
|
||||
|
||||
//Who pays the fees
|
||||
//0: (default) channel initiator
|
||||
//1: split
|
||||
//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
|
||||
|
||||
OurInputs []*wire.TxIn
|
||||
TheirInputs []*wire.TxIn
|
||||
}
|
||||
|
||||
//Writes the big endian representation of element
|
||||
//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 {
|
||||
var err error
|
||||
switch e := element.(type) {
|
||||
case uint8:
|
||||
var b [1]byte
|
||||
b[0] = byte(e)
|
||||
_, err = w.Write(b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case uint32:
|
||||
var b [4]byte
|
||||
binary.BigEndian.PutUint32(b[:], uint32(e))
|
||||
_, err = w.Write(b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case btcutil.Amount:
|
||||
var b [8]byte
|
||||
binary.BigEndian.PutUint64(b[:], uint64(e))
|
||||
_, err = w.Write(b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *btcec.PublicKey:
|
||||
var b [33]byte
|
||||
serializedPubkey := e.SerializeCompressed()
|
||||
if len(serializedPubkey) != 33 {
|
||||
return fmt.Errorf("Wrong size pubkey")
|
||||
}
|
||||
copy(b[:], serializedPubkey)
|
||||
_, err = w.Write(b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case [20]byte:
|
||||
_, err = w.Write(e[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case PkScript:
|
||||
scriptLength := len(e)
|
||||
//Make sure it's P2PKH or P2SH size or less
|
||||
if scriptLength > 25 {
|
||||
return fmt.Errorf("PkScript too long!")
|
||||
}
|
||||
//Write the size (1-byte)
|
||||
err = binary.Write(w, binary.BigEndian, uint8(scriptLength))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Write the data
|
||||
_, err = w.Write(e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case []*wire.TxIn:
|
||||
//Append the unsigned(!!!) txins
|
||||
//Write the size (1-byte)
|
||||
if len(e) > 127 {
|
||||
return fmt.Errorf("Too many txins")
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, uint8(len(e)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Append the actual TxIns (Size: NumOfTxins * 36)
|
||||
//Do not include the sequence number to eliminate funny business
|
||||
for _, in := range e {
|
||||
//Hash
|
||||
var h [32]byte
|
||||
copy(h[:], in.PreviousOutPoint.Hash.Bytes())
|
||||
_, err = w.Write(h[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Index
|
||||
var idx [4]byte
|
||||
binary.BigEndian.PutUint32(idx[:], in.PreviousOutPoint.Index)
|
||||
_, err = w.Write(idx[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Unknown type in writeElement: %T", e)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readElement(r io.Reader, element interface{}) error {
|
||||
var err error
|
||||
switch e := element.(type) {
|
||||
case *uint32:
|
||||
var b [4]byte
|
||||
_, err = io.ReadFull(r, b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = binary.BigEndian.Uint32(b[:])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//Serializes the fundingRequest from the CreateChannel struct
|
||||
//Writes the data to w
|
||||
func (c *CreateChannel) SerializeFundingRequest(w io.Writer) error {
|
||||
var err error
|
||||
|
||||
//Fund request byte
|
||||
err = binary.Write(w, binary.BigEndian, uint8(0x30))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Channel Type
|
||||
//default to 0 for CLTV-only
|
||||
err = writeElement(w, c.ChannelType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Our Funding Amont
|
||||
err = writeElement(w, c.OurFundingAmount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Our Channel Minimum Capacity
|
||||
err = writeElement(w, c.MinTotalFundingAmount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Our Revocation Hash
|
||||
err = writeElement(w, c.OurRevocationHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Our Commitment Pubkey
|
||||
err = writeElement(w, c.OurPubkey)
|
||||
if err != nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
//Minimum Transaction Fee Per KB
|
||||
err = writeElement(w, c.MinFeePerKb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//LockTime
|
||||
err = writeElement(w, c.LockTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//FeePayer
|
||||
err = writeElement(w, c.FeePayer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Delivery PkScript
|
||||
err = writeElement(w, c.DeliveryPkScript)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Append the actual Txins
|
||||
err = writeElement(w, c.OurInputs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user