mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
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:
parent
cb32ab1fb9
commit
0d4c78e90d
@ -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.
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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) +
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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) +
|
||||
|
@ -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
145
lnwire/lnwire_test.go
Normal 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())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user