Messages for funding flow.
This is the most different due to segwit (the rest of the messages are simple). I still need to simplify/refactor the tests, they're "messy".
This commit is contained in:
1 parent
a5f0d3e56e
commit
a93b6dcee4
12 files changed
+986
-71
No files matched your search
+154
-12
@@ -1,6 +1,7 @@
|
||||
package lnwire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
@@ -39,6 +40,14 @@ func writeElement(w io.Writer, includeSig bool, element interface{}) error {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case uint64:
|
||||
var b [8]byte
|
||||
binary.BigEndian.PutUint64(b[:], uint64(e))
|
||||
_, err = w.Write(b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case btcutil.Amount:
|
||||
err = binary.Write(w, binary.BigEndian, int64(e))
|
||||
if err != nil {
|
||||
@@ -57,6 +66,47 @@ func writeElement(w io.Writer, includeSig bool, element interface{}) error {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case *[]btcec.Signature:
|
||||
numSigs := len(*e)
|
||||
if numSigs > 127 {
|
||||
return fmt.Errorf("Too many signatures!")
|
||||
}
|
||||
//Write the size
|
||||
err = writeElement(w, false, uint8(numSigs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Write the data
|
||||
for i := 0; i < numSigs; i++ {
|
||||
err = writeElement(w, false, &(*e)[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case *btcec.Signature:
|
||||
sig := e.Serialize()
|
||||
sigLength := len(sig)
|
||||
if sigLength > 73 {
|
||||
return fmt.Errorf("Signature too long!")
|
||||
}
|
||||
//Write the size
|
||||
err = writeElement(w, false, uint8(sigLength))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Write the data
|
||||
_, err = w.Write(sig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case *wire.ShaHash:
|
||||
_, err = w.Write(e[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case [20]byte:
|
||||
_, err = w.Write(e[:])
|
||||
if err != nil {
|
||||
@@ -78,7 +128,7 @@ func writeElement(w io.Writer, includeSig bool, element interface{}) error {
|
||||
return fmt.Errorf("PkScript too long!")
|
||||
}
|
||||
//Write the size (1-byte)
|
||||
err = binary.Write(w, binary.BigEndian, uint8(scriptLength))
|
||||
err = writeElement(w, false, uint8(scriptLength))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -94,7 +144,7 @@ func writeElement(w io.Writer, includeSig bool, element interface{}) error {
|
||||
if len(e) > 127 {
|
||||
return fmt.Errorf("Too many txins")
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, uint8(len(e)))
|
||||
err = writeElement(w, false, uint8(len(e)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -163,6 +213,14 @@ func readElement(r io.Reader, includeSig bool, element interface{}) error {
|
||||
}
|
||||
*e = binary.BigEndian.Uint32(b[:])
|
||||
return nil
|
||||
case *uint64:
|
||||
var b [8]byte
|
||||
_, err = io.ReadFull(r, b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = binary.BigEndian.Uint64(b[:])
|
||||
return nil
|
||||
case *btcutil.Amount:
|
||||
var b [8]byte
|
||||
_, err = io.ReadFull(r, b[:])
|
||||
@@ -171,6 +229,14 @@ func readElement(r io.Reader, includeSig bool, element interface{}) error {
|
||||
}
|
||||
*e = btcutil.Amount(int64(binary.BigEndian.Uint64(b[:])))
|
||||
return nil
|
||||
case **wire.ShaHash:
|
||||
var b wire.ShaHash
|
||||
_, err = io.ReadFull(r, b[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = &b
|
||||
return nil
|
||||
case **btcec.PublicKey:
|
||||
var b [33]byte
|
||||
_, err = io.ReadFull(r, b[:])
|
||||
@@ -178,10 +244,55 @@ func readElement(r io.Reader, includeSig bool, element interface{}) error {
|
||||
return err
|
||||
}
|
||||
x, err := btcec.ParsePubKey(b[:], btcec.S256())
|
||||
*e = &*x
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = &*x
|
||||
return nil
|
||||
case **[]btcec.Signature:
|
||||
var numSigs uint8
|
||||
err = readElement(r, false, &numSigs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if numSigs > 127 {
|
||||
return fmt.Errorf("Too many signatures!")
|
||||
}
|
||||
|
||||
//Read that number of signatures
|
||||
var sigs []btcec.Signature
|
||||
for i := uint8(0); i < numSigs; i++ {
|
||||
sig := new(btcec.Signature)
|
||||
readElement(r, false, &sig)
|
||||
sigs = append(sigs, *sig)
|
||||
}
|
||||
*e = &sigs
|
||||
return nil
|
||||
case **btcec.Signature:
|
||||
var sigLength uint8
|
||||
err = readElement(r, false, &sigLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sigLength > 73 {
|
||||
return fmt.Errorf("Signature too long!")
|
||||
}
|
||||
|
||||
//Read the sig length
|
||||
l := io.LimitReader(r, int64(sigLength))
|
||||
sig, err := ioutil.ReadAll(l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(sig) != int(sigLength) {
|
||||
return fmt.Errorf("EOF: Signature length mismatch.")
|
||||
}
|
||||
btcecSig, err := btcec.ParseSignature(sig, btcec.S256())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*e = &*btcecSig
|
||||
return nil
|
||||
case *[20]byte:
|
||||
_, err = io.ReadFull(r, e[:])
|
||||
@@ -199,37 +310,40 @@ func readElement(r io.Reader, includeSig bool, element interface{}) error {
|
||||
return nil
|
||||
case *PkScript:
|
||||
//Get the script length first
|
||||
var scriptLength [1]uint8
|
||||
_, err = r.Read(scriptLength[:])
|
||||
var scriptLength uint8
|
||||
err = readElement(r, false, &scriptLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if scriptLength[0] > 25 {
|
||||
if scriptLength > 25 {
|
||||
return fmt.Errorf("PkScript too long!")
|
||||
}
|
||||
|
||||
//Read the script length
|
||||
l := io.LimitReader(r, int64(scriptLength[0]))
|
||||
*e, _ = ioutil.ReadAll(l)
|
||||
l := io.LimitReader(r, int64(scriptLength))
|
||||
*e, err = ioutil.ReadAll(l)
|
||||
if len(*e) != int(scriptLength) {
|
||||
return fmt.Errorf("EOF: Signature length mismatch.")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case *[]*wire.TxIn:
|
||||
//Read the size (1-byte number of txins)
|
||||
var numScripts [1]uint8
|
||||
_, err = r.Read(numScripts[:])
|
||||
var numScripts uint8
|
||||
err = readElement(r, false, &numScripts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if numScripts[0] > 127 {
|
||||
if numScripts > 127 {
|
||||
return fmt.Errorf("Too many txins")
|
||||
}
|
||||
|
||||
//Append the actual TxIns
|
||||
var txins []*wire.TxIn
|
||||
for i := uint8(0); i < numScripts[0]; i++ {
|
||||
for i := uint8(0); i < numScripts; i++ {
|
||||
//Hash
|
||||
var h [32]byte
|
||||
_, err = io.ReadFull(r, h[:])
|
||||
@@ -281,3 +395,31 @@ func readElements(r io.Reader, includeSig bool, elements ...interface{}) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//Validates whether a PkScript byte array is P2SH or P2PKH
|
||||
func ValidatePkScript(pkScript PkScript) error {
|
||||
if len(pkScript) == 25 {
|
||||
//P2PKH
|
||||
//Begins with OP_DUP OP_HASH160 PUSHDATA(20)
|
||||
if !bytes.Equal(pkScript[0:3], []byte{118, 169, 20}) ||
|
||||
//Ends with OP_EQUALVERIFY OP_CHECKSIG
|
||||
!bytes.Equal(pkScript[23:25], []byte{136, 172}) {
|
||||
//If it's not correct, return error
|
||||
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
|
||||
}
|
||||
} else if len(pkScript) == 23 {
|
||||
//P2SH
|
||||
//Begins with OP_HASH160 PUSHDATA(20)
|
||||
if !bytes.Equal(pkScript[0:2], []byte{169, 20}) ||
|
||||
//Ends with OP_EQUAL
|
||||
!bytes.Equal(pkScript[22:23], []byte{135}) {
|
||||
//If it's not correct, return error
|
||||
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
|
||||
}
|
||||
} else {
|
||||
//Length not 23 or 25
|
||||
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user