FundReq/FundResp update / Refactor tests

* Added field
* Renamed FundingAmount and ReserveAmount to specify in FundingRequest
  and FundingResponse that it is for RequesterFundingAmount or
  ResponderFundingAmount
* Added PaymentAmount field to FundingRequest
* Added MinDepth field to FundingRequest and FundingResponse
* Fixed .Serialize() to show inputs/etc. only if there are fields
  available (prevents trying to dereference nil value)
* Add a bunch of Validate() conditions
* MASSIVE REFACTOR of tests (removed tons of redundancy)
This commit is contained in:
Joseph Poon 2015-12-30 22:28:14 -08:00 committed by Olaoluwa Osuntokun
parent cb32ab1fb9
commit 0d4c78e90d
10 changed files with 417 additions and 524 deletions

View File

@ -39,3 +39,24 @@ Funding Transaction. This is provided as a courtesy, it cannot be relied upon
with non-cooperative channel counterparties and the Funding Transaction can be
braodcast without this message being received by the requester. After the
necessary number of confirmations, Lightning Network transactions can proceed.
Cooperative Channel Close
=========================
This is when either party want to close out a channel with the current balance.
Requires the cooperation of both parites for this type. In the event of
non-cooperation, either party may broadcast the most recent Commitment
Transaction.
Close Channel
-------------
One party unilaterally sends their sig to the other party. No further channel
updates are possible. In the future, we might include HTLCs in the outputs, but
for now, we're assuming *all* HTLCs are cleared out.
Close Channel Complete
----------------------
Returns the Txid as a courtesy. The counterparty may not send this if they're
being non-cooperative.

View File

