Cleanup comments & removed notes on escrow
This commit is contained in:
parent
84c0f56330
commit
f2a1c0368a
@ -1,121 +0,0 @@
|
|||||||
NOTE: Not implemented in code, only included as part of the wire protocol for
|
|
||||||
future implementation!
|
|
||||||
|
|
||||||
There are multiple R-value hashes supported in HTLCs in the wire protocol. This
|
|
||||||
is to support conditional multiparty payments, e.g. 2-of-3 "escrow", which is
|
|
||||||
one of the biggest use cases of bitcoin scripting today. An example use case is
|
|
||||||
a 3rd party escrow verifies whether a seller should be paid. This design is
|
|
||||||
such that the escrow is not a traditional custodial escrow, but instead
|
|
||||||
determines who should get the money in the event of non-cooperation.
|
|
||||||
|
|
||||||
In this implementation, we are including *wire protocol support* but not
|
|
||||||
writing code yet for 2-of-3, it is to be implemented later. Arbitrary N-of-M
|
|
||||||
can be supported with M values higher than 3 and lower than max script size,
|
|
||||||
but let's keep this simple for now!
|
|
||||||
|
|
||||||
How it works: Require 2-of-3 R-value preimages (from 3 hashes) in order for the
|
|
||||||
HTLC to be fulfilled. For each hop in the payment, it requires this 2-of-3
|
|
||||||
condition. The timeout minimum for each hop in the path is at least the minimum
|
|
||||||
agreed contractual escrow timeout. This means each hop consumes a higher amount
|
|
||||||
of time-value (due to much longer timeouts along all channels in the path),
|
|
||||||
which does have greater pressure towards lower hop-distances compared to
|
|
||||||
straight payments.
|
|
||||||
|
|
||||||
This is a slightly different way of thinking about things. It's not signatures
|
|
||||||
that the escrow produces (or for that matters any of the 3-parties in the
|
|
||||||
2-of-3). It's some secret which is revealed to authorize payment. So if the
|
|
||||||
Escrow wants the payment to go through, they disclose the secret (R-value) to
|
|
||||||
the recipient. If the recipient is unable to produce 2-of-3, after the agreed
|
|
||||||
timeout, the sender will be refunded. Sender and receiver can agree to
|
|
||||||
authorize payment in most cases where there is cooperation, escrow is only
|
|
||||||
contacted if there is non-cooperation.
|
|
||||||
|
|
||||||
Supported in the wire protocol for the uint8 (two 4-bit N-of-M):
|
|
||||||
17 (00010001): 1-of-1
|
|
||||||
34 (00100010): 2-of-2
|
|
||||||
35 (00100011): 2-of-3 [with Recipient being 1 of the two N parties]
|
|
||||||
51 (00110011): 3-of-3
|
|
||||||
|
|
||||||
I think the only ones that really matter are 1-of-1, 2-of-3, and 2-of-2. 1-of-2
|
|
||||||
and 1-of-3 doesn't make sense if the recipient must consent to receiving funds
|
|
||||||
anyway (pushing funds w/o consent is tricky due to pay-to-contract-hash) so
|
|
||||||
that's basically a 1-of-1.
|
|
||||||
|
|
||||||
Assume the order in the stack is Sender, Escrow, Recipient.
|
|
||||||
|
|
||||||
For PAID 2-of-3 Escrow+Recipient, the HTLC stack is:
|
|
||||||
<BobSig> <0> <EscrowPreimageR> <RecipientPreimageR> <0>
|
|
||||||
|
|
||||||
If it's REFUND because 2-of-3 has not been redeemed in time:
|
|
||||||
<AliceSig> <1>
|
|
||||||
|
|
||||||
Script (we use OP_1/OP_0 to distinctly show computed true/false. 0/1 is for
|
|
||||||
supplied data as part of the sigScript/redeemScript stack):
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
//Paid
|
|
||||||
OP_IF
|
|
||||||
<CSVDelay> OP_DROP OP_CSV
|
|
||||||
|
|
||||||
//Stack: <BobSig> <0> <EscrowPreimageR> <RecipientPreimageR>
|
|
||||||
//Recipient must agree to receive funds.
|
|
||||||
OP_HASH160 <RecipientHash> OP_EQUALVERIFY
|
|
||||||
|
|
||||||
//Stack: <BobSig> <0> <EscrowPreimageR>
|
|
||||||
//Either the Sender or Escrow must consent for payment
|
|
||||||
OP_HASH160 <EscrowHash> OP_EQUAL
|
|
||||||
//Stack: <BobSig> <0> <OP_1>
|
|
||||||
OP_SWAP
|
|
||||||
//Stack: <BobSig> <OP_1> <0>
|
|
||||||
OP_HASH160 <SenderHash> OP_EQUAL
|
|
||||||
//Stack: <BobSig> <OP_1> <OP_0>
|
|
||||||
OP_BOOLOR
|
|
||||||
//Stack: <BobSig> <OP_1>
|
|
||||||
OP_VERIFY
|
|
||||||
|
|
||||||
<BobPubKey>
|
|
||||||
//Stack: <BobSig> <BobPubKey>
|
|
||||||
//Refund
|
|
||||||
OP_ELSE
|
|
||||||
<CSVDelay> OP_DROP OP_CSV
|
|
||||||
|
|
||||||
<HTLCTimeout> OP_DROP OP_CLTV
|
|
||||||
<AlicePubKey>
|
|
||||||
//Stack: <AliceSig> <AlicePubKey>
|
|
||||||
OP_ENDIF
|
|
||||||
OP_CHECKSIG
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Note: It is possible that Alice and Bob may not be Sender, Recipient, nor
|
|
||||||
Escrow!
|
|
||||||
|
|
||||||
The result? We can do 2-of-3 escrow payments which refund to the sender after a
|
|
||||||
timeout! The Sender and Recipient can agree to redeem and they only need to go
|
|
||||||
to the Escrow if there's a dispute. All nodes along the path gets paid or
|
|
||||||
refunded atomically, the same as a single-HTLC payment on Lightning.
|
|
||||||
|
|
||||||
Possible Resolution States:
|
|
||||||
* Recipient paid: Recipient and Sender provide R-values
|
|
||||||
* Recipient paid: Recipient and Escrow provide R-values
|
|
||||||
* Sender refunded via timeout: Sender is refunded if Recipient cannot convince
|
|
||||||
Escrow or Sender to disclose their R-value before HTLC timeout
|
|
||||||
* Payment immediately cancelled and Sender gets refunded: Payment sent in the
|
|
||||||
opposite direction enforced by same R-values (if there is sender & receiver
|
|
||||||
consent & cooperation to cancel payment)
|
|
||||||
|
|
||||||
Sender+Escrow isn't going to want to push funds w/o cooperation of Recipient.
|
|
||||||
However, it's possible to construct a script that way.
|
|
||||||
|
|
||||||
Ta-da! "Smart Contract(TM)" maymay.
|
|
||||||
|
|
||||||
Escrow-enforced immediately refundable payments (2-of-3 can immediately cancel
|
|
||||||
a payment) are also possible but requires another payment in the opposite
|
|
||||||
direction with the R-value hashed twice (the H becomes the R-value) and funds
|
|
||||||
encumbered in the opposite direction, but that's kind of annoying to write...
|
|
||||||
it's easier if immediate refund can only occur when both Recipient+Sender agree
|
|
||||||
to cancel the payment immediately (otherwise it will wait until the timeout).
|
|
||||||
|
|
||||||
Escrow is only contacted if the recipient needs to redeem and the sender is
|
|
||||||
uncooperative so this is still true to the "lazy escrow service" in Bitcoin
|
|
||||||
multisig.
|
|
||||||
|
|
||||||
(2-of-2 is also needed for payment cancellation.)
|
|
@ -11,15 +11,15 @@ import (
|
|||||||
type CloseComplete struct {
|
type CloseComplete struct {
|
||||||
ReservationID uint64
|
ReservationID uint64
|
||||||
|
|
||||||
ResponderCloseSig *btcec.Signature //Requester's Commitment
|
ResponderCloseSig *btcec.Signature // Requester's Commitment
|
||||||
CloseShaHash *wire.ShaHash //TxID of the Close Tx
|
CloseShaHash *wire.ShaHash // TxID of the Close Tx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CloseComplete) Decode(r io.Reader, pver uint32) error {
|
func (c *CloseComplete) Decode(r io.Reader, pver uint32) error {
|
||||||
//ReservationID (8)
|
// ReservationID (8)
|
||||||
//ResponderCloseSig (73)
|
// ResponderCloseSig (73)
|
||||||
// First byte length then sig
|
// First byte length then sig
|
||||||
//CloseShaHash (32)
|
// CloseShaHash (32)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ReservationID,
|
&c.ReservationID,
|
||||||
&c.ResponderCloseSig,
|
&c.ResponderCloseSig,
|
||||||
@ -31,17 +31,17 @@ func (c *CloseComplete) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new CloseComplete
|
// Creates a new CloseComplete
|
||||||
func NewCloseComplete() *CloseComplete {
|
func NewCloseComplete() *CloseComplete {
|
||||||
return &CloseComplete{}
|
return &CloseComplete{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the CloseComplete struct
|
// Serializes the item from the CloseComplete struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *CloseComplete) Encode(w io.Writer, pver uint32) error {
|
func (c *CloseComplete) Encode(w io.Writer, pver uint32) error {
|
||||||
//ReservationID
|
// ReservationID
|
||||||
//ResponderCloseSig
|
// ResponderCloseSig
|
||||||
//CloseShaHash
|
// CloseShaHash
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ReservationID,
|
c.ReservationID,
|
||||||
c.ResponderCloseSig,
|
c.ResponderCloseSig,
|
||||||
@ -58,13 +58,13 @@ func (c *CloseComplete) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *CloseComplete) MaxPayloadLength(uint32) uint32 {
|
func (c *CloseComplete) MaxPayloadLength(uint32) uint32 {
|
||||||
//8 + 73 + 32
|
// 8 + 73 + 32
|
||||||
return 113
|
return 113
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *CloseComplete) Validate() error {
|
func (c *CloseComplete) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package lnwire
|
package lnwire
|
||||||
|
|
||||||
import (
|
import (
|
||||||
//"github.com/btcsuite/btcutil"
|
// "github.com/btcsuite/btcutil"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,19 +16,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCloseCompleteEncodeDecode(t *testing.T) {
|
func TestCloseCompleteEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, closeComplete, closeCompleteSerializedString, filename)
|
s := SerializeTest(t, closeComplete, closeCompleteSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewCloseComplete()
|
newMessage := NewCloseComplete()
|
||||||
DeserializeTest(t, s, newMessage, closeComplete)
|
DeserializeTest(t, s, newMessage, closeComplete)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, closeComplete, closeCompleteSerializedMessage)
|
MessageSerializeDeserializeTest(t, closeComplete, closeCompleteSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -11,15 +11,15 @@ import (
|
|||||||
type CloseRequest struct {
|
type CloseRequest struct {
|
||||||
ReservationID uint64
|
ReservationID uint64
|
||||||
|
|
||||||
RequesterCloseSig *btcec.Signature //Requester's Commitment
|
RequesterCloseSig *btcec.Signature // Requester's Commitment
|
||||||
Fee btcutil.Amount
|
Fee btcutil.Amount
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CloseRequest) Decode(r io.Reader, pver uint32) error {
|
func (c *CloseRequest) Decode(r io.Reader, pver uint32) error {
|
||||||
//ReservationID (8)
|
// ReservationID (8)
|
||||||
//RequesterCloseSig (73)
|
// RequesterCloseSig (73)
|
||||||
// First byte length then sig
|
// First byte length then sig
|
||||||
//Fee (8)
|
// Fee (8)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ReservationID,
|
&c.ReservationID,
|
||||||
&c.RequesterCloseSig,
|
&c.RequesterCloseSig,
|
||||||
@ -31,17 +31,17 @@ func (c *CloseRequest) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new CloseRequest
|
// Creates a new CloseRequest
|
||||||
func NewCloseRequest() *CloseRequest {
|
func NewCloseRequest() *CloseRequest {
|
||||||
return &CloseRequest{}
|
return &CloseRequest{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the CloseRequest struct
|
// Serializes the item from the CloseRequest struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *CloseRequest) Encode(w io.Writer, pver uint32) error {
|
func (c *CloseRequest) Encode(w io.Writer, pver uint32) error {
|
||||||
//ReservationID
|
// ReservationID
|
||||||
//RequesterCloseSig
|
// RequesterCloseSig
|
||||||
//Fee
|
// Fee
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ReservationID,
|
c.ReservationID,
|
||||||
c.RequesterCloseSig,
|
c.RequesterCloseSig,
|
||||||
@ -58,17 +58,17 @@ func (c *CloseRequest) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *CloseRequest) MaxPayloadLength(uint32) uint32 {
|
func (c *CloseRequest) MaxPayloadLength(uint32) uint32 {
|
||||||
//8 + 73 + 8
|
// 8 + 73 + 8
|
||||||
return 89
|
return 89
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *CloseRequest) Validate() error {
|
func (c *CloseRequest) Validate() error {
|
||||||
//Fee must be greater than 0
|
// Fee must be greater than 0
|
||||||
if c.Fee < 0 {
|
if c.Fee < 0 {
|
||||||
return fmt.Errorf("Fee must be greater than zero.")
|
return fmt.Errorf("Fee must be greater than zero.")
|
||||||
}
|
}
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,19 +16,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCloseRequestEncodeDecode(t *testing.T) {
|
func TestCloseRequestEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, closeRequest, closeRequestSerializedString, filename)
|
s := SerializeTest(t, closeRequest, closeRequestSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewCloseRequest()
|
newMessage := NewCloseRequest()
|
||||||
DeserializeTest(t, s, newMessage, closeRequest)
|
DeserializeTest(t, s, newMessage, closeRequest)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, closeRequest, closeRequestSerializedMessage)
|
MessageSerializeDeserializeTest(t, closeRequest, closeRequestSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -5,28 +5,28 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Multiple Clearing Requests are possible by putting this inside an array of
|
// Multiple Clearing Requests are possible by putting this inside an array of
|
||||||
//clearing requests
|
// clearing requests
|
||||||
type CommitRevocation struct {
|
type CommitRevocation struct {
|
||||||
//We can use a different data type for this if necessary...
|
// We can use a different data type for this if necessary...
|
||||||
ChannelID uint64
|
ChannelID uint64
|
||||||
|
|
||||||
//Height of the commitment
|
// Height of the commitment
|
||||||
//You should have the most recent commitment height stored locally
|
// You should have the most recent commitment height stored locally
|
||||||
//This should be validated!
|
// This should be validated!
|
||||||
//This is used for shachain.
|
// This is used for shachain.
|
||||||
//Each party increments their own CommitmentHeight, they can differ for
|
// Each party increments their own CommitmentHeight, they can differ for
|
||||||
//each part of the Commitment.
|
// each part of the Commitment.
|
||||||
CommitmentHeight uint64
|
CommitmentHeight uint64
|
||||||
|
|
||||||
//Revocation to use
|
// Revocation to use
|
||||||
RevocationProof [20]byte
|
RevocationProof [20]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommitRevocation) Decode(r io.Reader, pver uint32) error {
|
func (c *CommitRevocation) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//CommitmentHeight(8)
|
// CommitmentHeight(8)
|
||||||
//RevocationProof(20)
|
// RevocationProof(20)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.CommitmentHeight,
|
&c.CommitmentHeight,
|
||||||
@ -39,13 +39,13 @@ func (c *CommitRevocation) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new CommitRevocation
|
// Creates a new CommitRevocation
|
||||||
func NewCommitRevocation() *CommitRevocation {
|
func NewCommitRevocation() *CommitRevocation {
|
||||||
return &CommitRevocation{}
|
return &CommitRevocation{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the CommitRevocation struct
|
// Serializes the item from the CommitRevocation struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *CommitRevocation) Encode(w io.Writer, pver uint32) error {
|
func (c *CommitRevocation) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -67,9 +67,9 @@ func (c *CommitRevocation) MaxPayloadLength(uint32) uint32 {
|
|||||||
return 36
|
return 36
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *CommitRevocation) Validate() error {
|
func (c *CommitRevocation) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,32 +5,32 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//Need to to do this here
|
// Need to to do this here
|
||||||
_ = copy(revocationHash[:], revocationHashBytes)
|
_ = copy(revocationHash[:], revocationHashBytes)
|
||||||
|
|
||||||
commitRevocation = &CommitRevocation{
|
commitRevocation = &CommitRevocation{
|
||||||
ChannelID: uint64(12345678),
|
ChannelID: uint64(12345678),
|
||||||
CommitmentHeight: uint64(12345),
|
CommitmentHeight: uint64(12345),
|
||||||
RevocationProof: revocationHash, //technically it's not a hash... fix later
|
RevocationProof: revocationHash, // technically it's not a hash... fix later
|
||||||
}
|
}
|
||||||
commitRevocationSerializedString = "0000000000bc614e00000000000030394132b6b48371f7b022a16eacb9b2b0ebee134d41"
|
commitRevocationSerializedString = "0000000000bc614e00000000000030394132b6b48371f7b022a16eacb9b2b0ebee134d41"
|
||||||
commitRevocationSerializedMessage = "0709110b000007da000000240000000000bc614e00000000000030394132b6b48371f7b022a16eacb9b2b0ebee134d41"
|
commitRevocationSerializedMessage = "0709110b000007da000000240000000000bc614e00000000000030394132b6b48371f7b022a16eacb9b2b0ebee134d41"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCommitRevocationEncodeDecode(t *testing.T) {
|
func TestCommitRevocationEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, commitRevocation, commitRevocationSerializedString, filename)
|
s := SerializeTest(t, commitRevocation, commitRevocationSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewCommitRevocation()
|
newMessage := NewCommitRevocation()
|
||||||
DeserializeTest(t, s, newMessage, commitRevocation)
|
DeserializeTest(t, s, newMessage, commitRevocation)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, commitRevocation, commitRevocationSerializedMessage)
|
MessageSerializeDeserializeTest(t, commitRevocation, commitRevocationSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -7,40 +7,40 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Multiple Clearing Requests are possible by putting this inside an array of
|
// Multiple Clearing Requests are possible by putting this inside an array of
|
||||||
//clearing requests
|
// clearing requests
|
||||||
type CommitSignature struct {
|
type CommitSignature struct {
|
||||||
//We can use a different data type for this if necessary...
|
// We can use a different data type for this if necessary...
|
||||||
ChannelID uint64
|
ChannelID uint64
|
||||||
|
|
||||||
//Height of the commitment
|
// Height of the commitment
|
||||||
//You should have the most recent commitment height stored locally
|
// You should have the most recent commitment height stored locally
|
||||||
//This should be validated!
|
// This should be validated!
|
||||||
//This is used for shachain.
|
// This is used for shachain.
|
||||||
//Each party increments their own CommitmentHeight, they can differ for
|
// Each party increments their own CommitmentHeight, they can differ for
|
||||||
//each part of the Commitment.
|
// each part of the Commitment.
|
||||||
CommitmentHeight uint64
|
CommitmentHeight uint64
|
||||||
|
|
||||||
//List of HTLC Keys which are updated from all parties
|
// List of HTLC Keys which are updated from all parties
|
||||||
UpdatedHTLCKeys []uint64
|
UpdatedHTLCKeys []uint64
|
||||||
|
|
||||||
//Hash of the revocation to use
|
// Hash of the revocation to use
|
||||||
RevocationHash [20]byte
|
RevocationHash [20]byte
|
||||||
|
|
||||||
//Total miners' fee that was used
|
// Total miners' fee that was used
|
||||||
Fee btcutil.Amount
|
Fee btcutil.Amount
|
||||||
|
|
||||||
//Signature for the new Commitment
|
// Signature for the new Commitment
|
||||||
CommitSig *btcec.Signature //Requester's Commitment
|
CommitSig *btcec.Signature // Requester's Commitment
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommitSignature) Decode(r io.Reader, pver uint32) error {
|
func (c *CommitSignature) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//CommitmentHeight(8)
|
// CommitmentHeight(8)
|
||||||
//c.UpdatedHTLCKeys(8*1000max)
|
// c.UpdatedHTLCKeys(8*1000max)
|
||||||
//RevocationHash(20)
|
// RevocationHash(20)
|
||||||
//Fee(8)
|
// Fee(8)
|
||||||
//RequesterCommitSig(73max+2)
|
// RequesterCommitSig(73max+2)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.CommitmentHeight,
|
&c.CommitmentHeight,
|
||||||
@ -56,13 +56,13 @@ func (c *CommitSignature) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new CommitSignature
|
// Creates a new CommitSignature
|
||||||
func NewCommitSignature() *CommitSignature {
|
func NewCommitSignature() *CommitSignature {
|
||||||
return &CommitSignature{}
|
return &CommitSignature{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the CommitSignature struct
|
// Serializes the item from the CommitSignature struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *CommitSignature) Encode(w io.Writer, pver uint32) error {
|
func (c *CommitSignature) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -87,24 +87,24 @@ func (c *CommitSignature) MaxPayloadLength(uint32) uint32 {
|
|||||||
return 8192
|
return 8192
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *CommitSignature) Validate() error {
|
func (c *CommitSignature) Validate() error {
|
||||||
if c.Fee < 0 {
|
if c.Fee < 0 {
|
||||||
//While fees can be negative, it's too confusing to allow
|
// While fees can be negative, it's too confusing to allow
|
||||||
//negative payments. Maybe for some wallets, but not this one!
|
// negative payments. Maybe for some wallets, but not this one!
|
||||||
return fmt.Errorf("Amount paid cannot be negative.")
|
return fmt.Errorf("Amount paid cannot be negative.")
|
||||||
}
|
}
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommitSignature) String() string {
|
func (c *CommitSignature) String() string {
|
||||||
//c.ChannelID,
|
// c.ChannelID,
|
||||||
//c.CommitmentHeight,
|
// c.CommitmentHeight,
|
||||||
//c.RevocationHash,
|
// c.RevocationHash,
|
||||||
//c.UpdatedHTLCKeys,
|
// c.UpdatedHTLCKeys,
|
||||||
//c.Fee,
|
// c.Fee,
|
||||||
//c.CommitSig,
|
// c.CommitSig,
|
||||||
var serializedSig []byte
|
var serializedSig []byte
|
||||||
if &c.CommitSig != nil && c.CommitSig.R != nil {
|
if &c.CommitSig != nil && c.CommitSig.R != nil {
|
||||||
serializedSig = c.CommitSig.Serialize()
|
serializedSig = c.CommitSig.Serialize()
|
||||||
|
@ -6,13 +6,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//Need to to do this here
|
// Need to to do this here
|
||||||
_ = copy(revocationHash[:], revocationHashBytes)
|
_ = copy(revocationHash[:], revocationHashBytes)
|
||||||
|
|
||||||
commitSignature = &CommitSignature{
|
commitSignature = &CommitSignature{
|
||||||
ChannelID: uint64(12345678),
|
ChannelID: uint64(12345678),
|
||||||
CommitmentHeight: uint64(12345),
|
CommitmentHeight: uint64(12345),
|
||||||
//CommitterLastStaging: uint64(12345678),
|
// CommitterLastStaging: uint64(12345678),
|
||||||
UpdatedHTLCKeys: []uint64{1, 2, 3, 4, 5},
|
UpdatedHTLCKeys: []uint64{1, 2, 3, 4, 5},
|
||||||
RevocationHash: revocationHash,
|
RevocationHash: revocationHash,
|
||||||
Fee: btcutil.Amount(10000),
|
Fee: btcutil.Amount(10000),
|
||||||
@ -23,19 +23,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCommitSignatureEncodeDecode(t *testing.T) {
|
func TestCommitSignatureEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, commitSignature, commitSignatureSerializedString, filename)
|
s := SerializeTest(t, commitSignature, commitSignatureSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewCommitSignature()
|
newMessage := NewCommitSignature()
|
||||||
DeserializeTest(t, s, newMessage, commitSignature)
|
DeserializeTest(t, s, newMessage, commitSignature)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, commitSignature, commitSignatureSerializedMessage)
|
MessageSerializeDeserializeTest(t, commitSignature, commitSignatureSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,19 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Multiple Clearing Requests are possible by putting this inside an array of
|
// Multiple Clearing Requests are possible by putting this inside an array of
|
||||||
//clearing requests
|
// clearing requests
|
||||||
type ErrorGeneric struct {
|
type ErrorGeneric struct {
|
||||||
//We can use a different data type for this if necessary...
|
// We can use a different data type for this if necessary...
|
||||||
ChannelID uint64
|
ChannelID uint64
|
||||||
//Some kind of message
|
// Some kind of message
|
||||||
//Max length 8192
|
// Max length 8192
|
||||||
Problem string
|
Problem string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ErrorGeneric) Decode(r io.Reader, pver uint32) error {
|
func (c *ErrorGeneric) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//Problem
|
// Problem
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.Problem,
|
&c.Problem,
|
||||||
@ -29,13 +29,13 @@ func (c *ErrorGeneric) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new ErrorGeneric
|
// Creates a new ErrorGeneric
|
||||||
func NewErrorGeneric() *ErrorGeneric {
|
func NewErrorGeneric() *ErrorGeneric {
|
||||||
return &ErrorGeneric{}
|
return &ErrorGeneric{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the ErrorGeneric struct
|
// Serializes the item from the ErrorGeneric struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *ErrorGeneric) Encode(w io.Writer, pver uint32) error {
|
func (c *ErrorGeneric) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -53,16 +53,16 @@ func (c *ErrorGeneric) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ErrorGeneric) MaxPayloadLength(uint32) uint32 {
|
func (c *ErrorGeneric) MaxPayloadLength(uint32) uint32 {
|
||||||
//8+8192
|
// 8+8192
|
||||||
return 8208
|
return 8208
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *ErrorGeneric) Validate() error {
|
func (c *ErrorGeneric) Validate() error {
|
||||||
if len(c.Problem) > 8192 {
|
if len(c.Problem) > 8192 {
|
||||||
return fmt.Errorf("Problem string length too long")
|
return fmt.Errorf("Problem string length too long")
|
||||||
}
|
}
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestErrorGenericEncodeDecode(t *testing.T) {
|
func TestErrorGenericEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, errorGeneric, errorGenericSerializedString, filename)
|
s := SerializeTest(t, errorGeneric, errorGenericSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewErrorGeneric()
|
newMessage := NewErrorGeneric()
|
||||||
DeserializeTest(t, s, newMessage, errorGeneric)
|
DeserializeTest(t, s, newMessage, errorGeneric)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, errorGeneric, errorGenericSerializedMessage)
|
MessageSerializeDeserializeTest(t, errorGeneric, errorGenericSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -17,62 +17,62 @@ type FundingRequest struct {
|
|||||||
RequesterReserveAmount btcutil.Amount
|
RequesterReserveAmount btcutil.Amount
|
||||||
MinFeePerKb btcutil.Amount
|
MinFeePerKb btcutil.Amount
|
||||||
|
|
||||||
//The funding requester can request payment
|
// The funding requester can request payment
|
||||||
//This wallet only allows positive values,
|
// This wallet only allows positive values,
|
||||||
//which is a payment to the responder
|
// which is a payment to the responder
|
||||||
//(This can be used to fund the Reserve)
|
// (This can be used to fund the Reserve)
|
||||||
//If the responder disagrees, then the funding request fails
|
// If the responder disagrees, then the funding request fails
|
||||||
//THIS VALUE GOES INTO THE RESPONDER'S FUNDING AMOUNT
|
// THIS VALUE GOES INTO THE RESPONDER'S FUNDING AMOUNT
|
||||||
//total requester input value = RequesterFundingAmount + PaymentAmount + "Total Change" + Fees(?)
|
// total requester input value = RequesterFundingAmount + PaymentAmount + "Total Change" + Fees(?)
|
||||||
//RequesterFundingAmount = "Available Balance" + RequesterReserveAmount
|
// RequesterFundingAmount = "Available Balance" + RequesterReserveAmount
|
||||||
//Payment SHOULD NOT be acknowledged until the minimum confirmation has elapsed
|
// Payment SHOULD NOT be acknowledged until the minimum confirmation has elapsed
|
||||||
//(Due to double-spend risks the recipient will not want to acknolwedge confirmation until later)
|
// (Due to double-spend risks the recipient will not want to acknolwedge confirmation until later)
|
||||||
//This is to make a payment as part of opening the channel
|
// This is to make a payment as part of opening the channel
|
||||||
PaymentAmount btcutil.Amount
|
PaymentAmount btcutil.Amount
|
||||||
|
|
||||||
//Minimum number of confirmations to validate transaction
|
// Minimum number of confirmations to validate transaction
|
||||||
MinDepth uint32
|
MinDepth uint32
|
||||||
|
|
||||||
//Should double-check the total funding later
|
// Should double-check the total funding later
|
||||||
MinTotalFundingAmount btcutil.Amount
|
MinTotalFundingAmount btcutil.Amount
|
||||||
|
|
||||||
//CLTV/CSV lock-time to use
|
// CLTV/CSV lock-time to use
|
||||||
LockTime uint32
|
LockTime uint32
|
||||||
|
|
||||||
//Who pays the fees
|
// Who pays the fees
|
||||||
//0: (default) channel initiator
|
// 0: (default) channel initiator
|
||||||
//1: split
|
// 1: split
|
||||||
//2: channel responder
|
// 2: channel responder
|
||||||
FeePayer uint8
|
FeePayer uint8
|
||||||
|
|
||||||
RevocationHash [20]byte
|
RevocationHash [20]byte
|
||||||
Pubkey *btcec.PublicKey
|
Pubkey *btcec.PublicKey
|
||||||
DeliveryPkScript PkScript //*MUST* be either P2PKH or P2SH
|
DeliveryPkScript PkScript // *MUST* be either P2PKH or P2SH
|
||||||
ChangePkScript PkScript //*MUST* be either P2PKH or P2SH
|
ChangePkScript PkScript // *MUST* be either P2PKH or P2SH
|
||||||
|
|
||||||
Inputs []*wire.TxIn
|
Inputs []*wire.TxIn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FundingRequest) Decode(r io.Reader, pver uint32) error {
|
func (c *FundingRequest) Decode(r io.Reader, pver uint32) error {
|
||||||
//Reservation ID (8)
|
// Reservation ID (8)
|
||||||
//Channel Type (1)
|
// Channel Type (1)
|
||||||
//Funding Amount (8)
|
// Funding Amount (8)
|
||||||
//Channel Minimum Capacity (8)
|
// Channel Minimum Capacity (8)
|
||||||
//Revocation Hash (20)
|
// Revocation Hash (20)
|
||||||
//Commitment Pubkey (32)
|
// Commitment Pubkey (32)
|
||||||
//Reserve Amount (8)
|
// Reserve Amount (8)
|
||||||
//Minimum Transaction Fee Per Kb (8)
|
// Minimum Transaction Fee Per Kb (8)
|
||||||
//PaymentAmount (8)
|
// PaymentAmount (8)
|
||||||
//MinDepth (4)
|
// MinDepth (4)
|
||||||
//LockTime (4)
|
// LockTime (4)
|
||||||
//FeePayer (1)
|
// FeePayer (1)
|
||||||
//DeliveryPkScript (final delivery)
|
// DeliveryPkScript (final delivery)
|
||||||
// First byte length then pkscript
|
// First byte length then pkscript
|
||||||
//ChangePkScript (change for extra from inputs)
|
// ChangePkScript (change for extra from inputs)
|
||||||
// First byte length then pkscript
|
// First byte length then pkscript
|
||||||
//Inputs: Create the TxIns
|
// Inputs: Create the TxIns
|
||||||
// First byte is number of inputs
|
// First byte is number of inputs
|
||||||
// For each input, it's 32bytes txin & 4bytes index
|
// For each input, it's 32bytes txin & 4bytes index
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ReservationID,
|
&c.ReservationID,
|
||||||
&c.ChannelType,
|
&c.ChannelType,
|
||||||
@ -96,26 +96,26 @@ func (c *FundingRequest) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new FundingRequest
|
// Creates a new FundingRequest
|
||||||
func NewFundingRequest() *FundingRequest {
|
func NewFundingRequest() *FundingRequest {
|
||||||
return &FundingRequest{}
|
return &FundingRequest{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the FundingRequest struct
|
// Serializes the item from the FundingRequest struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *FundingRequest) Encode(w io.Writer, pver uint32) error {
|
func (c *FundingRequest) Encode(w io.Writer, pver uint32) error {
|
||||||
//Channel Type
|
// Channel Type
|
||||||
//Funding Amont
|
// Funding Amont
|
||||||
//Channel Minimum Capacity
|
// Channel Minimum Capacity
|
||||||
//Revocation Hash
|
// Revocation Hash
|
||||||
//Commitment Pubkey
|
// Commitment Pubkey
|
||||||
//Reserve Amount
|
// Reserve Amount
|
||||||
//Minimum Transaction Fee Per KB
|
// Minimum Transaction Fee Per KB
|
||||||
//LockTime
|
// LockTime
|
||||||
//FeePayer
|
// FeePayer
|
||||||
//DeliveryPkScript
|
// DeliveryPkScript
|
||||||
//ChangePkScript
|
// ChangePkScript
|
||||||
//Inputs: Append the actual Txins
|
// Inputs: Append the actual Txins
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ReservationID,
|
c.ReservationID,
|
||||||
c.ChannelType,
|
c.ChannelType,
|
||||||
@ -144,15 +144,15 @@ func (c *FundingRequest) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *FundingRequest) MaxPayloadLength(uint32) uint32 {
|
func (c *FundingRequest) MaxPayloadLength(uint32) uint32 {
|
||||||
//110 (base size) + 26 (pkscript) + 26 (pkscript) + 1 (numTxes) + 127*36(127 inputs * sha256+idx)
|
// 110 (base size) + 26 (pkscript) + 26 (pkscript) + 1 (numTxes) + 127*36(127 inputs * sha256+idx)
|
||||||
return 4735
|
return 4735
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *FundingRequest) Validate() error {
|
func (c *FundingRequest) Validate() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
//No negative values
|
// No negative values
|
||||||
if c.RequesterFundingAmount < 0 {
|
if c.RequesterFundingAmount < 0 {
|
||||||
return fmt.Errorf("RequesterFundingAmount cannot be negative")
|
return fmt.Errorf("RequesterFundingAmount cannot be negative")
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ func (c *FundingRequest) Validate() error {
|
|||||||
return fmt.Errorf("MinTotalFundingAmount cannot be negative")
|
return fmt.Errorf("MinTotalFundingAmount cannot be negative")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Validation of what makes sense...
|
// Validation of what makes sense...
|
||||||
if c.MinTotalFundingAmount < c.RequesterFundingAmount {
|
if c.MinTotalFundingAmount < c.RequesterFundingAmount {
|
||||||
return fmt.Errorf("Requester's minimum too low.")
|
return fmt.Errorf("Requester's minimum too low.")
|
||||||
}
|
}
|
||||||
@ -176,29 +176,29 @@ func (c *FundingRequest) Validate() error {
|
|||||||
return fmt.Errorf("Reserve must be below Funding Amount")
|
return fmt.Errorf("Reserve must be below Funding Amount")
|
||||||
}
|
}
|
||||||
|
|
||||||
//This wallet only allows payment from the requester to responder
|
// This wallet only allows payment from the requester to responder
|
||||||
if c.PaymentAmount < 0 {
|
if c.PaymentAmount < 0 {
|
||||||
return fmt.Errorf("This wallet requieres payment to be greater than zero.")
|
return fmt.Errorf("This wallet requieres payment to be greater than zero.")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make sure there's not more than 127 inputs
|
// Make sure there's not more than 127 inputs
|
||||||
if len(c.Inputs) > 127 {
|
if len(c.Inputs) > 127 {
|
||||||
return fmt.Errorf("Too many inputs")
|
return fmt.Errorf("Too many inputs")
|
||||||
}
|
}
|
||||||
|
|
||||||
//DeliveryPkScript is either P2SH or P2PKH
|
// DeliveryPkScript is either P2SH or P2PKH
|
||||||
err = ValidatePkScript(c.DeliveryPkScript)
|
err = ValidatePkScript(c.DeliveryPkScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//ChangePkScript is either P2SH or P2PKH
|
// ChangePkScript is either P2SH or P2PKH
|
||||||
err = ValidatePkScript(c.ChangePkScript)
|
err = ValidatePkScript(c.ChangePkScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//Need to do this here
|
// Need to do this here
|
||||||
_ = copy(revocationHash[:], revocationHashBytes)
|
_ = copy(revocationHash[:], revocationHashBytes)
|
||||||
|
|
||||||
//funding request
|
// funding request
|
||||||
fundingRequest = &FundingRequest{
|
fundingRequest = &FundingRequest{
|
||||||
ReservationID: uint64(12345678),
|
ReservationID: uint64(12345678),
|
||||||
ChannelType: uint8(0),
|
ChannelType: uint8(0),
|
||||||
@ -17,7 +17,7 @@ var (
|
|||||||
RequesterReserveAmount: btcutil.Amount(131072),
|
RequesterReserveAmount: btcutil.Amount(131072),
|
||||||
MinFeePerKb: btcutil.Amount(20000),
|
MinFeePerKb: btcutil.Amount(20000),
|
||||||
MinTotalFundingAmount: btcutil.Amount(150000000),
|
MinTotalFundingAmount: btcutil.Amount(150000000),
|
||||||
LockTime: uint32(4320), //30 block-days
|
LockTime: uint32(4320), // 30 block-days
|
||||||
FeePayer: uint8(0),
|
FeePayer: uint8(0),
|
||||||
PaymentAmount: btcutil.Amount(1234567),
|
PaymentAmount: btcutil.Amount(1234567),
|
||||||
MinDepth: uint32(6),
|
MinDepth: uint32(6),
|
||||||
@ -32,19 +32,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestFundingRequestEncodeDecode(t *testing.T) {
|
func TestFundingRequestEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, fundingRequest, fundingRequestSerializedString, filename)
|
s := SerializeTest(t, fundingRequest, fundingRequestSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewFundingRequest()
|
newMessage := NewFundingRequest()
|
||||||
DeserializeTest(t, s, newMessage, fundingRequest)
|
DeserializeTest(t, s, newMessage, fundingRequest)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, fundingRequest, fundingRequestSerializedMessage)
|
MessageSerializeDeserializeTest(t, fundingRequest, fundingRequestSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -13,51 +13,51 @@ type FundingResponse struct {
|
|||||||
|
|
||||||
ReservationID uint64
|
ReservationID uint64
|
||||||
|
|
||||||
ResponderFundingAmount btcutil.Amount //Responder's funding amount
|
ResponderFundingAmount btcutil.Amount // Responder's funding amount
|
||||||
ResponderReserveAmount btcutil.Amount //Responder's reserve amount
|
ResponderReserveAmount btcutil.Amount // Responder's reserve amount
|
||||||
MinFeePerKb btcutil.Amount //Lock-in min fee
|
MinFeePerKb btcutil.Amount // Lock-in min fee
|
||||||
|
|
||||||
//Minimum depth
|
// Minimum depth
|
||||||
MinDepth uint32
|
MinDepth uint32
|
||||||
|
|
||||||
//CLTV/CSV lock-time to use
|
// CLTV/CSV lock-time to use
|
||||||
LockTime uint32
|
LockTime uint32
|
||||||
|
|
||||||
//Who pays the fees
|
// Who pays the fees
|
||||||
//0: (default) channel initiator
|
// 0: (default) channel initiator
|
||||||
//1: split
|
// 1: split
|
||||||
//2: channel responder
|
// 2: channel responder
|
||||||
FeePayer uint8
|
FeePayer uint8
|
||||||
|
|
||||||
RevocationHash [20]byte
|
RevocationHash [20]byte
|
||||||
Pubkey *btcec.PublicKey
|
Pubkey *btcec.PublicKey
|
||||||
CommitSig *btcec.Signature //Requester's Commitment
|
CommitSig *btcec.Signature // Requester's Commitment
|
||||||
DeliveryPkScript PkScript //*MUST* be either P2PKH or P2SH
|
DeliveryPkScript PkScript // *MUST* be either P2PKH or P2SH
|
||||||
ChangePkScript PkScript //*MUST* be either P2PKH or P2SH
|
ChangePkScript PkScript // *MUST* be either P2PKH or P2SH
|
||||||
|
|
||||||
Inputs []*wire.TxIn
|
Inputs []*wire.TxIn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FundingResponse) Decode(r io.Reader, pver uint32) error {
|
func (c *FundingResponse) Decode(r io.Reader, pver uint32) error {
|
||||||
//ReservationID (8)
|
// ReservationID (8)
|
||||||
//Channel Type (1)
|
// Channel Type (1)
|
||||||
//Funding Amount (8)
|
// Funding Amount (8)
|
||||||
//Revocation Hash (20)
|
// Revocation Hash (20)
|
||||||
//Commitment Pubkey (32)
|
// Commitment Pubkey (32)
|
||||||
//Reserve Amount (8)
|
// Reserve Amount (8)
|
||||||
//Minimum Transaction Fee Per Kb (8)
|
// Minimum Transaction Fee Per Kb (8)
|
||||||
//MinDepth (4)
|
// MinDepth (4)
|
||||||
//LockTime (4)
|
// LockTime (4)
|
||||||
//FeePayer (1)
|
// FeePayer (1)
|
||||||
//DeliveryPkScript (final delivery)
|
// DeliveryPkScript (final delivery)
|
||||||
// First byte length then pkscript
|
// First byte length then pkscript
|
||||||
//ChangePkScript (change for extra from inputs)
|
// ChangePkScript (change for extra from inputs)
|
||||||
// First byte length then pkscript
|
// First byte length then pkscript
|
||||||
//CommitSig
|
// CommitSig
|
||||||
// First byte length then sig
|
// First byte length then sig
|
||||||
//Inputs: Create the TxIns
|
// Inputs: Create the TxIns
|
||||||
// First byte is number of inputs
|
// First byte is number of inputs
|
||||||
// For each input, it's 32bytes txin & 4bytes index
|
// For each input, it's 32bytes txin & 4bytes index
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ReservationID,
|
&c.ReservationID,
|
||||||
&c.ChannelType,
|
&c.ChannelType,
|
||||||
@ -80,27 +80,27 @@ func (c *FundingResponse) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new FundingResponse
|
// Creates a new FundingResponse
|
||||||
func NewFundingResponse() *FundingResponse {
|
func NewFundingResponse() *FundingResponse {
|
||||||
return &FundingResponse{}
|
return &FundingResponse{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the FundingResponse struct
|
// Serializes the item from the FundingResponse struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *FundingResponse) Encode(w io.Writer, pver uint32) error {
|
func (c *FundingResponse) Encode(w io.Writer, pver uint32) error {
|
||||||
//ReservationID (8)
|
// ReservationID (8)
|
||||||
//Channel Type (1)
|
// Channel Type (1)
|
||||||
//Funding Amount (8)
|
// Funding Amount (8)
|
||||||
//Revocation Hash (20)
|
// Revocation Hash (20)
|
||||||
//Commitment Pubkey (32)
|
// Commitment Pubkey (32)
|
||||||
//Reserve Amount (8)
|
// Reserve Amount (8)
|
||||||
//Minimum Transaction Fee Per Kb (8)
|
// Minimum Transaction Fee Per Kb (8)
|
||||||
//LockTime (4)
|
// LockTime (4)
|
||||||
//FeePayer (1)
|
// FeePayer (1)
|
||||||
//DeliveryPkScript (final delivery)
|
// DeliveryPkScript (final delivery)
|
||||||
//ChangePkScript (change for extra from inputs)
|
// ChangePkScript (change for extra from inputs)
|
||||||
//CommitSig
|
// CommitSig
|
||||||
//Inputs
|
// Inputs
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ReservationID,
|
c.ReservationID,
|
||||||
c.ChannelType,
|
c.ChannelType,
|
||||||
@ -128,15 +128,15 @@ func (c *FundingResponse) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *FundingResponse) MaxPayloadLength(uint32) uint32 {
|
func (c *FundingResponse) MaxPayloadLength(uint32) uint32 {
|
||||||
//86 (base size) + 26 (pkscript) + 26 (pkscript) + 74sig + 1 (numTxes) + 127*36(127 inputs * sha256+idx)
|
// 86 (base size) + 26 (pkscript) + 26 (pkscript) + 74sig + 1 (numTxes) + 127*36(127 inputs * sha256+idx)
|
||||||
return 4785
|
return 4785
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *FundingResponse) Validate() error {
|
func (c *FundingResponse) Validate() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
//No negative values
|
// No negative values
|
||||||
if c.ResponderFundingAmount < 0 {
|
if c.ResponderFundingAmount < 0 {
|
||||||
return fmt.Errorf("ResponderFundingAmount cannot be negative")
|
return fmt.Errorf("ResponderFundingAmount cannot be negative")
|
||||||
}
|
}
|
||||||
@ -149,29 +149,29 @@ func (c *FundingResponse) Validate() error {
|
|||||||
return fmt.Errorf("MinFeePerKb cannot be negative")
|
return fmt.Errorf("MinFeePerKb cannot be negative")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Validation of what makes sense...
|
// Validation of what makes sense...
|
||||||
if c.ResponderFundingAmount < c.ResponderReserveAmount {
|
if c.ResponderFundingAmount < c.ResponderReserveAmount {
|
||||||
return fmt.Errorf("Reserve must be below Funding Amount")
|
return fmt.Errorf("Reserve must be below Funding Amount")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make sure there's not more than 127 inputs
|
// Make sure there's not more than 127 inputs
|
||||||
if len(c.Inputs) > 127 {
|
if len(c.Inputs) > 127 {
|
||||||
return fmt.Errorf("Too many inputs")
|
return fmt.Errorf("Too many inputs")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Delivery PkScript is either P2SH or P2PKH
|
// Delivery PkScript is either P2SH or P2PKH
|
||||||
err = ValidatePkScript(c.DeliveryPkScript)
|
err = ValidatePkScript(c.DeliveryPkScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Change PkScript is either P2SH or P2PKH
|
// Change PkScript is either P2SH or P2PKH
|
||||||
err = ValidatePkScript(c.ChangePkScript)
|
err = ValidatePkScript(c.ChangePkScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//Need to do this here
|
// Need to do this here
|
||||||
_ = copy(revocationHash[:], revocationHashBytes)
|
_ = copy(revocationHash[:], revocationHashBytes)
|
||||||
|
|
||||||
//funding response
|
// funding response
|
||||||
fundingResponse = &FundingResponse{
|
fundingResponse = &FundingResponse{
|
||||||
ChannelType: uint8(1),
|
ChannelType: uint8(1),
|
||||||
ReservationID: uint64(12345678),
|
ReservationID: uint64(12345678),
|
||||||
@ -17,7 +17,7 @@ var (
|
|||||||
ResponderReserveAmount: btcutil.Amount(131072),
|
ResponderReserveAmount: btcutil.Amount(131072),
|
||||||
MinFeePerKb: btcutil.Amount(20000),
|
MinFeePerKb: btcutil.Amount(20000),
|
||||||
MinDepth: uint32(6),
|
MinDepth: uint32(6),
|
||||||
LockTime: uint32(4320), //30 block-days
|
LockTime: uint32(4320), // 30 block-days
|
||||||
FeePayer: uint8(1),
|
FeePayer: uint8(1),
|
||||||
RevocationHash: revocationHash,
|
RevocationHash: revocationHash,
|
||||||
Pubkey: pubKey,
|
Pubkey: pubKey,
|
||||||
@ -31,19 +31,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestFundingResponseEncodeDecode(t *testing.T) {
|
func TestFundingResponseEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, fundingResponse, fundingResponseSerializedString, filename)
|
s := SerializeTest(t, fundingResponse, fundingResponseSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewFundingResponse()
|
newMessage := NewFundingResponse()
|
||||||
DeserializeTest(t, s, newMessage, fundingResponse)
|
DeserializeTest(t, s, newMessage, fundingResponse)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, fundingResponse, fundingResponseSerializedMessage)
|
MessageSerializeDeserializeTest(t, fundingResponse, fundingResponseSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -9,18 +9,18 @@ import (
|
|||||||
type FundingSignAccept struct {
|
type FundingSignAccept struct {
|
||||||
ReservationID uint64
|
ReservationID uint64
|
||||||
|
|
||||||
CommitSig *btcec.Signature //Requester's Commitment
|
CommitSig *btcec.Signature // Requester's Commitment
|
||||||
FundingTXSigs []*btcec.Signature
|
FundingTXSigs []*btcec.Signature
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FundingSignAccept) Decode(r io.Reader, pver uint32) error {
|
func (c *FundingSignAccept) Decode(r io.Reader, pver uint32) error {
|
||||||
//ReservationID (8)
|
// ReservationID (8)
|
||||||
//CommitSig (73)
|
// CommitSig (73)
|
||||||
// First byte length then sig
|
// First byte length then sig
|
||||||
//FundingTXSigs
|
// FundingTXSigs
|
||||||
// First byte is number of FundingTxSigs
|
// First byte is number of FundingTxSigs
|
||||||
// Sorted list of the requester's input signatures
|
// Sorted list of the requester's input signatures
|
||||||
// (originally provided in the Funding Request)
|
// (originally provided in the Funding Request)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ReservationID,
|
&c.ReservationID,
|
||||||
&c.CommitSig,
|
&c.CommitSig,
|
||||||
@ -32,17 +32,17 @@ func (c *FundingSignAccept) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new FundingSignAccept
|
// Creates a new FundingSignAccept
|
||||||
func NewFundingSignAccept() *FundingSignAccept {
|
func NewFundingSignAccept() *FundingSignAccept {
|
||||||
return &FundingSignAccept{}
|
return &FundingSignAccept{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the FundingSignAccept struct
|
// Serializes the item from the FundingSignAccept struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *FundingSignAccept) Encode(w io.Writer, pver uint32) error {
|
func (c *FundingSignAccept) Encode(w io.Writer, pver uint32) error {
|
||||||
//ReservationID
|
// ReservationID
|
||||||
//CommitSig
|
// CommitSig
|
||||||
//FundingTxSigs
|
// FundingTxSigs
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ReservationID,
|
c.ReservationID,
|
||||||
c.CommitSig,
|
c.CommitSig,
|
||||||
@ -59,13 +59,13 @@ func (c *FundingSignAccept) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *FundingSignAccept) MaxPayloadLength(uint32) uint32 {
|
func (c *FundingSignAccept) MaxPayloadLength(uint32) uint32 {
|
||||||
//8 (base size) + 73 + (73maxSigSize*127maxInputs)
|
// 8 (base size) + 73 + (73maxSigSize*127maxInputs)
|
||||||
return 9352
|
return 9352
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *FundingSignAccept) Validate() error {
|
func (c *FundingSignAccept) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//funding sign accept
|
// funding sign accept
|
||||||
fundingSignAccept = &FundingSignAccept{
|
fundingSignAccept = &FundingSignAccept{
|
||||||
ReservationID: uint64(12345678),
|
ReservationID: uint64(12345678),
|
||||||
CommitSig: commitSig,
|
CommitSig: commitSig,
|
||||||
@ -16,19 +16,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestFundingSignAcceptEncodeDecode(t *testing.T) {
|
func TestFundingSignAcceptEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, fundingSignAccept, fundingSignAcceptSerializedString, filename)
|
s := SerializeTest(t, fundingSignAccept, fundingSignAcceptSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewFundingSignAccept()
|
newMessage := NewFundingSignAccept()
|
||||||
DeserializeTest(t, s, newMessage, fundingSignAccept)
|
DeserializeTest(t, s, newMessage, fundingSignAccept)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, fundingSignAccept, fundingSignAcceptSerializedMessage)
|
MessageSerializeDeserializeTest(t, fundingSignAccept, fundingSignAcceptSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,12 @@ type FundingSignComplete struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *FundingSignComplete) Decode(r io.Reader, pver uint32) error {
|
func (c *FundingSignComplete) Decode(r io.Reader, pver uint32) error {
|
||||||
//ReservationID (8)
|
// ReservationID (8)
|
||||||
//TxID (32)
|
// TxID (32)
|
||||||
//FundingTXSigs
|
// FundingTXSigs
|
||||||
// First byte is number of FundingTxSigs
|
// First byte is number of FundingTxSigs
|
||||||
// Sorted list of the requester's input signatures
|
// Sorted list of the requester's input signatures
|
||||||
// (originally provided in the Funding Request)
|
// (originally provided in the Funding Request)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ReservationID,
|
&c.ReservationID,
|
||||||
&c.TxID,
|
&c.TxID,
|
||||||
@ -32,13 +32,13 @@ func (c *FundingSignComplete) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new FundingSignComplete
|
// Creates a new FundingSignComplete
|
||||||
func NewFundingSignComplete() *FundingSignComplete {
|
func NewFundingSignComplete() *FundingSignComplete {
|
||||||
return &FundingSignComplete{}
|
return &FundingSignComplete{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the FundingSignComplete struct
|
// Serializes the item from the FundingSignComplete struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *FundingSignComplete) Encode(w io.Writer, pver uint32) error {
|
func (c *FundingSignComplete) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ReservationID,
|
c.ReservationID,
|
||||||
@ -56,13 +56,13 @@ func (c *FundingSignComplete) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *FundingSignComplete) MaxPayloadLength(uint32) uint32 {
|
func (c *FundingSignComplete) MaxPayloadLength(uint32) uint32 {
|
||||||
//8 (base size) + 32 + (73maxSigSize*127maxInputs)
|
// 8 (base size) + 32 + (73maxSigSize*127maxInputs)
|
||||||
return 9311
|
return 9311
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *FundingSignComplete) Validate() error {
|
func (c *FundingSignComplete) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//funding response
|
// funding response
|
||||||
fundingSignComplete = &FundingSignComplete{
|
fundingSignComplete = &FundingSignComplete{
|
||||||
ReservationID: uint64(12345678),
|
ReservationID: uint64(12345678),
|
||||||
TxID: txid,
|
TxID: txid,
|
||||||
@ -16,19 +16,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestFundingSignCompleteEncodeDecode(t *testing.T) {
|
func TestFundingSignCompleteEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, fundingSignComplete, fundingSignCompleteSerializedString, filename)
|
s := SerializeTest(t, fundingSignComplete, fundingSignCompleteSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewFundingSignComplete()
|
newMessage := NewFundingSignComplete()
|
||||||
DeserializeTest(t, s, newMessage, fundingSignComplete)
|
DeserializeTest(t, s, newMessage, fundingSignComplete)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, fundingSignComplete, fundingSignCompleteSerializedMessage)
|
MessageSerializeDeserializeTest(t, fundingSignComplete, fundingSignCompleteSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ type HTLCAddAccept struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCAddAccept) Decode(r io.Reader, pver uint32) error {
|
func (c *HTLCAddAccept) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//HTLCKey(8)
|
// HTLCKey(8)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.HTLCKey,
|
&c.HTLCKey,
|
||||||
@ -24,13 +24,13 @@ func (c *HTLCAddAccept) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new HTLCAddAccept
|
// Creates a new HTLCAddAccept
|
||||||
func NewHTLCAddAccept() *HTLCAddAccept {
|
func NewHTLCAddAccept() *HTLCAddAccept {
|
||||||
return &HTLCAddAccept{}
|
return &HTLCAddAccept{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the HTLCAddAccept struct
|
// Serializes the item from the HTLCAddAccept struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *HTLCAddAccept) Encode(w io.Writer, pver uint32) error {
|
func (c *HTLCAddAccept) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -49,13 +49,13 @@ func (c *HTLCAddAccept) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCAddAccept) MaxPayloadLength(uint32) uint32 {
|
func (c *HTLCAddAccept) MaxPayloadLength(uint32) uint32 {
|
||||||
//16 base size
|
// 16 base size
|
||||||
return 16
|
return 16
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *HTLCAddAccept) Validate() error {
|
func (c *HTLCAddAccept) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestHTLCAddAcceptEncodeDecode(t *testing.T) {
|
func TestHTLCAddAcceptEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, htlcAddAccept, htlcAddAcceptSerializedString, filename)
|
s := SerializeTest(t, htlcAddAccept, htlcAddAcceptSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewHTLCAddAccept()
|
newMessage := NewHTLCAddAccept()
|
||||||
DeserializeTest(t, s, newMessage, htlcAddAccept)
|
DeserializeTest(t, s, newMessage, htlcAddAccept)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, htlcAddAccept, htlcAddAcceptSerializedMessage)
|
MessageSerializeDeserializeTest(t, htlcAddAccept, htlcAddAcceptSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ type HTLCAddReject struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCAddReject) Decode(r io.Reader, pver uint32) error {
|
func (c *HTLCAddReject) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//CommitmentHeight(8)
|
// CommitmentHeight(8)
|
||||||
//NextResponderCommitmentRevocationHash(20)
|
// NextResponderCommitmentRevocationHash(20)
|
||||||
//ResponderRevocationPreimage(20)
|
// ResponderRevocationPreimage(20)
|
||||||
//ResponderCommitSig(2+73max)
|
// ResponderCommitSig(2+73max)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.HTLCKey,
|
&c.HTLCKey,
|
||||||
@ -27,13 +27,13 @@ func (c *HTLCAddReject) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new HTLCAddReject
|
// Creates a new HTLCAddReject
|
||||||
func NewHTLCAddReject() *HTLCAddReject {
|
func NewHTLCAddReject() *HTLCAddReject {
|
||||||
return &HTLCAddReject{}
|
return &HTLCAddReject{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the HTLCAddReject struct
|
// Serializes the item from the HTLCAddReject struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *HTLCAddReject) Encode(w io.Writer, pver uint32) error {
|
func (c *HTLCAddReject) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -52,13 +52,13 @@ func (c *HTLCAddReject) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCAddReject) MaxPayloadLength(uint32) uint32 {
|
func (c *HTLCAddReject) MaxPayloadLength(uint32) uint32 {
|
||||||
//16 base size
|
// 16 base size
|
||||||
return 16
|
return 16
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *HTLCAddReject) Validate() error {
|
func (c *HTLCAddReject) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestHTLCAddRejectEncodeDecode(t *testing.T) {
|
func TestHTLCAddRejectEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, htlcAddReject, htlcAddRejectSerializedString, filename)
|
s := SerializeTest(t, htlcAddReject, htlcAddRejectSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewHTLCAddReject()
|
newMessage := NewHTLCAddReject()
|
||||||
DeserializeTest(t, s, newMessage, htlcAddReject)
|
DeserializeTest(t, s, newMessage, htlcAddReject)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, htlcAddReject, htlcAddRejectSerializedMessage)
|
MessageSerializeDeserializeTest(t, htlcAddReject, htlcAddRejectSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -5,46 +5,46 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Multiple Clearing Requests are possible by putting this inside an array of
|
// Multiple Clearing Requests are possible by putting this inside an array of
|
||||||
//clearing requests
|
// clearing requests
|
||||||
type HTLCAddRequest struct {
|
type HTLCAddRequest struct {
|
||||||
//We can use a different data type for this if necessary...
|
// We can use a different data type for this if necessary...
|
||||||
ChannelID uint64
|
ChannelID uint64
|
||||||
|
|
||||||
//ID of this request
|
// ID of this request
|
||||||
HTLCKey HTLCKey
|
HTLCKey HTLCKey
|
||||||
|
|
||||||
//When the HTLC expires
|
// When the HTLC expires
|
||||||
Expiry uint32
|
Expiry uint32
|
||||||
|
|
||||||
//Amount to pay in the hop
|
// Amount to pay in the hop
|
||||||
//Difference between hop and first item in blob is the fee to complete
|
// Difference between hop and first item in blob is the fee to complete
|
||||||
Amount CreditsAmount
|
Amount CreditsAmount
|
||||||
|
|
||||||
//RefundContext is for payment cancellation
|
// RefundContext is for payment cancellation
|
||||||
//TODO (j): not currently in use, add later
|
// TODO (j): not currently in use, add later
|
||||||
RefundContext HTLCKey
|
RefundContext HTLCKey
|
||||||
|
|
||||||
//Contract Type
|
// Contract Type
|
||||||
//first 4 bits is n, second for is m, in n-of-m "multisig"
|
// first 4 bits is n, second for is m, in n-of-m "multisig"
|
||||||
ContractType uint8
|
ContractType uint8
|
||||||
|
|
||||||
//Redemption Hashes
|
// Redemption Hashes
|
||||||
RedemptionHashes []*[20]byte
|
RedemptionHashes []*[20]byte
|
||||||
|
|
||||||
//Data to parse&pass on to the next node
|
// Data to parse&pass on to the next node
|
||||||
//Eventually, we need to make this into a group of 2 nested structs?
|
// Eventually, we need to make this into a group of 2 nested structs?
|
||||||
Blob []byte
|
Blob []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCAddRequest) Decode(r io.Reader, pver uint32) error {
|
func (c *HTLCAddRequest) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//HTLCKey(8)
|
// HTLCKey(8)
|
||||||
//Expiry(4)
|
// Expiry(4)
|
||||||
//Amount(4)
|
// Amount(4)
|
||||||
//ContractType(1)
|
// ContractType(1)
|
||||||
//RedemptionHashes (numOfHashes * 20 + numOfHashes)
|
// RedemptionHashes (numOfHashes * 20 + numOfHashes)
|
||||||
//Blob(2+blobsize)
|
// Blob(2+blobsize)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.HTLCKey,
|
&c.HTLCKey,
|
||||||
@ -61,13 +61,13 @@ func (c *HTLCAddRequest) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new HTLCAddRequest
|
// Creates a new HTLCAddRequest
|
||||||
func NewHTLCAddRequest() *HTLCAddRequest {
|
func NewHTLCAddRequest() *HTLCAddRequest {
|
||||||
return &HTLCAddRequest{}
|
return &HTLCAddRequest{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the HTLCAddRequest struct
|
// Serializes the item from the HTLCAddRequest struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *HTLCAddRequest) Encode(w io.Writer, pver uint32) error {
|
func (c *HTLCAddRequest) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -90,19 +90,19 @@ func (c *HTLCAddRequest) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCAddRequest) MaxPayloadLength(uint32) uint32 {
|
func (c *HTLCAddRequest) MaxPayloadLength(uint32) uint32 {
|
||||||
//base size ~110, but blob can be variable.
|
// base size ~110, but blob can be variable.
|
||||||
//shouldn't be bigger than 8K though...
|
// shouldn't be bigger than 8K though...
|
||||||
return 8192
|
return 8192
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *HTLCAddRequest) Validate() error {
|
func (c *HTLCAddRequest) Validate() error {
|
||||||
if c.Amount < 0 {
|
if c.Amount < 0 {
|
||||||
//While fees can be negative, it's too confusing to allow
|
// While fees can be negative, it's too confusing to allow
|
||||||
//negative payments. Maybe for some wallets, but not this one!
|
// negative payments. Maybe for some wallets, but not this one!
|
||||||
return fmt.Errorf("Amount paid cannot be negative.")
|
return fmt.Errorf("Amount paid cannot be negative.")
|
||||||
}
|
}
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//Need to to do this here
|
// Need to to do this here
|
||||||
_ = copy(revocationHash[:], revocationHashBytes)
|
_ = copy(revocationHash[:], revocationHashBytes)
|
||||||
_ = copy(redemptionHash[:], redemptionHashBytes)
|
_ = copy(redemptionHash[:], redemptionHashBytes)
|
||||||
emptyRedemptionHashes = []*[20]byte{}
|
emptyRedemptionHashes = []*[20]byte{}
|
||||||
@ -26,19 +26,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestHTLCAddRequestEncodeDecode(t *testing.T) {
|
func TestHTLCAddRequestEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, htlcAddRequest, htlcAddRequestSerializedString, filename)
|
s := SerializeTest(t, htlcAddRequest, htlcAddRequestSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewHTLCAddRequest()
|
newMessage := NewHTLCAddRequest()
|
||||||
DeserializeTest(t, s, newMessage, htlcAddRequest)
|
DeserializeTest(t, s, newMessage, htlcAddRequest)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, htlcAddRequest, htlcAddRequestSerializedMessage)
|
MessageSerializeDeserializeTest(t, htlcAddRequest, htlcAddRequestSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,19 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Multiple Clearing Requests are possible by putting this inside an array of
|
// Multiple Clearing Requests are possible by putting this inside an array of
|
||||||
//clearing requests
|
// clearing requests
|
||||||
type HTLCSettleAccept struct {
|
type HTLCSettleAccept struct {
|
||||||
//We can use a different data type for this if necessary...
|
// We can use a different data type for this if necessary...
|
||||||
ChannelID uint64
|
ChannelID uint64
|
||||||
|
|
||||||
//ID of this request
|
// ID of this request
|
||||||
HTLCKey HTLCKey
|
HTLCKey HTLCKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCSettleAccept) Decode(r io.Reader, pver uint32) error {
|
func (c *HTLCSettleAccept) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//HTLCKey(8)
|
// HTLCKey(8)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.HTLCKey,
|
&c.HTLCKey,
|
||||||
@ -29,13 +29,13 @@ func (c *HTLCSettleAccept) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new HTLCSettleAccept
|
// Creates a new HTLCSettleAccept
|
||||||
func NewHTLCSettleAccept() *HTLCSettleAccept {
|
func NewHTLCSettleAccept() *HTLCSettleAccept {
|
||||||
return &HTLCSettleAccept{}
|
return &HTLCSettleAccept{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the HTLCSettleAccept struct
|
// Serializes the item from the HTLCSettleAccept struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *HTLCSettleAccept) Encode(w io.Writer, pver uint32) error {
|
func (c *HTLCSettleAccept) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -53,13 +53,13 @@ func (c *HTLCSettleAccept) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCSettleAccept) MaxPayloadLength(uint32) uint32 {
|
func (c *HTLCSettleAccept) MaxPayloadLength(uint32) uint32 {
|
||||||
//16
|
// 16
|
||||||
return 16
|
return 16
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *HTLCSettleAccept) Validate() error {
|
func (c *HTLCSettleAccept) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestHTLCSettleAcceptEncodeDecode(t *testing.T) {
|
func TestHTLCSettleAcceptEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, htlcSettleAccept, htlcSettleAcceptSerializedString, filename)
|
s := SerializeTest(t, htlcSettleAccept, htlcSettleAcceptSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewHTLCSettleAccept()
|
newMessage := NewHTLCSettleAccept()
|
||||||
DeserializeTest(t, s, newMessage, htlcSettleAccept)
|
DeserializeTest(t, s, newMessage, htlcSettleAccept)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, htlcSettleAccept, htlcSettleAcceptSerializedMessage)
|
MessageSerializeDeserializeTest(t, htlcSettleAccept, htlcSettleAcceptSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -5,28 +5,28 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Multiple Clearing Requests are possible by putting this inside an array of
|
// Multiple Clearing Requests are possible by putting this inside an array of
|
||||||
//clearing requests
|
// clearing requests
|
||||||
type HTLCSettleRequest struct {
|
type HTLCSettleRequest struct {
|
||||||
//We can use a different data type for this if necessary...
|
// We can use a different data type for this if necessary...
|
||||||
ChannelID uint64
|
ChannelID uint64
|
||||||
|
|
||||||
//ID of this request
|
// ID of this request
|
||||||
HTLCKey HTLCKey
|
HTLCKey HTLCKey
|
||||||
|
|
||||||
//Redemption Proofs (R-Values)
|
// Redemption Proofs (R-Values)
|
||||||
RedemptionProofs []*[20]byte
|
RedemptionProofs []*[20]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCSettleRequest) Decode(r io.Reader, pver uint32) error {
|
func (c *HTLCSettleRequest) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//HTLCKey(8)
|
// HTLCKey(8)
|
||||||
//Expiry(4)
|
// Expiry(4)
|
||||||
//Amount(4)
|
// Amount(4)
|
||||||
//NextHop(20)
|
// NextHop(20)
|
||||||
//ContractType(1)
|
// ContractType(1)
|
||||||
//RedemptionHashes (numOfHashes * 20 + numOfHashes)
|
// RedemptionHashes (numOfHashes * 20 + numOfHashes)
|
||||||
//Blob(2+blobsize)
|
// Blob(2+blobsize)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.HTLCKey,
|
&c.HTLCKey,
|
||||||
@ -39,13 +39,13 @@ func (c *HTLCSettleRequest) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new HTLCSettleRequest
|
// Creates a new HTLCSettleRequest
|
||||||
func NewHTLCSettleRequest() *HTLCSettleRequest {
|
func NewHTLCSettleRequest() *HTLCSettleRequest {
|
||||||
return &HTLCSettleRequest{}
|
return &HTLCSettleRequest{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the HTLCSettleRequest struct
|
// Serializes the item from the HTLCSettleRequest struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *HTLCSettleRequest) Encode(w io.Writer, pver uint32) error {
|
func (c *HTLCSettleRequest) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -64,13 +64,13 @@ func (c *HTLCSettleRequest) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCSettleRequest) MaxPayloadLength(uint32) uint32 {
|
func (c *HTLCSettleRequest) MaxPayloadLength(uint32) uint32 {
|
||||||
//21*15+16
|
// 21*15+16
|
||||||
return 331
|
return 331
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *HTLCSettleRequest) Validate() error {
|
func (c *HTLCSettleRequest) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//Need to to do this here
|
// Need to to do this here
|
||||||
_ = copy(redemptionHash[:], redemptionHashBytes)
|
_ = copy(redemptionHash[:], redemptionHashBytes)
|
||||||
emptyRedemptionProofs = []*[20]byte{}
|
emptyRedemptionProofs = []*[20]byte{}
|
||||||
redemptionProofs = append(emptyRedemptionProofs, &redemptionHash)
|
redemptionProofs = append(emptyRedemptionProofs, &redemptionHash)
|
||||||
@ -20,19 +20,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestHTLCSettleRequestEncodeDecode(t *testing.T) {
|
func TestHTLCSettleRequestEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, htlcSettleRequest, htlcSettleRequestSerializedString, filename)
|
s := SerializeTest(t, htlcSettleRequest, htlcSettleRequestSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewHTLCSettleRequest()
|
newMessage := NewHTLCSettleRequest()
|
||||||
DeserializeTest(t, s, newMessage, htlcSettleRequest)
|
DeserializeTest(t, s, newMessage, htlcSettleRequest)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, htlcSettleRequest, htlcSettleRequestSerializedMessage)
|
MessageSerializeDeserializeTest(t, htlcSettleRequest, htlcSettleRequestSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,19 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Multiple Clearing Requests are possible by putting this inside an array of
|
// Multiple Clearing Requests are possible by putting this inside an array of
|
||||||
//clearing requests
|
// clearing requests
|
||||||
type HTLCTimeoutAccept struct {
|
type HTLCTimeoutAccept struct {
|
||||||
//We can use a different data type for this if necessary...
|
// We can use a different data type for this if necessary...
|
||||||
ChannelID uint64
|
ChannelID uint64
|
||||||
|
|
||||||
//ID of this request
|
// ID of this request
|
||||||
HTLCKey HTLCKey
|
HTLCKey HTLCKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCTimeoutAccept) Decode(r io.Reader, pver uint32) error {
|
func (c *HTLCTimeoutAccept) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//HTLCKey(8)
|
// HTLCKey(8)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.HTLCKey,
|
&c.HTLCKey,
|
||||||
@ -29,13 +29,13 @@ func (c *HTLCTimeoutAccept) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new HTLCTimeoutAccept
|
// Creates a new HTLCTimeoutAccept
|
||||||
func NewHTLCTimeoutAccept() *HTLCTimeoutAccept {
|
func NewHTLCTimeoutAccept() *HTLCTimeoutAccept {
|
||||||
return &HTLCTimeoutAccept{}
|
return &HTLCTimeoutAccept{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the HTLCTimeoutAccept struct
|
// Serializes the item from the HTLCTimeoutAccept struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *HTLCTimeoutAccept) Encode(w io.Writer, pver uint32) error {
|
func (c *HTLCTimeoutAccept) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -53,13 +53,13 @@ func (c *HTLCTimeoutAccept) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCTimeoutAccept) MaxPayloadLength(uint32) uint32 {
|
func (c *HTLCTimeoutAccept) MaxPayloadLength(uint32) uint32 {
|
||||||
//16
|
// 16
|
||||||
return 16
|
return 16
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *HTLCTimeoutAccept) Validate() error {
|
func (c *HTLCTimeoutAccept) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestHTLCTimeoutAcceptEncodeDecode(t *testing.T) {
|
func TestHTLCTimeoutAcceptEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, htlcTimeoutAccept, htlcTimeoutAcceptSerializedString, filename)
|
s := SerializeTest(t, htlcTimeoutAccept, htlcTimeoutAcceptSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewHTLCTimeoutAccept()
|
newMessage := NewHTLCTimeoutAccept()
|
||||||
DeserializeTest(t, s, newMessage, htlcTimeoutAccept)
|
DeserializeTest(t, s, newMessage, htlcTimeoutAccept)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, htlcTimeoutAccept, htlcTimeoutAcceptSerializedMessage)
|
MessageSerializeDeserializeTest(t, htlcTimeoutAccept, htlcTimeoutAcceptSerializedMessage)
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,19 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Multiple Clearing Requests are possible by putting this inside an array of
|
// Multiple Clearing Requests are possible by putting this inside an array of
|
||||||
//clearing requests
|
// clearing requests
|
||||||
type HTLCTimeoutRequest struct {
|
type HTLCTimeoutRequest struct {
|
||||||
//We can use a different data type for this if necessary...
|
// We can use a different data type for this if necessary...
|
||||||
ChannelID uint64
|
ChannelID uint64
|
||||||
|
|
||||||
//ID of this request
|
// ID of this request
|
||||||
HTLCKey HTLCKey
|
HTLCKey HTLCKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCTimeoutRequest) Decode(r io.Reader, pver uint32) error {
|
func (c *HTLCTimeoutRequest) Decode(r io.Reader, pver uint32) error {
|
||||||
//ChannelID(8)
|
// ChannelID(8)
|
||||||
//HTLCKey(8)
|
// HTLCKey(8)
|
||||||
err := readElements(r,
|
err := readElements(r,
|
||||||
&c.ChannelID,
|
&c.ChannelID,
|
||||||
&c.HTLCKey,
|
&c.HTLCKey,
|
||||||
@ -29,13 +29,13 @@ func (c *HTLCTimeoutRequest) Decode(r io.Reader, pver uint32) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new HTLCTimeoutRequest
|
// Creates a new HTLCTimeoutRequest
|
||||||
func NewHTLCTimeoutRequest() *HTLCTimeoutRequest {
|
func NewHTLCTimeoutRequest() *HTLCTimeoutRequest {
|
||||||
return &HTLCTimeoutRequest{}
|
return &HTLCTimeoutRequest{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serializes the item from the HTLCTimeoutRequest struct
|
// Serializes the item from the HTLCTimeoutRequest struct
|
||||||
//Writes the data to w
|
// Writes the data to w
|
||||||
func (c *HTLCTimeoutRequest) Encode(w io.Writer, pver uint32) error {
|
func (c *HTLCTimeoutRequest) Encode(w io.Writer, pver uint32) error {
|
||||||
err := writeElements(w,
|
err := writeElements(w,
|
||||||
c.ChannelID,
|
c.ChannelID,
|
||||||
@ -53,13 +53,13 @@ func (c *HTLCTimeoutRequest) Command() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTLCTimeoutRequest) MaxPayloadLength(uint32) uint32 {
|
func (c *HTLCTimeoutRequest) MaxPayloadLength(uint32) uint32 {
|
||||||
//16
|
// 16
|
||||||
return 16
|
return 16
|
||||||
}
|
}
|
||||||
|
|
||||||
//Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
// Makes sure the struct data is valid (e.g. no negatives or invalid pkscripts)
|
||||||
func (c *HTLCTimeoutRequest) Validate() error {
|
func (c *HTLCTimeoutRequest) Validate() error {
|
||||||
//We're good!
|
// We're good!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestHTLCTimeoutRequestEncodeDecode(t *testing.T) {
|
func TestHTLCTimeoutRequestEncodeDecode(t *testing.T) {
|
||||||
//All of these types being passed are of the message interface type
|
// All of these types being passed are of the message interface type
|
||||||
//Test serialization, runs: message.Encode(b, 0)
|
// Test serialization, runs: message.Encode(b, 0)
|
||||||
//Returns bytes
|
// Returns bytes
|
||||||
//Compares the expected serialized string from the original
|
// Compares the expected serialized string from the original
|
||||||
s := SerializeTest(t, htlcTimeoutRequest, htlcTimeoutRequestSerializedString, filename)
|
s := SerializeTest(t, htlcTimeoutRequest, htlcTimeoutRequestSerializedString, filename)
|
||||||
|
|
||||||
//Test deserialization, runs: message.Decode(s, 0)
|
// Test deserialization, runs: message.Decode(s, 0)
|
||||||
//Makes sure the deserialized struct is the same as the original
|
// Makes sure the deserialized struct is the same as the original
|
||||||
newMessage := NewHTLCTimeoutRequest()
|
newMessage := NewHTLCTimeoutRequest()
|
||||||
DeserializeTest(t, s, newMessage, htlcTimeoutRequest)
|
DeserializeTest(t, s, newMessage, htlcTimeoutRequest)
|
||||||
|
|
||||||
//Test message using Message interface
|
// Test message using Message interface
|
||||||
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
|
||||||
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
|
||||||
MessageSerializeDeserializeTest(t, htlcTimeoutRequest, htlcTimeoutRequestSerializedMessage)
|
MessageSerializeDeserializeTest(t, htlcTimeoutRequest, htlcTimeoutRequestSerializedMessage)
|
||||||
}
|
}
|
||||||
|
140
lnwire/lnwire.go
140
lnwire/lnwire.go
@ -13,31 +13,31 @@ import (
|
|||||||
|
|
||||||
var MAX_SLICE_LENGTH = 65535
|
var MAX_SLICE_LENGTH = 65535
|
||||||
|
|
||||||
//Actual pkScript, not redeemScript
|
// Actual pkScript, not redeemScript
|
||||||
type PkScript []byte
|
type PkScript []byte
|
||||||
|
|
||||||
type HTLCKey uint64
|
type HTLCKey uint64
|
||||||
type CommitHeight uint64
|
type CommitHeight uint64
|
||||||
|
|
||||||
//Subsatoshi amount (Micro-Satoshi, 1/1000th)
|
// Subsatoshi amount (Micro-Satoshi, 1/1000th)
|
||||||
//Should be a signed int to account for negative fees
|
// Should be a signed int to account for negative fees
|
||||||
//
|
//
|
||||||
//"In any science-fiction movie, anywhere in the galaxy, currency is referred
|
// "In any science-fiction movie, anywhere in the galaxy, currency is referred
|
||||||
//to as 'credits.'"
|
// to as 'credits.'"
|
||||||
// --Sam Humphries. Ebert, Roger (1999). Ebert's bigger little movie
|
// --Sam Humphries. Ebert, Roger (1999). Ebert's bigger little movie
|
||||||
// glossary. Andrews McMeel. p. 172.
|
// glossary. Andrews McMeel. p. 172.
|
||||||
//
|
//
|
||||||
//https://en.wikipedia.org/wiki/List_of_fictional_currencies
|
// https:// en.wikipedia.org/wiki/List_of_fictional_currencies
|
||||||
//https://en.wikipedia.org/wiki/Fictional_currency#Trends_in_the_use_of_fictional_currencies
|
// https:// en.wikipedia.org/wiki/Fictional_currency#Trends_in_the_use_of_fictional_currencies
|
||||||
//http://tvtropes.org/pmwiki/pmwiki.php/Main/WeWillSpendCreditsInTheFuture
|
// http:// tvtropes.org/pmwiki/pmwiki.php/Main/WeWillSpendCreditsInTheFuture
|
||||||
type CreditsAmount int32 //Credits (XCB, accountants should use XCB :^)
|
type CreditsAmount int32 // Credits (XCB, accountants should use XCB :^)
|
||||||
//US Display format: 1 BTC = 100,000,000'000 XCB
|
// US Display format: 1 BTC = 100,000,000'000 XCB
|
||||||
//Or in BTC = 1.00000000'000
|
// Or in BTC = 1.00000000'000
|
||||||
|
|
||||||
//Writes the big endian representation of element
|
// Writes the big endian representation of element
|
||||||
//Unified function to call when writing different types
|
// Unified function to call when writing different types
|
||||||
//Pre-allocate a byte-array of the correct size for cargo-cult security
|
// Pre-allocate a byte-array of the correct size for cargo-cult security
|
||||||
//More copies but whatever...
|
// More copies but whatever...
|
||||||
func writeElement(w io.Writer, element interface{}) error {
|
func writeElement(w io.Writer, element interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
switch e := element.(type) {
|
switch e := element.(type) {
|
||||||
@ -107,12 +107,12 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
if numItems > 65535 {
|
if numItems > 65535 {
|
||||||
return fmt.Errorf("Too many []uint64s")
|
return fmt.Errorf("Too many []uint64s")
|
||||||
}
|
}
|
||||||
//Write the size
|
// Write the size
|
||||||
err = writeElement(w, uint16(numItems))
|
err = writeElement(w, uint16(numItems))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Write the data
|
// Write the data
|
||||||
for i := 0; i < numItems; i++ {
|
for i := 0; i < numItems; i++ {
|
||||||
err = writeElement(w, e[i])
|
err = writeElement(w, e[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -125,12 +125,12 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
if numSigs > 127 {
|
if numSigs > 127 {
|
||||||
return fmt.Errorf("Too many signatures!")
|
return fmt.Errorf("Too many signatures!")
|
||||||
}
|
}
|
||||||
//Write the size
|
// Write the size
|
||||||
err = writeElement(w, uint8(numSigs))
|
err = writeElement(w, uint8(numSigs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Write the data
|
// Write the data
|
||||||
for i := 0; i < numSigs; i++ {
|
for i := 0; i < numSigs; i++ {
|
||||||
err = writeElement(w, e[i])
|
err = writeElement(w, e[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -144,12 +144,12 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
if sigLength > 73 {
|
if sigLength > 73 {
|
||||||
return fmt.Errorf("Signature too long!")
|
return fmt.Errorf("Signature too long!")
|
||||||
}
|
}
|
||||||
//Write the size
|
// Write the size
|
||||||
err = writeElement(w, uint8(sigLength))
|
err = writeElement(w, uint8(sigLength))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Write the data
|
// Write the data
|
||||||
_, err = w.Write(sig)
|
_, err = w.Write(sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -162,13 +162,13 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case []*[20]byte:
|
case []*[20]byte:
|
||||||
//Get size of slice and dump in slice
|
// Get size of slice and dump in slice
|
||||||
sliceSize := len(e)
|
sliceSize := len(e)
|
||||||
err = writeElement(w, uint16(sliceSize))
|
err = writeElement(w, uint16(sliceSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Write in each sequentially
|
// Write in each sequentially
|
||||||
for _, element := range e {
|
for _, element := range e {
|
||||||
err = writeElement(w, &element)
|
err = writeElement(w, &element)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -200,12 +200,12 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
if sliceLength > MAX_SLICE_LENGTH {
|
if sliceLength > MAX_SLICE_LENGTH {
|
||||||
return fmt.Errorf("Slice length too long!")
|
return fmt.Errorf("Slice length too long!")
|
||||||
}
|
}
|
||||||
//Write the size
|
// Write the size
|
||||||
err = writeElement(w, uint16(sliceLength))
|
err = writeElement(w, uint16(sliceLength))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Write the data
|
// Write the data
|
||||||
_, err = w.Write(e)
|
_, err = w.Write(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -213,16 +213,16 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
case PkScript:
|
case PkScript:
|
||||||
scriptLength := len(e)
|
scriptLength := len(e)
|
||||||
//Make sure it's P2PKH or P2SH size or less
|
// Make sure it's P2PKH or P2SH size or less
|
||||||
if scriptLength > 25 {
|
if scriptLength > 25 {
|
||||||
return fmt.Errorf("PkScript too long!")
|
return fmt.Errorf("PkScript too long!")
|
||||||
}
|
}
|
||||||
//Write the size (1-byte)
|
// Write the size (1-byte)
|
||||||
err = writeElement(w, uint8(scriptLength))
|
err = writeElement(w, uint8(scriptLength))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Write the data
|
// Write the data
|
||||||
_, err = w.Write(e)
|
_, err = w.Write(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -233,19 +233,19 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
if strlen > 65535 {
|
if strlen > 65535 {
|
||||||
return fmt.Errorf("String too long!")
|
return fmt.Errorf("String too long!")
|
||||||
}
|
}
|
||||||
//Write the size (2-bytes)
|
// Write the size (2-bytes)
|
||||||
err = writeElement(w, uint16(strlen))
|
err = writeElement(w, uint16(strlen))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Write the data
|
// Write the data
|
||||||
_, err = w.Write([]byte(e))
|
_, err = w.Write([]byte(e))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case []*wire.TxIn:
|
case []*wire.TxIn:
|
||||||
//Append the unsigned(!!!) txins
|
// Append the unsigned(!!!) txins
|
||||||
//Write the size (1-byte)
|
// Write the size (1-byte)
|
||||||
if len(e) > 127 {
|
if len(e) > 127 {
|
||||||
return fmt.Errorf("Too many txins")
|
return fmt.Errorf("Too many txins")
|
||||||
}
|
}
|
||||||
@ -253,8 +253,8 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Append the actual TxIns (Size: NumOfTxins * 36)
|
// Append the actual TxIns (Size: NumOfTxins * 36)
|
||||||
//Do not include the sequence number to eliminate funny business
|
// Do not include the sequence number to eliminate funny business
|
||||||
for _, in := range e {
|
for _, in := range e {
|
||||||
err = writeElement(w, in)
|
err = writeElement(w, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -263,14 +263,14 @@ func writeElement(w io.Writer, element interface{}) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case *wire.TxIn:
|
case *wire.TxIn:
|
||||||
//Hash
|
// Hash
|
||||||
var h [32]byte
|
var h [32]byte
|
||||||
copy(h[:], e.PreviousOutPoint.Hash.Bytes())
|
copy(h[:], e.PreviousOutPoint.Hash.Bytes())
|
||||||
_, err = w.Write(h[:])
|
_, err = w.Write(h[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Index
|
// Index
|
||||||
var idx [4]byte
|
var idx [4]byte
|
||||||
binary.BigEndian.PutUint32(idx[:], e.PreviousOutPoint.Index)
|
binary.BigEndian.PutUint32(idx[:], e.PreviousOutPoint.Index)
|
||||||
_, err = w.Write(idx[:])
|
_, err = w.Write(idx[:])
|
||||||
@ -381,11 +381,11 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//if numItems > 65535 {
|
// if numItems > 65535 {
|
||||||
// return fmt.Errorf("Too many items in []uint64")
|
// return fmt.Errorf("Too many items in []uint64")
|
||||||
//}
|
// }
|
||||||
|
|
||||||
//Read the number of items
|
// Read the number of items
|
||||||
var items []uint64
|
var items []uint64
|
||||||
for i := uint16(0); i < numItems; i++ {
|
for i := uint16(0); i < numItems; i++ {
|
||||||
var item uint64
|
var item uint64
|
||||||
@ -407,7 +407,7 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
return fmt.Errorf("Too many signatures!")
|
return fmt.Errorf("Too many signatures!")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read that number of signatures
|
// Read that number of signatures
|
||||||
var sigs []*btcec.Signature
|
var sigs []*btcec.Signature
|
||||||
for i := uint8(0); i < numSigs; i++ {
|
for i := uint8(0); i < numSigs; i++ {
|
||||||
sig := new(btcec.Signature)
|
sig := new(btcec.Signature)
|
||||||
@ -430,7 +430,7 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
return fmt.Errorf("Signature too long!")
|
return fmt.Errorf("Signature too long!")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read the sig length
|
// Read the sig length
|
||||||
l := io.LimitReader(r, int64(sigLength))
|
l := io.LimitReader(r, int64(sigLength))
|
||||||
sig, err := ioutil.ReadAll(l)
|
sig, err := ioutil.ReadAll(l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -446,14 +446,14 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
*e = &*btcecSig
|
*e = &*btcecSig
|
||||||
return nil
|
return nil
|
||||||
case *[]*[20]byte:
|
case *[]*[20]byte:
|
||||||
//How many to read
|
// How many to read
|
||||||
var sliceSize uint16
|
var sliceSize uint16
|
||||||
err = readElement(r, &sliceSize)
|
err = readElement(r, &sliceSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var data []*[20]byte
|
var data []*[20]byte
|
||||||
//Append the actual
|
// Append the actual
|
||||||
for i := uint16(0); i < sliceSize; i++ {
|
for i := uint16(0); i < sliceSize; i++ {
|
||||||
var element [20]byte
|
var element [20]byte
|
||||||
err = readElement(r, &element)
|
err = readElement(r, &element)
|
||||||
@ -479,20 +479,20 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
*e = wire.BitcoinNet(binary.BigEndian.Uint32(b[:]))
|
*e = wire.BitcoinNet(binary.BigEndian.Uint32(b[:]))
|
||||||
return nil
|
return nil
|
||||||
case *[]byte:
|
case *[]byte:
|
||||||
//Get the blob length first
|
// Get the blob length first
|
||||||
var blobLength uint16
|
var blobLength uint16
|
||||||
err = readElement(r, &blobLength)
|
err = readElement(r, &blobLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Shouldn't need to do this, since it's uint16, but we
|
// Shouldn't need to do this, since it's uint16, but we
|
||||||
//might have a different value for MAX_SLICE_LENGTH...
|
// might have a different value for MAX_SLICE_LENGTH...
|
||||||
if int(blobLength) > MAX_SLICE_LENGTH {
|
if int(blobLength) > MAX_SLICE_LENGTH {
|
||||||
return fmt.Errorf("Slice length too long!")
|
return fmt.Errorf("Slice length too long!")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read the slice length
|
// Read the slice length
|
||||||
l := io.LimitReader(r, int64(blobLength))
|
l := io.LimitReader(r, int64(blobLength))
|
||||||
*e, err = ioutil.ReadAll(l)
|
*e, err = ioutil.ReadAll(l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -503,7 +503,7 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case *PkScript:
|
case *PkScript:
|
||||||
//Get the script length first
|
// Get the script length first
|
||||||
var scriptLength uint8
|
var scriptLength uint8
|
||||||
err = readElement(r, &scriptLength)
|
err = readElement(r, &scriptLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -514,7 +514,7 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
return fmt.Errorf("PkScript too long!")
|
return fmt.Errorf("PkScript too long!")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read the script length
|
// Read the script length
|
||||||
l := io.LimitReader(r, int64(scriptLength))
|
l := io.LimitReader(r, int64(scriptLength))
|
||||||
*e, err = ioutil.ReadAll(l)
|
*e, err = ioutil.ReadAll(l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -525,13 +525,13 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case *string:
|
case *string:
|
||||||
//Get the string length first
|
// Get the string length first
|
||||||
var strlen uint16
|
var strlen uint16
|
||||||
err = readElement(r, &strlen)
|
err = readElement(r, &strlen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//Read the string for the length
|
// Read the string for the length
|
||||||
l := io.LimitReader(r, int64(strlen))
|
l := io.LimitReader(r, int64(strlen))
|
||||||
b, err := ioutil.ReadAll(l)
|
b, err := ioutil.ReadAll(l)
|
||||||
if len(b) != int(strlen) {
|
if len(b) != int(strlen) {
|
||||||
@ -543,7 +543,7 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case *[]*wire.TxIn:
|
case *[]*wire.TxIn:
|
||||||
//Read the size (1-byte number of txins)
|
// Read the size (1-byte number of txins)
|
||||||
var numScripts uint8
|
var numScripts uint8
|
||||||
err = readElement(r, &numScripts)
|
err = readElement(r, &numScripts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -553,7 +553,7 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
return fmt.Errorf("Too many txins")
|
return fmt.Errorf("Too many txins")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Append the actual TxIns
|
// Append the actual TxIns
|
||||||
var txins []*wire.TxIn
|
var txins []*wire.TxIn
|
||||||
for i := uint8(0); i < numScripts; i++ {
|
for i := uint8(0); i < numScripts; i++ {
|
||||||
outpoint := new(wire.OutPoint)
|
outpoint := new(wire.OutPoint)
|
||||||
@ -567,7 +567,7 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
*e = *&txins
|
*e = *&txins
|
||||||
return nil
|
return nil
|
||||||
case **wire.TxIn:
|
case **wire.TxIn:
|
||||||
//Hash
|
// Hash
|
||||||
var h [32]byte
|
var h [32]byte
|
||||||
_, err = io.ReadFull(r, h[:])
|
_, err = io.ReadFull(r, h[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -578,7 +578,7 @@ func readElement(r io.Reader, element interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
(*e).PreviousOutPoint.Hash = *hash
|
(*e).PreviousOutPoint.Hash = *hash
|
||||||
//Index
|
// Index
|
||||||
var idxBytes [4]byte
|
var idxBytes [4]byte
|
||||||
_, err = io.ReadFull(r, idxBytes[:])
|
_, err = io.ReadFull(r, idxBytes[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -603,31 +603,31 @@ func readElements(r io.Reader, elements ...interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Validates whether a PkScript byte array is P2SH or P2PKH
|
// Validates whether a PkScript byte array is P2SH or P2PKH
|
||||||
func ValidatePkScript(pkScript PkScript) error {
|
func ValidatePkScript(pkScript PkScript) error {
|
||||||
if &pkScript == nil {
|
if &pkScript == nil {
|
||||||
return fmt.Errorf("PkScript should not be empty!")
|
return fmt.Errorf("PkScript should not be empty!")
|
||||||
}
|
}
|
||||||
if len(pkScript) == 25 {
|
if len(pkScript) == 25 {
|
||||||
//P2PKH
|
// P2PKH
|
||||||
//Begins with OP_DUP OP_HASH160 PUSHDATA(20)
|
// Begins with OP_DUP OP_HASH160 PUSHDATA(20)
|
||||||
if !bytes.Equal(pkScript[0:3], []byte{118, 169, 20}) ||
|
if !bytes.Equal(pkScript[0:3], []byte{118, 169, 20}) ||
|
||||||
//Ends with OP_EQUALVERIFY OP_CHECKSIG
|
// Ends with OP_EQUALVERIFY OP_CHECKSIG
|
||||||
!bytes.Equal(pkScript[23:25], []byte{136, 172}) {
|
!bytes.Equal(pkScript[23:25], []byte{136, 172}) {
|
||||||
//If it's not correct, return error
|
// If it's not correct, return error
|
||||||
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
|
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
|
||||||
}
|
}
|
||||||
} else if len(pkScript) == 23 {
|
} else if len(pkScript) == 23 {
|
||||||
//P2SH
|
// P2SH
|
||||||
//Begins with OP_HASH160 PUSHDATA(20)
|
// Begins with OP_HASH160 PUSHDATA(20)
|
||||||
if !bytes.Equal(pkScript[0:2], []byte{169, 20}) ||
|
if !bytes.Equal(pkScript[0:2], []byte{169, 20}) ||
|
||||||
//Ends with OP_EQUAL
|
// Ends with OP_EQUAL
|
||||||
!bytes.Equal(pkScript[22:23], []byte{135}) {
|
!bytes.Equal(pkScript[22:23], []byte{135}) {
|
||||||
//If it's not correct, return error
|
// If it's not correct, return error
|
||||||
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
|
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Length not 23 or 25
|
// Length not 23 or 25
|
||||||
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
|
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,24 +11,24 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Common variables and functions for the message tests
|
// Common variables and functions for the message tests
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//For debugging, writes to /dev/shm/
|
// For debugging, writes to /dev/shm/
|
||||||
//Maybe in the future do it if you do "go test -v"
|
// Maybe in the future do it if you do "go test -v"
|
||||||
WRITE_FILE = true
|
WRITE_FILE = true
|
||||||
filename = "/dev/shm/serialized.raw"
|
filename = "/dev/shm/serialized.raw"
|
||||||
|
|
||||||
//preimage: 9a2cbd088763db88dd8ba79e5726daa6aba4aa7e
|
// preimage: 9a2cbd088763db88dd8ba79e5726daa6aba4aa7e
|
||||||
//echo -n | openssl sha256 | openssl ripemd160 | openssl sha256 | openssl ripemd160
|
// echo -n | openssl sha256 | openssl ripemd160 | openssl sha256 | openssl ripemd160
|
||||||
revocationHashBytes, _ = hex.DecodeString("4132b6b48371f7b022a16eacb9b2b0ebee134d41")
|
revocationHashBytes, _ = hex.DecodeString("4132b6b48371f7b022a16eacb9b2b0ebee134d41")
|
||||||
revocationHash [20]byte
|
revocationHash [20]byte
|
||||||
|
|
||||||
//preimage: "hello world"
|
// preimage: "hello world"
|
||||||
redemptionHashBytes, _ = hex.DecodeString("5b315ebabb0d8c0d94281caa2dfee69a1a00436e")
|
redemptionHashBytes, _ = hex.DecodeString("5b315ebabb0d8c0d94281caa2dfee69a1a00436e")
|
||||||
redemptionHash [20]byte
|
redemptionHash [20]byte
|
||||||
|
|
||||||
//preimage: "next hop"
|
// preimage: "next hop"
|
||||||
nextHopBytes, _ = hex.DecodeString("94a9ded5a30fc5944cb1e2cbcd980f30616a1440")
|
nextHopBytes, _ = hex.DecodeString("94a9ded5a30fc5944cb1e2cbcd980f30616a1440")
|
||||||
nextHop [20]byte
|
nextHop [20]byte
|
||||||
|
|
||||||
@ -36,51 +36,51 @@ var (
|
|||||||
privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
|
privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
|
||||||
address = pubKey
|
address = pubKey
|
||||||
|
|
||||||
// Delivery PkScript
|
// Delivery PkScript
|
||||||
//Privkey: f2c00ead9cbcfec63098dc0a5f152c0165aff40a2ab92feb4e24869a284c32a7
|
// Privkey: f2c00ead9cbcfec63098dc0a5f152c0165aff40a2ab92feb4e24869a284c32a7
|
||||||
//PKhash: n2fkWVphUzw3zSigzPsv9GuDyg9mohzKpz
|
// PKhash: n2fkWVphUzw3zSigzPsv9GuDyg9mohzKpz
|
||||||
deliveryPkScript, _ = hex.DecodeString("76a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac")
|
deliveryPkScript, _ = hex.DecodeString("76a914e8048c0fb75bdecc91ebfb99c174f4ece29ffbd488ac")
|
||||||
|
|
||||||
// Change PkScript
|
// Change PkScript
|
||||||
//Privkey: 5b18f5049efd9d3aff1fb9a06506c0b809fb71562b6ecd02f6c5b3ab298f3b0f
|
// Privkey: 5b18f5049efd9d3aff1fb9a06506c0b809fb71562b6ecd02f6c5b3ab298f3b0f
|
||||||
//PKhash: miky84cHvLuk6jcT6GsSbgHR8d7eZCu9Qc
|
// PKhash: miky84cHvLuk6jcT6GsSbgHR8d7eZCu9Qc
|
||||||
changePkScript, _ = hex.DecodeString("76a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac")
|
changePkScript, _ = hex.DecodeString("76a914238ee44bb5c8c1314dd03974a17ec6c406fdcb8388ac")
|
||||||
|
|
||||||
//echo -n | openssl sha256
|
// echo -n | openssl sha256
|
||||||
//This stuff gets reversed!!!
|
// This stuff gets reversed!!!
|
||||||
shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
|
shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
|
||||||
shaHash1, _ = wire.NewShaHash(shaHash1Bytes)
|
shaHash1, _ = wire.NewShaHash(shaHash1Bytes)
|
||||||
outpoint1 = wire.NewOutPoint(shaHash1, 0)
|
outpoint1 = wire.NewOutPoint(shaHash1, 0)
|
||||||
//echo | openssl sha256
|
// echo | openssl sha256
|
||||||
//This stuff gets reversed!!!
|
// This stuff gets reversed!!!
|
||||||
shaHash2Bytes, _ = hex.DecodeString("01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b")
|
shaHash2Bytes, _ = hex.DecodeString("01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b")
|
||||||
shaHash2, _ = wire.NewShaHash(shaHash2Bytes)
|
shaHash2, _ = wire.NewShaHash(shaHash2Bytes)
|
||||||
outpoint2 = wire.NewOutPoint(shaHash2, 1)
|
outpoint2 = wire.NewOutPoint(shaHash2, 1)
|
||||||
//create inputs from outpoint1 and outpoint2
|
// create inputs from outpoint1 and outpoint2
|
||||||
inputs = []*wire.TxIn{wire.NewTxIn(outpoint1, nil), wire.NewTxIn(outpoint2, nil)}
|
inputs = []*wire.TxIn{wire.NewTxIn(outpoint1, nil), wire.NewTxIn(outpoint2, nil)}
|
||||||
|
|
||||||
//Commitment Signature
|
// Commitment Signature
|
||||||
tx = wire.NewMsgTx()
|
tx = wire.NewMsgTx()
|
||||||
emptybytes = new([]byte)
|
emptybytes = new([]byte)
|
||||||
sigStr, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, privKey)
|
sigStr, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, privKey)
|
||||||
commitSig, _ = btcec.ParseSignature(sigStr, btcec.S256())
|
commitSig, _ = btcec.ParseSignature(sigStr, btcec.S256())
|
||||||
|
|
||||||
//Funding TX Sig 1
|
// Funding TX Sig 1
|
||||||
sig1privKeyBytes, _ = hex.DecodeString("927f5827d75dd2addeb532c0fa5ac9277565f981dd6d0d037b422be5f60bdbef")
|
sig1privKeyBytes, _ = hex.DecodeString("927f5827d75dd2addeb532c0fa5ac9277565f981dd6d0d037b422be5f60bdbef")
|
||||||
sig1privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig1privKeyBytes)
|
sig1privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig1privKeyBytes)
|
||||||
sigStr1, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig1privKey)
|
sigStr1, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig1privKey)
|
||||||
commitSig1, _ = btcec.ParseSignature(sigStr1, btcec.S256())
|
commitSig1, _ = btcec.ParseSignature(sigStr1, btcec.S256())
|
||||||
//Funding TX Sig 2
|
// Funding TX Sig 2
|
||||||
sig2privKeyBytes, _ = hex.DecodeString("8a4ad188f6f4000495b765cfb6ffa591133a73019c45428ddd28f53bab551847")
|
sig2privKeyBytes, _ = hex.DecodeString("8a4ad188f6f4000495b765cfb6ffa591133a73019c45428ddd28f53bab551847")
|
||||||
sig2privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig2privKeyBytes)
|
sig2privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig2privKeyBytes)
|
||||||
sigStr2, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig2privKey)
|
sigStr2, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig2privKey)
|
||||||
commitSig2, _ = btcec.ParseSignature(sigStr2, btcec.S256())
|
commitSig2, _ = btcec.ParseSignature(sigStr2, btcec.S256())
|
||||||
//Slice of Funding TX Sigs
|
// Slice of Funding TX Sigs
|
||||||
ptrFundingTXSigs = append(*new([]*btcec.Signature), commitSig1, commitSig2)
|
ptrFundingTXSigs = append(*new([]*btcec.Signature), commitSig1, commitSig2)
|
||||||
|
|
||||||
//TxID
|
// TxID
|
||||||
txid = new(wire.ShaHash)
|
txid = new(wire.ShaHash)
|
||||||
//Reversed when displayed
|
// Reversed when displayed
|
||||||
txidBytes, _ = hex.DecodeString("fd95c6e5c9d5bcf9cfc7231b6a438e46c518c724d0b04b75cc8fddf84a254e3a")
|
txidBytes, _ = hex.DecodeString("fd95c6e5c9d5bcf9cfc7231b6a438e46c518c724d0b04b75cc8fddf84a254e3a")
|
||||||
_ = copy(txid[:], txidBytes)
|
_ = copy(txid[:], txidBytes)
|
||||||
)
|
)
|
||||||
@ -95,12 +95,12 @@ func SerializeTest(t *testing.T, message Message, expectedString string, filenam
|
|||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
} else {
|
} else {
|
||||||
t.Logf("Encoded Bytes: %x\n", b.Bytes())
|
t.Logf("Encoded Bytes: %x\n", b.Bytes())
|
||||||
//Check if we serialized correctly
|
// Check if we serialized correctly
|
||||||
if expectedString != hex.EncodeToString(b.Bytes()) {
|
if expectedString != hex.EncodeToString(b.Bytes()) {
|
||||||
t.Error("Serialization does not match expected")
|
t.Error("Serialization does not match expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
//So I can do: hexdump -C /dev/shm/fundingRequest.raw
|
// So I can do: hexdump -C /dev/shm/fundingRequest.raw
|
||||||
if WRITE_FILE {
|
if WRITE_FILE {
|
||||||
err = ioutil.WriteFile(filename, b.Bytes(), 0644)
|
err = ioutil.WriteFile(filename, b.Bytes(), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -113,7 +113,7 @@ func SerializeTest(t *testing.T, message Message, expectedString string, filenam
|
|||||||
|
|
||||||
func DeserializeTest(t *testing.T, buf *bytes.Buffer, message Message, originalMessage Message) {
|
func DeserializeTest(t *testing.T, buf *bytes.Buffer, message Message, originalMessage Message) {
|
||||||
var err error
|
var err error
|
||||||
//Make a new buffer just to be clean
|
// Make a new buffer just to be clean
|
||||||
c := new(bytes.Buffer)
|
c := new(bytes.Buffer)
|
||||||
c.Write(buf.Bytes())
|
c.Write(buf.Bytes())
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ func DeserializeTest(t *testing.T, buf *bytes.Buffer, message Message, originalM
|
|||||||
if !reflect.DeepEqual(message, originalMessage) {
|
if !reflect.DeepEqual(message, originalMessage) {
|
||||||
t.Error("Decoding does not match!")
|
t.Error("Decoding does not match!")
|
||||||
}
|
}
|
||||||
//Show the struct
|
// Show the struct
|
||||||
t.Log(message.String())
|
t.Log(message.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ func MessageSerializeDeserializeTest(t *testing.T, message Message, expectedStri
|
|||||||
if hex.EncodeToString(b.Bytes()) != expectedString {
|
if hex.EncodeToString(b.Bytes()) != expectedString {
|
||||||
t.Error("Message encoding error")
|
t.Error("Message encoding error")
|
||||||
}
|
}
|
||||||
//Deserialize/Decode
|
// Deserialize/Decode
|
||||||
c := new(bytes.Buffer)
|
c := new(bytes.Buffer)
|
||||||
c.Write(b.Bytes())
|
c.Write(b.Bytes())
|
||||||
_, newMsg, _, err := ReadMessage(c, uint32(1), wire.TestNet3)
|
_, newMsg, _, err := ReadMessage(c, uint32(1), wire.TestNet3)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//Code derived from https://github.com/btcsuite/btcd/blob/master/wire/message.go
|
// Code derived from https:// github.com/btcsuite/btcd/blob/master/wire/message.go
|
||||||
package lnwire
|
package lnwire
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
// message type identifyer bytes
|
// message type identifyer bytes
|
||||||
const (
|
const (
|
||||||
MSGID_FUNDREQUEST = 0x30
|
MSGID_FUNDREQUEST = 0x30
|
||||||
MSGID_FUNDRESPONSE = 0x31
|
MSGID_FUNDRESPONSE = 0x31
|
||||||
@ -23,52 +23,52 @@ const (
|
|||||||
MSGID_FWDAUTHREQ = 0x21
|
MSGID_FWDAUTHREQ = 0x21
|
||||||
)
|
)
|
||||||
|
|
||||||
//4-byte network + 4-byte message id + payload-length 4-byte
|
// 4-byte network + 4-byte message id + payload-length 4-byte
|
||||||
const MessageHeaderSize = 12
|
const MessageHeaderSize = 12
|
||||||
|
|
||||||
const MaxMessagePayload = 1024 * 1024 * 32 // 32MB
|
const MaxMessagePayload = 1024 * 1024 * 32 // 32MB
|
||||||
|
|
||||||
const (
|
const (
|
||||||
//Funding channel open
|
// Funding channel open
|
||||||
CmdFundingRequest = uint32(200)
|
CmdFundingRequest = uint32(200)
|
||||||
CmdFundingResponse = uint32(210)
|
CmdFundingResponse = uint32(210)
|
||||||
CmdFundingSignAccept = uint32(220)
|
CmdFundingSignAccept = uint32(220)
|
||||||
CmdFundingSignComplete = uint32(230)
|
CmdFundingSignComplete = uint32(230)
|
||||||
|
|
||||||
//Close channel
|
// Close channel
|
||||||
CmdCloseRequest = uint32(300)
|
CmdCloseRequest = uint32(300)
|
||||||
CmdCloseComplete = uint32(310)
|
CmdCloseComplete = uint32(310)
|
||||||
|
|
||||||
//TODO Renumber to 1100
|
// TODO Renumber to 1100
|
||||||
//HTLC payment
|
// HTLC payment
|
||||||
CmdHTLCAddRequest = uint32(1000)
|
CmdHTLCAddRequest = uint32(1000)
|
||||||
CmdHTLCAddAccept = uint32(1010)
|
CmdHTLCAddAccept = uint32(1010)
|
||||||
CmdHTLCAddReject = uint32(1020)
|
CmdHTLCAddReject = uint32(1020)
|
||||||
|
|
||||||
//TODO Renumber to 1200
|
// TODO Renumber to 1200
|
||||||
//HTLC settlement
|
// HTLC settlement
|
||||||
CmdHTLCSettleRequest = uint32(1100)
|
CmdHTLCSettleRequest = uint32(1100)
|
||||||
CmdHTLCSettleAccept = uint32(1110)
|
CmdHTLCSettleAccept = uint32(1110)
|
||||||
|
|
||||||
//HTLC timeout
|
// HTLC timeout
|
||||||
CmdHTLCTimeoutRequest = uint32(1300)
|
CmdHTLCTimeoutRequest = uint32(1300)
|
||||||
CmdHTLCTimeoutAccept = uint32(1310)
|
CmdHTLCTimeoutAccept = uint32(1310)
|
||||||
|
|
||||||
//Commitments
|
// Commitments
|
||||||
CmdCommitSignature = uint32(2000)
|
CmdCommitSignature = uint32(2000)
|
||||||
CmdCommitRevocation = uint32(2010)
|
CmdCommitRevocation = uint32(2010)
|
||||||
|
|
||||||
//Error
|
// Error
|
||||||
CmdErrorGeneric = uint32(4000)
|
CmdErrorGeneric = uint32(4000)
|
||||||
)
|
)
|
||||||
|
|
||||||
//Every message has these functions:
|
// Every message has these functions:
|
||||||
type Message interface {
|
type Message interface {
|
||||||
Decode(io.Reader, uint32) error //(io, protocol version)
|
Decode(io.Reader, uint32) error // (io, protocol version)
|
||||||
Encode(io.Writer, uint32) error //(io, protocol version)
|
Encode(io.Writer, uint32) error // (io, protocol version)
|
||||||
Command() uint32 //returns ID of the message
|
Command() uint32 // returns ID of the message
|
||||||
MaxPayloadLength(uint32) uint32 //(version) maxpayloadsize
|
MaxPayloadLength(uint32) uint32 // (version) maxpayloadsize
|
||||||
Validate() error //Validates the data struct
|
Validate() error // Validates the data struct
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,10 +116,10 @@ func makeEmptyMessage(command uint32) (Message, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type messageHeader struct {
|
type messageHeader struct {
|
||||||
//NOTE(j): We don't need to worry about the magic overlapping with
|
// NOTE(j): We don't need to worry about the magic overlapping with
|
||||||
//bitcoin since this is inside encrypted comms anyway, but maybe we
|
// bitcoin since this is inside encrypted comms anyway, but maybe we
|
||||||
//should use the XOR (^wire.TestNet3) just in case???
|
// should use the XOR (^wire.TestNet3) just in case???
|
||||||
magic wire.BitcoinNet //which Blockchain Technology(TM) to use
|
magic wire.BitcoinNet // which Blockchain Technology(TM) to use
|
||||||
command uint32
|
command uint32
|
||||||
length uint32
|
length uint32
|
||||||
}
|
}
|
||||||
@ -145,12 +145,12 @@ func readMessageHeader(r io.Reader) (int, *messageHeader, error) {
|
|||||||
return n, &hdr, nil
|
return n, &hdr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// discardInput reads n bytes from reader r in chunks and discards the read
|
// discardInput reads n bytes from reader r in chunks and discards the read
|
||||||
// bytes. This is used to skip payloads when various errors occur and helps
|
// bytes. This is used to skip payloads when various errors occur and helps
|
||||||
// prevent rogue nodes from causing massive memory allocation through forging
|
// prevent rogue nodes from causing massive memory allocation through forging
|
||||||
// header length.
|
// header length.
|
||||||
func discardInput(r io.Reader, n uint32) {
|
func discardInput(r io.Reader, n uint32) {
|
||||||
maxSize := uint32(10 * 1024) //10k at a time
|
maxSize := uint32(10 * 1024) // 10k at a time
|
||||||
numReads := n / maxSize
|
numReads := n / maxSize
|
||||||
bytesRemaining := n % maxSize
|
bytesRemaining := n % maxSize
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
@ -170,7 +170,7 @@ func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet wire.BitcoinNet)
|
|||||||
|
|
||||||
cmd := msg.Command()
|
cmd := msg.Command()
|
||||||
|
|
||||||
//Encode the message payload
|
// Encode the message payload
|
||||||
var bw bytes.Buffer
|
var bw bytes.Buffer
|
||||||
err := msg.Encode(&bw, pver)
|
err := msg.Encode(&bw, pver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -179,37 +179,37 @@ func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet wire.BitcoinNet)
|
|||||||
payload := bw.Bytes()
|
payload := bw.Bytes()
|
||||||
lenp := len(payload)
|
lenp := len(payload)
|
||||||
|
|
||||||
//Enforce maximum overall message payload
|
// Enforce maximum overall message payload
|
||||||
if lenp > MaxMessagePayload {
|
if lenp > MaxMessagePayload {
|
||||||
return totalBytes, fmt.Errorf("message payload is too large - encoded %d bytes, but maximum message payload is %d bytes", lenp, MaxMessagePayload)
|
return totalBytes, fmt.Errorf("message payload is too large - encoded %d bytes, but maximum message payload is %d bytes", lenp, MaxMessagePayload)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Enforce maximum message payload on the message type
|
// Enforce maximum message payload on the message type
|
||||||
mpl := msg.MaxPayloadLength(pver)
|
mpl := msg.MaxPayloadLength(pver)
|
||||||
if uint32(lenp) > mpl {
|
if uint32(lenp) > mpl {
|
||||||
return totalBytes, fmt.Errorf("message payload is too large - encoded %d bytes, but maximum message payload of type %x is %d bytes", lenp, cmd, mpl)
|
return totalBytes, fmt.Errorf("message payload is too large - encoded %d bytes, but maximum message payload of type %x is %d bytes", lenp, cmd, mpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create header for the message
|
// Create header for the message
|
||||||
hdr := messageHeader{}
|
hdr := messageHeader{}
|
||||||
hdr.magic = btcnet
|
hdr.magic = btcnet
|
||||||
hdr.command = cmd
|
hdr.command = cmd
|
||||||
hdr.length = uint32(lenp)
|
hdr.length = uint32(lenp)
|
||||||
|
|
||||||
// Encode the header for the message. This is done to a buffer
|
// Encode the header for the message. This is done to a buffer
|
||||||
// rather than directly to the writer since writeElements doesn't
|
// rather than directly to the writer since writeElements doesn't
|
||||||
// return the number of bytes written.
|
// return the number of bytes written.
|
||||||
hw := bytes.NewBuffer(make([]byte, 0, MessageHeaderSize))
|
hw := bytes.NewBuffer(make([]byte, 0, MessageHeaderSize))
|
||||||
writeElements(hw, hdr.magic, hdr.command, hdr.length)
|
writeElements(hw, hdr.magic, hdr.command, hdr.length)
|
||||||
|
|
||||||
//Write header
|
// Write header
|
||||||
n, err := w.Write(hw.Bytes())
|
n, err := w.Write(hw.Bytes())
|
||||||
totalBytes += n
|
totalBytes += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return totalBytes, err
|
return totalBytes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Write payload
|
// Write payload
|
||||||
n, err = w.Write(payload)
|
n, err = w.Write(payload)
|
||||||
totalBytes += n
|
totalBytes += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -227,18 +227,18 @@ func ReadMessage(r io.Reader, pver uint32, btcnet wire.BitcoinNet) (int, Message
|
|||||||
return totalBytes, nil, nil, err
|
return totalBytes, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Enforce maximum message payload
|
// Enforce maximum message payload
|
||||||
if hdr.length > MaxMessagePayload {
|
if hdr.length > MaxMessagePayload {
|
||||||
return totalBytes, nil, nil, fmt.Errorf("message payload is too large - header indicates %d bytes, but max message payload is %d bytes.", hdr.length, MaxMessagePayload)
|
return totalBytes, nil, nil, fmt.Errorf("message payload is too large - header indicates %d bytes, but max message payload is %d bytes.", hdr.length, MaxMessagePayload)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check for messages in the wrong bitcoin network
|
// Check for messages in the wrong bitcoin network
|
||||||
if hdr.magic != btcnet {
|
if hdr.magic != btcnet {
|
||||||
discardInput(r, hdr.length)
|
discardInput(r, hdr.length)
|
||||||
return totalBytes, nil, nil, fmt.Errorf("message from other network [%v]", hdr.magic)
|
return totalBytes, nil, nil, fmt.Errorf("message from other network [%v]", hdr.magic)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create struct of appropriate message type based on the command
|
// Create struct of appropriate message type based on the command
|
||||||
command := hdr.command
|
command := hdr.command
|
||||||
msg, err := makeEmptyMessage(command)
|
msg, err := makeEmptyMessage(command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -246,14 +246,14 @@ func ReadMessage(r io.Reader, pver uint32, btcnet wire.BitcoinNet) (int, Message
|
|||||||
return totalBytes, nil, nil, fmt.Errorf("ReadMessage %s", err.Error())
|
return totalBytes, nil, nil, fmt.Errorf("ReadMessage %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check for maximum length based on the message type
|
// Check for maximum length based on the message type
|
||||||
mpl := msg.MaxPayloadLength(pver)
|
mpl := msg.MaxPayloadLength(pver)
|
||||||
if hdr.length > mpl {
|
if hdr.length > mpl {
|
||||||
discardInput(r, hdr.length)
|
discardInput(r, hdr.length)
|
||||||
return totalBytes, nil, nil, fmt.Errorf("payload exceeds max length. indicates %v bytes, but max of message type %v is %v.", hdr.length, command, mpl)
|
return totalBytes, nil, nil, fmt.Errorf("payload exceeds max length. indicates %v bytes, but max of message type %v is %v.", hdr.length, command, mpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read payload
|
// Read payload
|
||||||
payload := make([]byte, hdr.length)
|
payload := make([]byte, hdr.length)
|
||||||
n, err = io.ReadFull(r, payload)
|
n, err = io.ReadFull(r, payload)
|
||||||
totalBytes += n
|
totalBytes += n
|
||||||
@ -261,19 +261,19 @@ func ReadMessage(r io.Reader, pver uint32, btcnet wire.BitcoinNet) (int, Message
|
|||||||
return totalBytes, nil, nil, err
|
return totalBytes, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Unmarshal message
|
// Unmarshal message
|
||||||
pr := bytes.NewBuffer(payload)
|
pr := bytes.NewBuffer(payload)
|
||||||
err = msg.Decode(pr, pver)
|
err = msg.Decode(pr, pver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return totalBytes, nil, nil, err
|
return totalBytes, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Validate the data
|
// Validate the data
|
||||||
err = msg.Validate()
|
err = msg.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return totalBytes, nil, nil, err
|
return totalBytes, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//We're good!
|
// We're good!
|
||||||
return totalBytes, msg, payload, nil
|
return totalBytes, msg, payload, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user