@ -11,9 +11,19 @@ import (
type FundingRequest struct {
ChannelType uint8
FundingAmount btcutil.Amount
ReserveAmount btcutil.Amount
MinFeePerKb btcutil.Amount
RequesterFundingAmount btcutil.Amount
RequesterReserveAmount btcutil.Amount
MinFeePerKb btcutil.Amount
//The funding requester can request payment
//This wallet only allows positive values,
//which is a payment to the responder
//(This can be used to fund the Reserve)
//If the responder disagrees, then the funding request fails
PaymentAmount btcutil.Amount
//Minimum number of confirmations to validate transaction
MinDepth uint32
//Should double-check the total funding later
MinTotalFundingAmount btcutil.Amount
@ -36,15 +46,17 @@ type FundingRequest struct {
}
func (c *FundingRequest) Decode(r io.Reader, pver uint32) error {
//Channel Type (0/1)
//Funding Amount (1/8)
//Channel Minimum Capacity (9/8)
//Revocation Hash (17/20)
//Commitment Pubkey (37/32)
//Reserve Amount (69/8)
//Minimum Transaction Fee Per Kb (77/8)
//LockTime (85/4)
//FeePayer (89/1)
//Channel Type (1)
//Funding Amount (8)
//Channel Minimum Capacity (8)
//Revocation Hash (20)
//Commitment Pubkey (32)
//Reserve Amount (8)
//Minimum Transaction Fee Per Kb (8)
//PaymentAmount (8)
//MinDepth (4)
//LockTime (4)
//FeePayer (1)
//DeliveryPkScript (final delivery)
// First byte length then pkscript
//ChangePkScript (change for extra from inputs)
@ -54,12 +66,14 @@ func (c *FundingRequest) Decode(r io.Reader, pver uint32) error {
// For each input, it's 32bytes txin & 4bytes index
err := readElements(r, false,
&c.ChannelType,
&c.FundingAmount,
&c.RequesterFundingAmount,
&c.MinTotalFundingAmount,
&c.RevocationHash,
&c.Pubkey,
&c.ReserveAmount,
&c.RequesterReserveAmount,
&c.MinFeePerKb,
&c.PaymentAmount,
&c.MinDepth,
&c.LockTime,
&c.FeePayer,
&c.DeliveryPkScript,
@ -94,12 +108,14 @@ func (c *FundingRequest) Encode(w io.Writer, pver uint32) error {
//Inputs: Append the actual Txins
err := writeElements(w, false,
c.ChannelType,
c.FundingAmount,
c.RequesterFundingAmount,
c.MinTotalFundingAmount,
c.RevocationHash,
c.Pubkey,
c.ReserveAmount,
c.RequesterReserveAmount,
c.MinFeePerKb,
c.PaymentAmount,
c.MinDepth,
c.LockTime,
c.FeePayer,
c.DeliveryPkScript,
@ -117,8 +133,8 @@ func (c *FundingRequest) Command() uint32 {
}
func (c *FundingRequest) MaxPayloadLength(uint32) uint32 {
//90 (base size) + 26 (pkscript) + 26 (pkscript) + 1 (numTxes) + 127*36(127 inputs * sha256+idx)
return 4715
//102 (base size) + 26 (pkscript) + 26 (pkscript) + 1 (numTxes) + 127*36(127 inputs * sha256+idx)
return 4727
}
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
@ -126,12 +142,12 @@ func (c *FundingRequest) Validate() error {
var err error
//No negative values
if c.FundingAmount < 0 {
return fmt.Errorf("FundingAmount cannot be negative")
if c.RequesterFundingAmount < 0 {
return fmt.Errorf("RequesterFundingAmount cannot be negative")
}
if c.ReserveAmount < 0 {
return fmt.Errorf("ReserveAmount cannot be negative")
if c.RequesterReserveAmount < 0 {
return fmt.Errorf("RequesterReserveAmount cannot be negative")
}
if c.MinFeePerKb < 0 {
@ -141,6 +157,28 @@ func (c *FundingRequest) Validate() error {
return fmt.Errorf("MinTotalFundingAmount cannot be negative")
}
//Validation of what makes sense...
if c.MinTotalFundingAmount < c.RequesterFundingAmount {
return fmt.Errorf("Requester's minimum too low.")
}
if c.RequesterFundingAmount < c.RequesterReserveAmount {
return fmt.Errorf("Reserve must be below Funding Amount")
}
//This wallet only allows payment from the requester to responder
if c.PaymentAmount < 0 {
return fmt.Errorf("This wallet requieres payment to be greater than zero.")
}
//The payment must be below our own contribution (less reserve kept for ourselves
if c.PaymentAmount > c.RequesterFundingAmount-c.RequesterReserveAmount {
return fmt.Errorf("Payment too large")
}
//Make sure there's not more than 127 inputs
if len(c.Inputs) > 127 {
return fmt.Errorf("Too many inputs")
}
//DeliveryPkScript is either P2SH or P2PKH
err = ValidatePkScript(c.DeliveryPkScript)
if err != nil {
@ -161,20 +199,24 @@ func (c *FundingRequest) String() string {
var inputs string
for i, in := range c.Inputs {
inputs += fmt.Sprintf("\n Slice\t%d\n", i)
inputs += fmt.Sprintf("\tHash\t%s\n", in.PreviousOutPoint.Hash)
inputs += fmt.Sprintf("\tIndex\t%d\n", in.PreviousOutPoint.Index)
if &in != nil {
inputs += fmt.Sprintf("\tHash\t%s\n", in.PreviousOutPoint.Hash)
inputs += fmt.Sprintf("\tIndex\t%d\n", in.PreviousOutPoint.Index)
}
}
return fmt.Sprintf("\n--- Begin FundingRequest ---\n") +
fmt.Sprintf("ChannelType:\t\t%x\n", c.ChannelType) +
fmt.Sprintf("FundingAmount:\t\t%s\n", c.FundingAmount.String()) +
fmt.Sprintf("ReserveAmount:\t\t%s\n", c.ReserveAmount.String()) +
fmt.Sprintf("MinFeePerKb:\t\t%s\n", c.MinFeePerKb.String()) +
fmt.Sprintf("MinTotalFundingAmount\t%s\n", c.MinTotalFundingAmount.String()) +
fmt.Sprintf("LockTime\t\t%d\n", c.LockTime) +
fmt.Sprintf("FeePayer\t\t%x\n", c.FeePayer) +
fmt.Sprintf("RevocationHash\t\t%x\n", c.RevocationHash) +
fmt.Sprintf("Pubkey\t\t\t%x\n", c.Pubkey.SerializeCompressed()) +
fmt.Sprintf("DeliveryPkScript\t%x\n", c.DeliveryPkScript) +
fmt.Sprintf("ChannelType:\t\t\t%x\n", c.ChannelType) +
fmt.Sprintf("RequesterFundingAmount:\t\t%s\n", c.RequesterFundingAmount.String()) +
fmt.Sprintf("RequesterReserveAmount:\t\t%s\n", c.RequesterReserveAmount.String()) +
fmt.Sprintf("MinFeePerKb:\t\t\t%s\n", c.MinFeePerKb.String()) +
fmt.Sprintf("PaymentAmount:\t\t\t%s\n", c.PaymentAmount.String()) +
fmt.Sprintf("MinDepth:\t\t\t%d\n", c.MinDepth) +
fmt.Sprintf("MinTotalFundingAmount\t\t%s\n", c.MinTotalFundingAmount.String()) +
fmt.Sprintf("LockTime\t\t\t%d\n", c.LockTime) +
fmt.Sprintf("FeePayer\t\t\t%x\n", c.FeePayer) +
fmt.Sprintf("RevocationHash\t\t\t%x\n", c.RevocationHash) +
fmt.Sprintf("Pubkey\t\t\t\t%x\n", c.Pubkey.SerializeCompressed()) +
fmt.Sprintf("DeliveryPkScript\t\t%x\n", c.DeliveryPkScript) +
fmt.Sprintf("Inputs:") +
inputs +
fmt.Sprintf("--- End FundingRequest ---\n")

View File

@ -1,135 +1,49 @@
package lnwire
import (
"bytes"
"encoding/hex"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
// "io"
"io/ioutil"
"reflect"
"testing"
)
var (
//For debugging, writes to /dev/shm/
//Maybe in the future do it if you do "go test -v"
WRITE_FILE = false
FILENAME = "/dev/shm/fundingRequest.raw"
//preimage: 9a2cbd088763db88dd8ba79e5726daa6aba4aa7e
//echo -n | openssl sha256 | openssl ripemd160 | openssl sha256 | openssl ripemd160
revocationHashBytes, _ = hex.DecodeString("4132b6b48371f7b022a16eacb9b2b0ebee134d41")
revocationHash [20]byte
_ = copy(revocationHash[:], revocationHashBytes)
//privkey: 9fa1d55217f57019a3c37f49465896b15836f54cb8ef6963870a52926420a2dd
pubKeyBytes, _ = hex.DecodeString("02f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee")
pubKey, _ = btcec.ParsePubKey(pubKeyBytes, btcec.S256())
// Delivery PkScript
//Privkey: f2c00ead9cbcfec63098dc0a5f152c0165aff40a2ab92feb4e24869a284c32a7
//PKhash: n2fkWVphUzw3zSigzPsv9GuDyg9mohzKpz
deliveryPkScript, _ = hex.DecodeString("76a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac")
// Change PkScript
//Privkey: 5b18f5049efd9d3aff1fb9a06506c0b809fb71562b6ecd02f6c5b3ab298f3b0f
//PKhash: miky84cHvLuk6jcT6GsSbgHR8d7eZCu9Qc
changePkScript, _ = hex.DecodeString("76a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac")
//echo -n | openssl sha256
//This stuff gets reversed!!!
shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
shaHash1, _ = wire.NewShaHash(shaHash1Bytes)
outpoint1 = wire.NewOutPoint(shaHash1, 0)
//echo | openssl sha256
//This stuff gets reversed!!!
shaHash2Bytes, _ = hex.DecodeString("01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b")
shaHash2, _ = wire.NewShaHash(shaHash2Bytes)
outpoint2 = wire.NewOutPoint(shaHash2, 1)
//create inputs from outpoint1 and outpoint2
inputs = []*wire.TxIn{wire.NewTxIn(outpoint1, nil), wire.NewTxIn(outpoint2, nil)}
//Need to do this here
_ = copy(revocationHash[:], revocationHashBytes)
//funding request
fundingRequest = &FundingRequest{
ChannelType: uint8(0),
FundingAmount: btcutil.Amount(100000000),
ReserveAmount: btcutil.Amount(131072),
MinFeePerKb: btcutil.Amount(20000),
MinTotalFundingAmount: btcutil.Amount(150000000),
LockTime: uint32(4320), //30 block-days
FeePayer: uint8(0),
RevocationHash: revocationHash,
Pubkey: pubKey,
DeliveryPkScript: deliveryPkScript,
ChangePkScript: changePkScript,
Inputs: inputs,
ChannelType: uint8(0),
RequesterFundingAmount: btcutil.Amount(100000000),
RequesterReserveAmount: btcutil.Amount(131072),
MinFeePerKb: btcutil.Amount(20000),
MinTotalFundingAmount: btcutil.Amount(150000000),
LockTime: uint32(4320), //30 block-days
FeePayer: uint8(0),
PaymentAmount: btcutil.Amount(1234567),
MinDepth: uint32(6),
RevocationHash: revocationHash,
Pubkey: pubKey,
DeliveryPkScript: deliveryPkScript,
ChangePkScript: changePkScript,
Inputs: inputs,
}
serializedString = "000000000005f5e1000000000008f0d1804132b6b48371f7b022a16eacb9b2b0ebee134d4102f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee00000000000200000000000000004e20000010e0001976a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac1976a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac02e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550000000001ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b00000001"
serializedMessage = "0709110b000000c8000000d8000000000005f5e1000000000008f0d1804132b6b48371f7b022a16eacb9b2b0ebee134d4102f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee00000000000200000000000000004e20000010e0001976a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac1976a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac02e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550000000001ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b00000001"
fundingRequestSerializedString = "000000000005f5e1000000000008f0d1804132b6b48371f7b022a16eacb9b2b0ebee134d4102f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee00000000000200000000000000004e20000000000012d68700000006000010e0001976a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac1976a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac02e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550000000001ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b00000001"
fundingRequestSerializedMessage = "0709110b000000c8000000e4000000000005f5e1000000000008f0d1804132b6b48371f7b022a16eacb9b2b0ebee134d4102f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee00000000000200000000000000004e20000000000012d68700000006000010e0001976a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac1976a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac02e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550000000001ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b00000001"
)
func TestFundingRequestEncodeDecode(t *testing.T) {
//Test serialization
b := new(bytes.Buffer)
err := fundingRequest.Encode(b, 0)
if err != nil {
t.Error("Serialization error")
t.Error(err.Error())
} else {
t.Logf("Encoded Funding Request: %x\n", b.Bytes())
//Check if we serialized correctly
if serializedString != hex.EncodeToString(b.Bytes()) {
t.Error("Serialization does not match expected")
}
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
s := SerializeTest(t, fundingRequest, fundingRequestSerializedString, filename)
//So I can do: hexdump -C /dev/shm/fundingRequest.raw
if WRITE_FILE {
err = ioutil.WriteFile(FILENAME, b.Bytes(), 0644)
if err != nil {
t.Error("File write error")
t.Error(err.Error())
}
}
}
//Test deserialization
//Make a new buffer just to be clean
c := new(bytes.Buffer)
c.Write(b.Bytes())
newFunding := NewFundingRequest()
err = newFunding.Decode(c, 0)
if err != nil {
t.Error("Decoding Error")
t.Error(err.Error())
} else {
if !reflect.DeepEqual(newFunding, fundingRequest) {
t.Error("Decoding does not match!")
}
//Show the struct
t.Log(newFunding.String())
}
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
newMessage := NewFundingRequest()
DeserializeTest(t, s, newMessage, fundingRequest)
//Test message using Message interface
//Serialize/Encode
b = new(bytes.Buffer)
_, err = WriteMessage(b, fundingRequest, uint32(1), wire.TestNet3)
t.Logf("%x\n", b.Bytes())
if hex.EncodeToString(b.Bytes()) != serializedMessage {
t.Error("Message encoding error")
}
//Deserialize/Decode
c = new(bytes.Buffer)
c.Write(b.Bytes())
_, msg, _, err := ReadMessage(c, uint32(1), wire.TestNet3)
if err != nil {
t.Errorf(err.Error())
} else {
if !reflect.DeepEqual(msg, fundingRequest) {
t.Error("Message decoding does not match!")
}
t.Logf(msg.String())
}
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, fundingRequest, fundingRequestSerializedMessage)
}

View File

@ -13,9 +13,12 @@ type FundingResponse struct {
ReservationID uint64
FundingAmount btcutil.Amount
ReserveAmount btcutil.Amount
MinFeePerKb btcutil.Amount //Lock-in min fee
ResponderFundingAmount btcutil.Amount //Responder's funding amount
ResponderReserveAmount btcutil.Amount //Responder's reserve amount
MinFeePerKb btcutil.Amount //Lock-in min fee
//Minimum depth
MinDepth uint32
//CLTV/CSV lock-time to use
LockTime uint32
@ -36,15 +39,16 @@ type FundingResponse struct {
}
func (c *FundingResponse) Decode(r io.Reader, pver uint32) error {
//ReservationID (0/8)
//Channel Type (8/1)
//Funding Amount (9/8)
//Revocation Hash (29/20)
//Commitment Pubkey (61/32)
//Reserve Amount (69/8)
//Minimum Transaction Fee Per Kb (77/8)
//LockTime (81/4)
//FeePayer (82/1)
//ReservationID (8)
//Channel Type (1)
//Funding Amount (8)
//Revocation Hash (20)
//Commitment Pubkey (32)
//Reserve Amount (8)
//Minimum Transaction Fee Per Kb (8)
//MinDepth (4)
//LockTime (4)
//FeePayer (1)
//DeliveryPkScript (final delivery)
// First byte length then pkscript
//ChangePkScript (change for extra from inputs)
@ -57,11 +61,12 @@ func (c *FundingResponse) Decode(r io.Reader, pver uint32) error {
err := readElements(r, false,
&c.ReservationID,
&c.ChannelType,
&c.FundingAmount,
&c.ResponderFundingAmount,
&c.RevocationHash,
&c.Pubkey,
&c.ReserveAmount,
&c.ResponderReserveAmount,
&c.MinFeePerKb,
&c.MinDepth,
&c.LockTime,
&c.FeePayer,
&c.DeliveryPkScript,
@ -99,11 +104,12 @@ func (c *FundingResponse) Encode(w io.Writer, pver uint32) error {
err := writeElements(w, false,
c.ReservationID,
c.ChannelType,
c.FundingAmount,
c.ResponderFundingAmount,
c.RevocationHash,
c.Pubkey,
c.ReserveAmount,
c.ResponderReserveAmount,
c.MinFeePerKb,
c.MinDepth,
c.LockTime,
c.FeePayer,
c.DeliveryPkScript,
@ -122,8 +128,8 @@ func (c *FundingResponse) Command() uint32 {
}
func (c *FundingResponse) MaxPayloadLength(uint32) uint32 {
//82 (base size) + 26 (pkscript) + 26 (pkscript) + 74sig + 1 (numTxes) + 127*36(127 inputs * sha256+idx)
return 4781
//86 (base size) + 26 (pkscript) + 26 (pkscript) + 74sig + 1 (numTxes) + 127*36(127 inputs * sha256+idx)
return 4785
}
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
@ -131,18 +137,28 @@ func (c *FundingResponse) Validate() error {
var err error
//No negative values
if c.FundingAmount < 0 {
return fmt.Errorf("FundingAmount cannot be negative")
if c.ResponderFundingAmount < 0 {
return fmt.Errorf("ResponderFundingAmount cannot be negative")
}
if c.ReserveAmount < 0 {
return fmt.Errorf("ReserveAmount cannot be negative")
if c.ResponderReserveAmount < 0 {
return fmt.Errorf("ResponderReserveAmount cannot be negative")
}
if c.MinFeePerKb < 0 {
return fmt.Errorf("MinFeePerKb cannot be negative")
}
//Validation of what makes sense...
if c.ResponderFundingAmount < c.ResponderReserveAmount {
return fmt.Errorf("Reserve must be below Funding Amount")
}
//Make sure there's not more than 127 inputs
if len(c.Inputs) > 127 {
return fmt.Errorf("Too many inputs")
}
//Delivery PkScript is either P2SH or P2PKH
err = ValidatePkScript(c.DeliveryPkScript)
if err != nil {
@ -163,22 +179,26 @@ func (c *FundingResponse) String() string {
var inputs string
for i, in := range c.Inputs {
inputs += fmt.Sprintf("\n Slice\t%d\n", i)
inputs += fmt.Sprintf("\tHash\t%s\n", in.PreviousOutPoint.Hash)
inputs += fmt.Sprintf("\tIndex\t%d\n", in.PreviousOutPoint.Index)
if &in != nil {
inputs += fmt.Sprintf("\tHash\t%s\n", in.PreviousOutPoint.Hash)
inputs += fmt.Sprintf("\tIndex\t%d\n", in.PreviousOutPoint.Index)
}
}
return fmt.Sprintf("\n--- Begin FundingResponse ---\n") +
fmt.Sprintf("ChannelType:\t\t%x\n", c.ChannelType) +
fmt.Sprintf("ReservationID:\t\t%d\n", c.ReservationID) +
fmt.Sprintf("FundingAmount:\t\t%s\n", c.FundingAmount.String()) +
fmt.Sprintf("ReserveAmount:\t\t%s\n", c.ReserveAmount.String()) +
fmt.Sprintf("MinFeePerKb:\t\t%s\n", c.MinFeePerKb.String()) +
fmt.Sprintf("LockTime\t\t%d\n", c.LockTime) +
fmt.Sprintf("FeePayer\t\t%x\n", c.FeePayer) +
fmt.Sprintf("RevocationHash\t\t%x\n", c.RevocationHash) +
fmt.Sprintf("Pubkey\t\t\t%x\n", c.Pubkey.SerializeCompressed()) +
fmt.Sprintf("CommitSig\t\t%x\n", c.CommitSig.Serialize()) +
fmt.Sprintf("DeliveryPkScript\t%x\n", c.DeliveryPkScript) +
fmt.Sprintf("ChangePkScript\t%x\n", c.ChangePkScript) +
fmt.Sprintf("ChannelType:\t\t\t%x\n", c.ChannelType) +
fmt.Sprintf("ReservationID:\t\t\t%d\n", c.ReservationID) +
fmt.Sprintf("ResponderFundingAmount:\t\t%s\n", c.ResponderFundingAmount.String()) +
fmt.Sprintf("ResponderReserveAmount:\t\t%s\n", c.ResponderReserveAmount.String()) +
fmt.Sprintf("MinFeePerKb:\t\t\t%s\n", c.MinFeePerKb.String()) +
fmt.Sprintf("MinDepth:\t\t\t%d\n", c.MinDepth) +
fmt.Sprintf("LockTime\t\t\t%d\n", c.LockTime) +
fmt.Sprintf("FeePayer\t\t\t%x\n", c.FeePayer) +
fmt.Sprintf("RevocationHash\t\t\t%x\n", c.RevocationHash) +
fmt.Sprintf("Pubkey\t\t\t\t%x\n", c.Pubkey.SerializeCompressed()) +
fmt.Sprintf("CommitSig\t\t\t%x\n", c.CommitSig.Serialize()) +
fmt.Sprintf("DeliveryPkScript\t\t%x\n", c.DeliveryPkScript) +
fmt.Sprintf("ChangePkScript\t\t%x\n", c.ChangePkScript) +
fmt.Sprintf("Inputs:") +
inputs +
fmt.Sprintf("--- End FundingResponse ---\n")

View File

@ -1,143 +1,49 @@
package lnwire
import (
"bytes"
"encoding/hex"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
// "io"
"io/ioutil"
"reflect"
"testing"
)
var (
//Need to do this here
_ = copy(revocationHash[:], revocationHashBytes)
//funding response
fundingResponse = &FundingResponse{
ChannelType: uint8(1),
ReservationID: uint64(12345678),
ResponderFundingAmount: btcutil.Amount(100000000),
ResponderReserveAmount: btcutil.Amount(131072),
MinFeePerKb: btcutil.Amount(20000),
MinDepth: uint32(6),
LockTime: uint32(4320), //30 block-days
FeePayer: uint8(1),
RevocationHash: revocationHash,
Pubkey: pubKey,
CommitSig: commitSig,
DeliveryPkScript: deliveryPkScript,
ChangePkScript: changePkScript,
Inputs: inputs,
}
fundingResponseSerializedString = "0000000000bc614e010000000005f5e1004132b6b48371f7b022a16eacb9b2b0ebee134d4102f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee00000000000200000000000000004e2000000006000010e0011976a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac1976a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df02e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550000000001ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b00000001"
fundingResponseSerializedMessage = "0709110b000000d2000001230000000000bc614e010000000005f5e1004132b6b48371f7b022a16eacb9b2b0ebee134d4102f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee00000000000200000000000000004e2000000006000010e0011976a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac1976a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df02e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550000000001ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b00000001"
)
func TestFundingResponseEncodeDecode(t *testing.T) {
var (
//For debugging, writes to /dev/shm/
//Maybe in the future do it if you do "go test -v"
WRITE_FILE = false
FILENAME = "/dev/shm/fundingResponse.raw"
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
s := SerializeTest(t, fundingResponse, fundingResponseSerializedString, filename)
//preimage: 9a2cbd088763db88dd8ba79e5726daa6aba4aa7e
//echo -n | openssl sha256 | openssl ripemd160 | openssl sha256 | openssl ripemd160
revocationHashBytes, _ = hex.DecodeString("4132b6b48371f7b022a16eacb9b2b0ebee134d41")
revocationHash [20]byte
_ = copy(revocationHash[:], revocationHashBytes)
privKeyBytes, _ = hex.DecodeString("9fa1d55217f57019a3c37f49465896b15836f54cb8ef6963870a52926420a2dd")
privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
//pubKeyBytes, _ = hex.DecodeString("02f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee")
//pubKey, _ = btcec.ParsePubKey(pubKeyBytes, btcec.S256())
// Delivery PkScript
//Privkey: f2c00ead9cbcfec63098dc0a5f152c0165aff40a2ab92feb4e24869a284c32a7
//PKhash: n2fkWVphUzw3zSigzPsv9GuDyg9mohzKpz
deliveryPkScript, _ = hex.DecodeString("76a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac")
// Change PkScript
//Privkey: 5b18f5049efd9d3aff1fb9a06506c0b809fb71562b6ecd02f6c5b3ab298f3b0f
//PKhash: miky84cHvLuk6jcT6GsSbgHR8d7eZCu9Qc
changePkScript, _ = hex.DecodeString("76a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac")
//echo -n | openssl sha256
//This stuff gets reversed!!!
shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
shaHash1, _ = wire.NewShaHash(shaHash1Bytes)
outpoint1 = wire.NewOutPoint(shaHash1, 0)
//echo | openssl sha256
//This stuff gets reversed!!!
shaHash2Bytes, _ = hex.DecodeString("01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b")
shaHash2, _ = wire.NewShaHash(shaHash2Bytes)
outpoint2 = wire.NewOutPoint(shaHash2, 1)
//create inputs from outpoint1 and outpoint2
inputs = []*wire.TxIn{wire.NewTxIn(outpoint1, nil), wire.NewTxIn(outpoint2, nil)}
//Commitment Signature
tx = wire.NewMsgTx()
emptybytes = new([]byte)
sigStr, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, privKey)
commitSig, _ = btcec.ParseSignature(sigStr, btcec.S256())
//funding response
fundingResponse = &FundingResponse{
ChannelType: uint8(1),
ReservationID: uint64(12345678),
FundingAmount: btcutil.Amount(100000000),
ReserveAmount: btcutil.Amount(131072),
MinFeePerKb: btcutil.Amount(20000),
LockTime: uint32(4320), //30 block-days
FeePayer: uint8(1),
RevocationHash: revocationHash,
Pubkey: pubKey,
CommitSig: commitSig,
DeliveryPkScript: deliveryPkScript,
ChangePkScript: changePkScript,
Inputs: inputs,
}
serializedString = "0000000000bc614e010000000005f5e1004132b6b48371f7b022a16eacb9b2b0ebee134d4102f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee00000000000200000000000000004e20000010e0011976a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac1976a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df02e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550000000001ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b00000001"
serializedMessage = "0709110b000000d20000011f0000000000bc614e010000000005f5e1004132b6b48371f7b022a16eacb9b2b0ebee134d4102f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee00000000000200000000000000004e20000010e0011976a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac1976a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df02e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550000000001ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b00000001"
)
//Test serialization
b := new(bytes.Buffer)
err := fundingResponse.Encode(b, 0)
if err != nil {
t.Error("Serialization error")
t.Error(err.Error())
} else {
t.Logf("Encoded Funding Response: %x\n", b.Bytes())
//Check if we serialized correctly
if serializedString != hex.EncodeToString(b.Bytes()) {
t.Error("Serialization does not match expected")
}
//So I can do: hexdump -C /dev/shm/fundingResponse.raw
if WRITE_FILE {
err = ioutil.WriteFile(FILENAME, b.Bytes(), 0644)
if err != nil {
t.Error("File write error")
t.Error(err.Error())
}
}
}
//Test deserialization
//Make a new buffer just to be clean
c := new(bytes.Buffer)
c.Write(b.Bytes())
newFunding := NewFundingResponse()
err = newFunding.Decode(c, 0)
if err != nil {
t.Error("Decoding Error")
t.Error(err.Error())
} else {
if !reflect.DeepEqual(newFunding, fundingResponse) {
t.Error("Decoding does not match!")
}
//Show the struct
t.Log(newFunding.String())
}
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
newMessage := NewFundingResponse()
DeserializeTest(t, s, newMessage, fundingResponse)
//Test message using Message interface
//Serialize/Encode
b = new(bytes.Buffer)
_, err = WriteMessage(b, fundingResponse, uint32(1), wire.TestNet3)
t.Logf("%x\n", b.Bytes())
if hex.EncodeToString(b.Bytes()) != serializedMessage {
t.Error("Message encoding error")
}
//Deserialize/Decode
c = new(bytes.Buffer)
c.Write(b.Bytes())
_, msg, _, err := ReadMessage(c, uint32(1), wire.TestNet3)
if err != nil {
t.Errorf(err.Error())
} else {
if !reflect.DeepEqual(msg, fundingResponse) {
t.Error("Message decoding does not match!")
}
t.Logf(msg.String())
}
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, fundingResponse, fundingResponseSerializedMessage)
}

View File

@ -73,7 +73,9 @@ func (c *FundingSignAccept) String() string {
var sigs string
for i, in := range *c.FundingTXSigs {
sigs += fmt.Sprintf("\n Slice\t%d\n", i)
sigs += fmt.Sprintf("\tSig\t%x\n", in.Serialize())
if &in != nil {
sigs += fmt.Sprintf("\tSig\t%x\n", in.Serialize())
}
}
return fmt.Sprintf("\n--- Begin FundingSignAccept ---\n") +
fmt.Sprintf("ReservationID:\t\t%d\n", c.ReservationID) +

View File

@ -1,115 +1,34 @@
package lnwire
import (
"bytes"
"encoding/hex"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
// "io"
"io/ioutil"
"reflect"
"testing"
)
var (
//funding sign accept
fundingSignAccept = &FundingSignAccept{
ReservationID: uint64(12345678),
CommitSig: commitSig,
FundingTXSigs: &fundingTXSigs,
}
fundingSignAcceptSerializedString = "0000000000bc614e4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df02473045022100e7946d057c0b4cc4d3ea525ba156b429796858ebc543d75a6c6c2cbca732db6902202fea377c1f9fb98cd103cf5a4fba276a074b378d4227d15f5fa6439f1a6685bb4630440220235ee55fed634080089953048c3e3f7dc3a154fd7ad18f31dc08e05b7864608a02203bdd7d4e4d9a8162d4b511faf161f0bb16c45181187125017cd0c620c53876ca"
fundingSignAcceptSerializedMessage = "0709110b000000dc000000df0000000000bc614e4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df02473045022100e7946d057c0b4cc4d3ea525ba156b429796858ebc543d75a6c6c2cbca732db6902202fea377c1f9fb98cd103cf5a4fba276a074b378d4227d15f5fa6439f1a6685bb4630440220235ee55fed634080089953048c3e3f7dc3a154fd7ad18f31dc08e05b7864608a02203bdd7d4e4d9a8162d4b511faf161f0bb16c45181187125017cd0c620c53876ca"
)
func TestFundingSignAcceptEncodeDecode(t *testing.T) {
var (
//For debugging, writes to /dev/shm/
//Maybe in the future do it if you do "go test -v"
WRITE_FILE = false
FILENAME = "/dev/shm/fundingSignAccept.raw"
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
s := SerializeTest(t, fundingSignAccept, fundingSignAcceptSerializedString, filename)
privKeyBytes, _ = hex.DecodeString("9fa1d55217f57019a3c37f49465896b15836f54cb8ef6963870a52926420a2dd")
privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
//pubKeyBytes, _ = hex.DecodeString("02f977808cb9577897582d7524b562691e180953dd0008eb44e09594c539d6daee")
//pubKey, _ = btcec.ParsePubKey(pubKeyBytes, btcec.S256())
//Commitment Signature
tx = wire.NewMsgTx()
emptybytes = new([]byte)
sigStr, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, privKey)
commitSig, _ = btcec.ParseSignature(sigStr, btcec.S256())
//Funding TX Sig 1
sig1privKeyBytes, _ = hex.DecodeString("927f5827d75dd2addeb532c0fa5ac9277565f981dd6d0d037b422be5f60bdbef")
sig1privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig1privKeyBytes)
sigStr1, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig1privKey)
commitSig1, _ = btcec.ParseSignature(sigStr1, btcec.S256())
//Funding TX Sig 2
sig2privKeyBytes, _ = hex.DecodeString("8a4ad188f6f4000495b765cfb6ffa591133a73019c45428ddd28f53bab551847")
sig2privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig2privKeyBytes)
sigStr2, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig2privKey)
commitSig2, _ = btcec.ParseSignature(sigStr2, btcec.S256())
fundingTXSigs = append(*new([]btcec.Signature), *commitSig1, *commitSig2)
//funding response
fundingSignAccept = &FundingSignAccept{
ReservationID: uint64(12345678),
CommitSig: commitSig,
FundingTXSigs: &fundingTXSigs,
}
serializedString = "0000000000bc614e4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df02473045022100e7946d057c0b4cc4d3ea525ba156b429796858ebc543d75a6c6c2cbca732db6902202fea377c1f9fb98cd103cf5a4fba276a074b378d4227d15f5fa6439f1a6685bb4630440220235ee55fed634080089953048c3e3f7dc3a154fd7ad18f31dc08e05b7864608a02203bdd7d4e4d9a8162d4b511faf161f0bb16c45181187125017cd0c620c53876ca"
serializedMessage = "0709110b000000dc000000df0000000000bc614e4630440220333835e58e958f5e92b4ff4e6fa2470dac88094c97506b4d6d1f4e23e52cb481022057483ac18d6b9c9c14f0c626694c9ccf8b27b3dbbedfdf6b6c9a9fa9f427a1df02473045022100e7946d057c0b4cc4d3ea525ba156b429796858ebc543d75a6c6c2cbca732db6902202fea377c1f9fb98cd103cf5a4fba276a074b378d4227d15f5fa6439f1a6685bb4630440220235ee55fed634080089953048c3e3f7dc3a154fd7ad18f31dc08e05b7864608a02203bdd7d4e4d9a8162d4b511faf161f0bb16c45181187125017cd0c620c53876ca"
)
//Test serialization
b := new(bytes.Buffer)
err := fundingSignAccept.Encode(b, 0)
if err != nil {
t.Error("Serialization error")
t.Error(err.Error())
} else {
t.Logf("Encoded Funding SignAccept: %x\n", b.Bytes())
//Check if we serialized correctly
if serializedString != hex.EncodeToString(b.Bytes()) {
t.Error("Serialization does not match expected")
}
//So I can do: hexdump -C /dev/shm/fundingSignAccept.raw
if WRITE_FILE {
err = ioutil.WriteFile(FILENAME, b.Bytes(), 0644)
if err != nil {
t.Error("File write error")
t.Error(err.Error())
}
}
}
//Test deserialization
//Make a new buffer just to be clean
c := new(bytes.Buffer)
c.Write(b.Bytes())
newFunding := NewFundingSignAccept()
err = newFunding.Decode(c, 0)
if err != nil {
t.Error("Decoding Error")
t.Error(err.Error())
} else {
if !reflect.DeepEqual(newFunding, fundingSignAccept) {
t.Error("Decoding does not match!")
}
//Show the struct
t.Log(newFunding.String())
}
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
newMessage := NewFundingSignAccept()
DeserializeTest(t, s, newMessage, fundingSignAccept)
//Test message using Message interface
//Serialize/Encode
b = new(bytes.Buffer)
_, err = WriteMessage(b, fundingSignAccept, uint32(1), wire.TestNet3)
t.Logf("%x\n", b.Bytes())
if hex.EncodeToString(b.Bytes()) != serializedMessage {
t.Error("Message encoding error")
}
//Deserialize/Decode
c = new(bytes.Buffer)
c.Write(b.Bytes())
_, msg, _, err := ReadMessage(c, uint32(1), wire.TestNet3)
if err != nil {
t.Errorf(err.Error())
} else {
if !reflect.DeepEqual(msg, fundingSignAccept) {
t.Error("Message decoding does not match!")
}
t.Logf(msg.String())
}
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, fundingSignAccept, fundingSignAcceptSerializedMessage)
}

View File

@ -73,7 +73,9 @@ func (c *FundingSignComplete) String() string {
var sigs string
for i, in := range *c.FundingTXSigs {
sigs += fmt.Sprintf("\n Slice\t%d\n", i)
sigs += fmt.Sprintf("\tSig\t%x\n", in.Serialize())
if &in != nil {
sigs += fmt.Sprintf("\tSig\t%x\n", in.Serialize())
}
}
return fmt.Sprintf("\n--- Begin FundingSignComplete ---\n") +
fmt.Sprintf("ReservationID:\t\t%d\n", c.ReservationID) +

View File

@ -1,112 +1,34 @@
package lnwire
import (
"bytes"
"encoding/hex"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
// "io"
"io/ioutil"
"reflect"
"testing"
)
var (
//funding response
fundingSignComplete = &FundingSignComplete{
ReservationID: uint64(12345678),
TxID: txid,
FundingTXSigs: &fundingTXSigs,
}
fundingSignCompleteSerializedString = "0000000000bc614efd95c6e5c9d5bcf9cfc7231b6a438e46c518c724d0b04b75cc8fddf84a254e3a02473045022100e7946d057c0b4cc4d3ea525ba156b429796858ebc543d75a6c6c2cbca732db6902202fea377c1f9fb98cd103cf5a4fba276a074b378d4227d15f5fa6439f1a6685bb4630440220235ee55fed634080089953048c3e3f7dc3a154fd7ad18f31dc08e05b7864608a02203bdd7d4e4d9a8162d4b511faf161f0bb16c45181187125017cd0c620c53876ca"
fundingSignCompleteSerializedMessage = "0709110b000000e6000000b80000000000bc614efd95c6e5c9d5bcf9cfc7231b6a438e46c518c724d0b04b75cc8fddf84a254e3a02473045022100e7946d057c0b4cc4d3ea525ba156b429796858ebc543d75a6c6c2cbca732db6902202fea377c1f9fb98cd103cf5a4fba276a074b378d4227d15f5fa6439f1a6685bb4630440220235ee55fed634080089953048c3e3f7dc3a154fd7ad18f31dc08e05b7864608a02203bdd7d4e4d9a8162d4b511faf161f0bb16c45181187125017cd0c620c53876ca"
)
func TestFundingSignCompleteEncodeDecode(t *testing.T) {
var (
//For debugging, writes to /dev/shm/
//Maybe in the future do it if you do "go test -v"
WRITE_FILE = false
FILENAME = "/dev/shm/fundingSignComplete.raw"
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
s := SerializeTest(t, fundingSignComplete, fundingSignCompleteSerializedString, filename)
//TxID
txid = new(wire.ShaHash)
//Reversed when displayed
txidBytes, _ = hex.DecodeString("fd95c6e5c9d5bcf9cfc7231b6a438e46c518c724d0b04b75cc8fddf84a254e3a")
_ = copy(txid[:], txidBytes)
//Funding TX Sig 1
tx = wire.NewMsgTx()
emptybytes = new([]byte)
sig1privKeyBytes, _ = hex.DecodeString("927f5827d75dd2addeb532c0fa5ac9277565f981dd6d0d037b422be5f60bdbef")
sig1privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig1privKeyBytes)
sigStr1, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig1privKey)
commitSig1, _ = btcec.ParseSignature(sigStr1, btcec.S256())
//Funding TX Sig 2
sig2privKeyBytes, _ = hex.DecodeString("8a4ad188f6f4000495b765cfb6ffa591133a73019c45428ddd28f53bab551847")
sig2privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig2privKeyBytes)
sigStr2, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig2privKey)
commitSig2, _ = btcec.ParseSignature(sigStr2, btcec.S256())
fundingTXSigs = append(*new([]btcec.Signature), *commitSig1, *commitSig2)
//funding response
fundingSignComplete = &FundingSignComplete{
ReservationID: uint64(12345678),
TxID: txid,
FundingTXSigs: &fundingTXSigs,
}
serializedString = "0000000000bc614efd95c6e5c9d5bcf9cfc7231b6a438e46c518c724d0b04b75cc8fddf84a254e3a02473045022100e7946d057c0b4cc4d3ea525ba156b429796858ebc543d75a6c6c2cbca732db6902202fea377c1f9fb98cd103cf5a4fba276a074b378d4227d15f5fa6439f1a6685bb4630440220235ee55fed634080089953048c3e3f7dc3a154fd7ad18f31dc08e05b7864608a02203bdd7d4e4d9a8162d4b511faf161f0bb16c45181187125017cd0c620c53876ca"
serializedMessage = "0709110b000000e6000000b80000000000bc614efd95c6e5c9d5bcf9cfc7231b6a438e46c518c724d0b04b75cc8fddf84a254e3a02473045022100e7946d057c0b4cc4d3ea525ba156b429796858ebc543d75a6c6c2cbca732db6902202fea377c1f9fb98cd103cf5a4fba276a074b378d4227d15f5fa6439f1a6685bb4630440220235ee55fed634080089953048c3e3f7dc3a154fd7ad18f31dc08e05b7864608a02203bdd7d4e4d9a8162d4b511faf161f0bb16c45181187125017cd0c620c53876ca"
)
//Test serialization
b := new(bytes.Buffer)
err := fundingSignComplete.Encode(b, 0)
if err != nil {
t.Error("Serialization error")
t.Error(err.Error())
} else {
t.Logf("Encoded FundingSignComplete: %x\n", b.Bytes())
//Check if we serialized correctly
if serializedString != hex.EncodeToString(b.Bytes()) {
t.Error("Serialization does not match expected")
}
//So I can do: hexdump -C /dev/shm/fundingSignComplete.raw
if WRITE_FILE {
err = ioutil.WriteFile(FILENAME, b.Bytes(), 0644)
if err != nil {
t.Error("File write error")
t.Error(err.Error())
}
}
}
//Test deserialization
//Make a new buffer just to be clean
c := new(bytes.Buffer)
c.Write(b.Bytes())
newFunding := NewFundingSignComplete()
err = newFunding.Decode(c, 0)
if err != nil {
t.Error("Decoding Error")
t.Error(err.Error())
} else {
if !reflect.DeepEqual(newFunding, fundingSignComplete) {
t.Error("Decoding does not match!")
}
//Show the struct
t.Log(newFunding.String())
}
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
newMessage := NewFundingSignComplete()
DeserializeTest(t, s, newMessage, fundingSignComplete)
//Test message using Message interface
//Serialize/Encode
b = new(bytes.Buffer)
_, err = WriteMessage(b, fundingSignComplete, uint32(1), wire.TestNet3)
t.Logf("%x\n", b.Bytes())
if hex.EncodeToString(b.Bytes()) != serializedMessage {
t.Error("Message encoding error")
}
//Deserialize/Decode
c = new(bytes.Buffer)
c.Write(b.Bytes())
_, msg, _, err := ReadMessage(c, uint32(1), wire.TestNet3)
if err != nil {
t.Errorf(err.Error())
} else {
if !reflect.DeepEqual(msg, fundingSignComplete) {
t.Error("Message decoding does not match!")
}
t.Logf(msg.String())
}
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, fundingSignComplete, fundingSignCompleteSerializedMessage)
}

145
lnwire/lnwire_test.go Normal file
View File

@ -0,0 +1,145 @@
package lnwire
import (
"bytes"
"encoding/hex"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"io/ioutil"
"reflect"
"testing"
)
//Common variables and functions for the message tests
var (
//For debugging, writes to /dev/shm/
//Maybe in the future do it if you do "go test -v"
WRITE_FILE = true
filename = "/dev/shm/serialized.raw"
//preimage: 9a2cbd088763db88dd8ba79e5726daa6aba4aa7e
//echo -n | openssl sha256 | openssl ripemd160 | openssl sha256 | openssl ripemd160
revocationHashBytes, _ = hex.DecodeString("4132b6b48371f7b022a16eacb9b2b0ebee134d41")
revocationHash [20]byte
privKeyBytes, _ = hex.DecodeString("9fa1d55217f57019a3c37f49465896b15836f54cb8ef6963870a52926420a2dd")
privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
// Delivery PkScript
//Privkey: f2c00ead9cbcfec63098dc0a5f152c0165aff40a2ab92feb4e24869a284c32a7
//PKhash: n2fkWVphUzw3zSigzPsv9GuDyg9mohzKpz
deliveryPkScript, _ = hex.DecodeString("76a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac")
// Change PkScript
//Privkey: 5b18f5049efd9d3aff1fb9a06506c0b809fb71562b6ecd02f6c5b3ab298f3b0f
//PKhash: miky84cHvLuk6jcT6GsSbgHR8d7eZCu9Qc
changePkScript, _ = hex.DecodeString("76a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac")
//echo -n | openssl sha256
//This stuff gets reversed!!!
shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
shaHash1, _ = wire.NewShaHash(shaHash1Bytes)
outpoint1 = wire.NewOutPoint(shaHash1, 0)
//echo | openssl sha256
//This stuff gets reversed!!!
shaHash2Bytes, _ = hex.DecodeString("01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b")
shaHash2, _ = wire.NewShaHash(shaHash2Bytes)
outpoint2 = wire.NewOutPoint(shaHash2, 1)
//create inputs from outpoint1 and outpoint2
inputs = []*wire.TxIn{wire.NewTxIn(outpoint1, nil), wire.NewTxIn(outpoint2, nil)}
//Commitment Signature
tx = wire.NewMsgTx()
emptybytes = new([]byte)
sigStr, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, privKey)
commitSig, _ = btcec.ParseSignature(sigStr, btcec.S256())
//Funding TX Sig 1
sig1privKeyBytes, _ = hex.DecodeString("927f5827d75dd2addeb532c0fa5ac9277565f981dd6d0d037b422be5f60bdbef")
sig1privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig1privKeyBytes)
sigStr1, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig1privKey)
commitSig1, _ = btcec.ParseSignature(sigStr1, btcec.S256())
//Funding TX Sig 2
sig2privKeyBytes, _ = hex.DecodeString("8a4ad188f6f4000495b765cfb6ffa591133a73019c45428ddd28f53bab551847")
sig2privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig2privKeyBytes)
sigStr2, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig2privKey)
commitSig2, _ = btcec.ParseSignature(sigStr2, btcec.S256())
//Slice of Funding TX Sigs
fundingTXSigs = append(*new([]btcec.Signature), *commitSig1, *commitSig2)
//TxID
txid = new(wire.ShaHash)
//Reversed when displayed
txidBytes, _ = hex.DecodeString("fd95c6e5c9d5bcf9cfc7231b6a438e46c518c724d0b04b75cc8fddf84a254e3a")
_ = copy(txid[:], txidBytes)
)
func SerializeTest(t *testing.T, message Message, expectedString string, filename string) *bytes.Buffer {
var err error
b := new(bytes.Buffer)
err = message.Encode(b, 0)
if err != nil {
t.Errorf(err.Error())
} else {
t.Logf("Encoded Funding Request: %x\n", b.Bytes())
//Check if we serialized correctly
if expectedString != hex.EncodeToString(b.Bytes()) {
t.Error("Serialization does not match expected")
}
//So I can do: hexdump -C /dev/shm/fundingRequest.raw
if WRITE_FILE {
err = ioutil.WriteFile(filename, b.Bytes(), 0644)
if err != nil {
t.Error(err.Error())
}
}
}
return b
}
func DeserializeTest(t *testing.T, buf *bytes.Buffer, message Message, originalMessage Message) {
var err error
//Make a new buffer just to be clean
c := new(bytes.Buffer)
c.Write(buf.Bytes())
err = message.Decode(c, 0)
if err != nil {
t.Error("Decoding Error")
t.Error(err.Error())
} else {
if !reflect.DeepEqual(message, originalMessage) {
t.Error("Decoding does not match!")
}
//Show the struct
t.Log(message.String())
}
}
func MessageSerializeDeserializeTest(t *testing.T, message Message, expectedString string) {
var err error
b := new(bytes.Buffer)
_, err = WriteMessage(b, message, uint32(1), wire.TestNet3)
t.Logf("%x\n", b.Bytes())
if hex.EncodeToString(b.Bytes()) != expectedString {
t.Error("Message encoding error")
}
//Deserialize/Decode
c := new(bytes.Buffer)
c.Write(b.Bytes())
_, newMsg, _, err := ReadMessage(c, uint32(1), wire.TestNet3)
if err != nil {
t.Errorf(err.Error())
} else {
if !reflect.DeepEqual(newMsg, message) {
t.Error("Message decoding does not match!")
}
t.Logf(newMsg.String())
}
}