Cleanup comments & removed notes on escrow

This commit is contained in:
Joseph Poon 2016-01-16 17:14:35 -08:00
parent 84c0f56330
commit f2a1c0368a
36 changed files with 648 additions and 769 deletions

View File

@ -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.)

View File

@ -11,15 +11,15 @@ import (
type CloseComplete struct {
ReservationID uint64
ResponderCloseSig *btcec.Signature //Requester's Commitment
CloseShaHash *wire.ShaHash //TxID of the Close Tx
ResponderCloseSig *btcec.Signature // Requester's Commitment
CloseShaHash *wire.ShaHash // TxID of the Close Tx
}
func (c *CloseComplete) Decode(r io.Reader, pver uint32) error {
//ReservationID (8)
//ResponderCloseSig (73)
// First byte length then sig
//CloseShaHash (32)
// ReservationID (8)
// ResponderCloseSig (73)
// First byte length then sig
// CloseShaHash (32)
err := readElements(r,
&c.ReservationID,
&c.ResponderCloseSig,
@ -31,17 +31,17 @@ func (c *CloseComplete) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new CloseComplete
// Creates a new CloseComplete
func NewCloseComplete() *CloseComplete {
return &CloseComplete{}
}
//Serializes the item from the CloseComplete struct
//Writes the data to w
// Serializes the item from the CloseComplete struct
// Writes the data to w
func (c *CloseComplete) Encode(w io.Writer, pver uint32) error {
//ReservationID
//ResponderCloseSig
//CloseShaHash
// ReservationID
// ResponderCloseSig
// CloseShaHash
err := writeElements(w,
c.ReservationID,
c.ResponderCloseSig,
@ -58,13 +58,13 @@ func (c *CloseComplete) Command() uint32 {
}
func (c *CloseComplete) MaxPayloadLength(uint32) uint32 {
//8 + 73 + 32
// 8 + 73 + 32
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 {
//We're good!
// We're good!
return nil
}

View File

@ -1,7 +1,7 @@
package lnwire
import (
//"github.com/btcsuite/btcutil"
// "github.com/btcsuite/btcutil"
"testing"
)
@ -16,19 +16,19 @@ var (
)
func TestCloseCompleteEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, closeComplete, closeCompleteSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewCloseComplete()
DeserializeTest(t, s, newMessage, closeComplete)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, closeComplete, closeCompleteSerializedMessage)
}

View File

@ -11,15 +11,15 @@ import (
type CloseRequest struct {
ReservationID uint64
RequesterCloseSig *btcec.Signature //Requester's Commitment
RequesterCloseSig *btcec.Signature // Requester's Commitment
Fee btcutil.Amount
}
func (c *CloseRequest) Decode(r io.Reader, pver uint32) error {
//ReservationID (8)
//RequesterCloseSig (73)
// First byte length then sig
//Fee (8)
// ReservationID (8)
// RequesterCloseSig (73)
// First byte length then sig
// Fee (8)
err := readElements(r,
&c.ReservationID,
&c.RequesterCloseSig,
@ -31,17 +31,17 @@ func (c *CloseRequest) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new CloseRequest
// Creates a new CloseRequest
func NewCloseRequest() *CloseRequest {
return &CloseRequest{}
}
//Serializes the item from the CloseRequest struct
//Writes the data to w
// Serializes the item from the CloseRequest struct
// Writes the data to w
func (c *CloseRequest) Encode(w io.Writer, pver uint32) error {
//ReservationID
//RequesterCloseSig
//Fee
// ReservationID
// RequesterCloseSig
// Fee
err := writeElements(w,
c.ReservationID,
c.RequesterCloseSig,
@ -58,17 +58,17 @@ func (c *CloseRequest) Command() uint32 {
}
func (c *CloseRequest) MaxPayloadLength(uint32) uint32 {
//8 + 73 + 8
// 8 + 73 + 8
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 {
//Fee must be greater than 0
// Fee must be greater than 0
if c.Fee < 0 {
return fmt.Errorf("Fee must be greater than zero.")
}
//We're good!
// We're good!
return nil
}

View File

@ -16,19 +16,19 @@ var (
)
func TestCloseRequestEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, closeRequest, closeRequestSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewCloseRequest()
DeserializeTest(t, s, newMessage, closeRequest)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, closeRequest, closeRequestSerializedMessage)
}

View File

@ -5,28 +5,28 @@ import (
"io"
)
//Multiple Clearing Requests are possible by putting this inside an array of
//clearing requests
// Multiple Clearing Requests are possible by putting this inside an array of
// clearing requests
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
//Height of the commitment
//You should have the most recent commitment height stored locally
//This should be validated!
//This is used for shachain.
//Each party increments their own CommitmentHeight, they can differ for
//each part of the Commitment.
// Height of the commitment
// You should have the most recent commitment height stored locally
// This should be validated!
// This is used for shachain.
// Each party increments their own CommitmentHeight, they can differ for
// each part of the Commitment.
CommitmentHeight uint64
//Revocation to use
// Revocation to use
RevocationProof [20]byte
}
func (c *CommitRevocation) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//CommitmentHeight(8)
//RevocationProof(20)
// ChannelID(8)
// CommitmentHeight(8)
// RevocationProof(20)
err := readElements(r,
&c.ChannelID,
&c.CommitmentHeight,
@ -39,13 +39,13 @@ func (c *CommitRevocation) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new CommitRevocation
// Creates a new CommitRevocation
func NewCommitRevocation() *CommitRevocation {
return &CommitRevocation{}
}
//Serializes the item from the CommitRevocation struct
//Writes the data to w
// Serializes the item from the CommitRevocation struct
// Writes the data to w
func (c *CommitRevocation) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -67,9 +67,9 @@ func (c *CommitRevocation) MaxPayloadLength(uint32) uint32 {
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 {
//We're good!
// We're good!
return nil
}

View File

@ -5,32 +5,32 @@ import (
)
var (
//Need to to do this here
// Need to to do this here
_ = copy(revocationHash[:], revocationHashBytes)
commitRevocation = &CommitRevocation{
ChannelID: uint64(12345678),
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"
commitRevocationSerializedMessage = "0709110b000007da000000240000000000bc614e00000000000030394132b6b48371f7b022a16eacb9b2b0ebee134d41"
)
func TestCommitRevocationEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, commitRevocation, commitRevocationSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewCommitRevocation()
DeserializeTest(t, s, newMessage, commitRevocation)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, commitRevocation, commitRevocationSerializedMessage)
}

View File

@ -7,40 +7,40 @@ import (
"io"
)
//Multiple Clearing Requests are possible by putting this inside an array of
//clearing requests
// Multiple Clearing Requests are possible by putting this inside an array of
// clearing requests
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
//Height of the commitment
//You should have the most recent commitment height stored locally
//This should be validated!
//This is used for shachain.
//Each party increments their own CommitmentHeight, they can differ for
//each part of the Commitment.
// Height of the commitment
// You should have the most recent commitment height stored locally
// This should be validated!
// This is used for shachain.
// Each party increments their own CommitmentHeight, they can differ for
// each part of the Commitment.
CommitmentHeight uint64
//List of HTLC Keys which are updated from all parties
// List of HTLC Keys which are updated from all parties
UpdatedHTLCKeys []uint64
//Hash of the revocation to use
// Hash of the revocation to use
RevocationHash [20]byte
//Total miners' fee that was used
// Total miners' fee that was used
Fee btcutil.Amount
//Signature for the new Commitment
CommitSig *btcec.Signature //Requester's Commitment
// Signature for the new Commitment
CommitSig *btcec.Signature // Requester's Commitment
}
func (c *CommitSignature) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//CommitmentHeight(8)
//c.UpdatedHTLCKeys(8*1000max)
//RevocationHash(20)
//Fee(8)
//RequesterCommitSig(73max+2)
// ChannelID(8)
// CommitmentHeight(8)
// c.UpdatedHTLCKeys(8*1000max)
// RevocationHash(20)
// Fee(8)
// RequesterCommitSig(73max+2)
err := readElements(r,
&c.ChannelID,
&c.CommitmentHeight,
@ -56,13 +56,13 @@ func (c *CommitSignature) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new CommitSignature
// Creates a new CommitSignature
func NewCommitSignature() *CommitSignature {
return &CommitSignature{}
}
//Serializes the item from the CommitSignature struct
//Writes the data to w
// Serializes the item from the CommitSignature struct
// Writes the data to w
func (c *CommitSignature) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -87,24 +87,24 @@ func (c *CommitSignature) MaxPayloadLength(uint32) uint32 {
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 {
if c.Fee < 0 {
//While fees can be negative, it's too confusing to allow
//negative payments. Maybe for some wallets, but not this one!
// While fees can be negative, it's too confusing to allow
// negative payments. Maybe for some wallets, but not this one!
return fmt.Errorf("Amount paid cannot be negative.")
}
//We're good!
// We're good!
return nil
}
func (c *CommitSignature) String() string {
//c.ChannelID,
//c.CommitmentHeight,
//c.RevocationHash,
//c.UpdatedHTLCKeys,
//c.Fee,
//c.CommitSig,
// c.ChannelID,
// c.CommitmentHeight,
// c.RevocationHash,
// c.UpdatedHTLCKeys,
// c.Fee,
// c.CommitSig,
var serializedSig []byte
if &c.CommitSig != nil && c.CommitSig.R != nil {
serializedSig = c.CommitSig.Serialize()

View File

@ -6,13 +6,13 @@ import (
)
var (
//Need to to do this here
// Need to to do this here
_ = copy(revocationHash[:], revocationHashBytes)
commitSignature = &CommitSignature{
ChannelID: uint64(12345678),
CommitmentHeight: uint64(12345),
//CommitterLastStaging: uint64(12345678),
// CommitterLastStaging: uint64(12345678),
UpdatedHTLCKeys: []uint64{1, 2, 3, 4, 5},
RevocationHash: revocationHash,
Fee: btcutil.Amount(10000),
@ -23,19 +23,19 @@ var (
)
func TestCommitSignatureEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, commitSignature, commitSignatureSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewCommitSignature()
DeserializeTest(t, s, newMessage, commitSignature)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, commitSignature, commitSignatureSerializedMessage)
}

View File

@ -5,19 +5,19 @@ import (
"io"
)
//Multiple Clearing Requests are possible by putting this inside an array of
//clearing requests
// Multiple Clearing Requests are possible by putting this inside an array of
// clearing requests
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
//Some kind of message
//Max length 8192
// Some kind of message
// Max length 8192
Problem string
}
func (c *ErrorGeneric) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//Problem
// ChannelID(8)
// Problem
err := readElements(r,
&c.ChannelID,
&c.Problem,
@ -29,13 +29,13 @@ func (c *ErrorGeneric) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new ErrorGeneric
// Creates a new ErrorGeneric
func NewErrorGeneric() *ErrorGeneric {
return &ErrorGeneric{}
}
//Serializes the item from the ErrorGeneric struct
//Writes the data to w
// Serializes the item from the ErrorGeneric struct
// Writes the data to w
func (c *ErrorGeneric) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -53,16 +53,16 @@ func (c *ErrorGeneric) Command() uint32 {
}
func (c *ErrorGeneric) MaxPayloadLength(uint32) uint32 {
//8+8192
// 8+8192
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 {
if len(c.Problem) > 8192 {
return fmt.Errorf("Problem string length too long")
}
//We're good!
// We're good!
return nil
}

View File

@ -14,19 +14,19 @@ var (
)
func TestErrorGenericEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, errorGeneric, errorGenericSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewErrorGeneric()
DeserializeTest(t, s, newMessage, errorGeneric)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, errorGeneric, errorGenericSerializedMessage)
}

View File

@ -17,62 +17,62 @@ type FundingRequest struct {
RequesterReserveAmount btcutil.Amount
MinFeePerKb btcutil.Amount
//The funding requester can request payment
//This wallet only allows positive values,
//which is a payment to the responder
//(This can be used to fund the Reserve)
//If the responder disagrees, then the funding request fails
//THIS VALUE GOES INTO THE RESPONDER'S FUNDING AMOUNT
//total requester input value = RequesterFundingAmount + PaymentAmount + "Total Change" + Fees(?)
//RequesterFundingAmount = "Available Balance" + RequesterReserveAmount
//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)
//This is to make a payment as part of opening the channel
// The funding requester can request payment
// This wallet only allows positive values,
// which is a payment to the responder
// (This can be used to fund the Reserve)
// If the responder disagrees, then the funding request fails
// THIS VALUE GOES INTO THE RESPONDER'S FUNDING AMOUNT
// total requester input value = RequesterFundingAmount + PaymentAmount + "Total Change" + Fees(?)
// RequesterFundingAmount = "Available Balance" + RequesterReserveAmount
// 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)
// This is to make a payment as part of opening the channel
PaymentAmount btcutil.Amount
//Minimum number of confirmations to validate transaction
// Minimum number of confirmations to validate transaction
MinDepth uint32
//Should double-check the total funding later
// Should double-check the total funding later
MinTotalFundingAmount btcutil.Amount
//CLTV/CSV lock-time to use
// CLTV/CSV lock-time to use
LockTime uint32
//Who pays the fees
//0: (default) channel initiator
//1: split
//2: channel responder
// Who pays the fees
// 0: (default) channel initiator
// 1: split
// 2: channel responder
FeePayer uint8
RevocationHash [20]byte
Pubkey *btcec.PublicKey
DeliveryPkScript PkScript //*MUST* be either P2PKH or P2SH
ChangePkScript PkScript //*MUST* be either P2PKH or P2SH
DeliveryPkScript PkScript // *MUST* be either P2PKH or P2SH
ChangePkScript PkScript // *MUST* be either P2PKH or P2SH
Inputs []*wire.TxIn
}
func (c *FundingRequest) Decode(r io.Reader, pver uint32) error {
//Reservation ID (8)
//Channel Type (1)
//Funding Amount (8)
//Channel Minimum Capacity (8)
//Revocation Hash (20)
//Commitment Pubkey (32)
//Reserve Amount (8)
//Minimum Transaction Fee Per Kb (8)
//PaymentAmount (8)
//MinDepth (4)
//LockTime (4)
//FeePayer (1)
//DeliveryPkScript (final delivery)
// First byte length then pkscript
//ChangePkScript (change for extra from inputs)
// First byte length then pkscript
//Inputs: Create the TxIns
// First byte is number of inputs
// For each input, it's 32bytes txin & 4bytes index
// Reservation ID (8)
// Channel Type (1)
// Funding Amount (8)
// Channel Minimum Capacity (8)
// Revocation Hash (20)
// Commitment Pubkey (32)
// Reserve Amount (8)
// Minimum Transaction Fee Per Kb (8)
// PaymentAmount (8)
// MinDepth (4)
// LockTime (4)
// FeePayer (1)
// DeliveryPkScript (final delivery)
// First byte length then pkscript
// ChangePkScript (change for extra from inputs)
// First byte length then pkscript
// Inputs: Create the TxIns
// First byte is number of inputs
// For each input, it's 32bytes txin & 4bytes index
err := readElements(r,
&c.ReservationID,
&c.ChannelType,
@ -96,26 +96,26 @@ func (c *FundingRequest) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new FundingRequest
// Creates a new FundingRequest
func NewFundingRequest() *FundingRequest {
return &FundingRequest{}
}
//Serializes the item from the FundingRequest struct
//Writes the data to w
// Serializes the item from the FundingRequest struct
// Writes the data to w
func (c *FundingRequest) Encode(w io.Writer, pver uint32) error {
//Channel Type
//Funding Amont
//Channel Minimum Capacity
//Revocation Hash
//Commitment Pubkey
//Reserve Amount
//Minimum Transaction Fee Per KB
//LockTime
//FeePayer
//DeliveryPkScript
//ChangePkScript
//Inputs: Append the actual Txins
// Channel Type
// Funding Amont
// Channel Minimum Capacity
// Revocation Hash
// Commitment Pubkey
// Reserve Amount
// Minimum Transaction Fee Per KB
// LockTime
// FeePayer
// DeliveryPkScript
// ChangePkScript
// Inputs: Append the actual Txins
err := writeElements(w,
c.ReservationID,
c.ChannelType,
@ -144,15 +144,15 @@ func (c *FundingRequest) Command() 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
}
//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 {
var err error
//No negative values
// No negative values
if c.RequesterFundingAmount < 0 {
return fmt.Errorf("RequesterFundingAmount cannot be negative")
}
@ -168,7 +168,7 @@ func (c *FundingRequest) Validate() error {
return fmt.Errorf("MinTotalFundingAmount cannot be negative")
}
//Validation of what makes sense...
// Validation of what makes sense...
if c.MinTotalFundingAmount < c.RequesterFundingAmount {
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")
}
//This wallet only allows payment from the requester to responder
// This wallet only allows payment from the requester to responder
if c.PaymentAmount < 0 {
return fmt.Errorf("This wallet requieres payment to be greater than zero.")
}
//Make sure there's not more than 127 inputs
// Make sure there's not more than 127 inputs
if len(c.Inputs) > 127 {
return fmt.Errorf("Too many inputs")
}
//DeliveryPkScript is either P2SH or P2PKH
// DeliveryPkScript is either P2SH or P2PKH
err = ValidatePkScript(c.DeliveryPkScript)
if err != nil {
return err
}
//ChangePkScript is either P2SH or P2PKH
// ChangePkScript is either P2SH or P2PKH
err = ValidatePkScript(c.ChangePkScript)
if err != nil {
return err
}
//We're good!
// We're good!
return nil
}

View File

@ -6,10 +6,10 @@ import (
)
var (
//Need to do this here
// Need to do this here
_ = copy(revocationHash[:], revocationHashBytes)
//funding request
// funding request
fundingRequest = &FundingRequest{
ReservationID: uint64(12345678),
ChannelType: uint8(0),
@ -17,7 +17,7 @@ var (
RequesterReserveAmount: btcutil.Amount(131072),
MinFeePerKb: btcutil.Amount(20000),
MinTotalFundingAmount: btcutil.Amount(150000000),
LockTime: uint32(4320), //30 block-days
LockTime: uint32(4320), // 30 block-days
FeePayer: uint8(0),
PaymentAmount: btcutil.Amount(1234567),
MinDepth: uint32(6),
@ -32,19 +32,19 @@ var (
)
func TestFundingRequestEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, fundingRequest, fundingRequestSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewFundingRequest()
DeserializeTest(t, s, newMessage, fundingRequest)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, fundingRequest, fundingRequestSerializedMessage)
}

View File

@ -13,51 +13,51 @@ type FundingResponse struct {
ReservationID uint64
ResponderFundingAmount btcutil.Amount //Responder's funding amount
ResponderReserveAmount btcutil.Amount //Responder's reserve amount
MinFeePerKb btcutil.Amount //Lock-in min fee
ResponderFundingAmount btcutil.Amount // Responder's funding amount
ResponderReserveAmount btcutil.Amount // Responder's reserve amount
MinFeePerKb btcutil.Amount // Lock-in min fee
//Minimum depth
// Minimum depth
MinDepth uint32
//CLTV/CSV lock-time to use
// CLTV/CSV lock-time to use
LockTime uint32
//Who pays the fees
//0: (default) channel initiator
//1: split
//2: channel responder
// Who pays the fees
// 0: (default) channel initiator
// 1: split
// 2: channel responder
FeePayer uint8
RevocationHash [20]byte
Pubkey *btcec.PublicKey
CommitSig *btcec.Signature //Requester's Commitment
DeliveryPkScript PkScript //*MUST* be either P2PKH or P2SH
ChangePkScript PkScript //*MUST* be either P2PKH or P2SH
CommitSig *btcec.Signature // Requester's Commitment
DeliveryPkScript PkScript // *MUST* be either P2PKH or P2SH
ChangePkScript PkScript // *MUST* be either P2PKH or P2SH
Inputs []*wire.TxIn
}
func (c *FundingResponse) Decode(r io.Reader, pver uint32) error {
//ReservationID (8)
//Channel Type (1)
//Funding Amount (8)
//Revocation Hash (20)
//Commitment Pubkey (32)
//Reserve Amount (8)
//Minimum Transaction Fee Per Kb (8)
//MinDepth (4)
//LockTime (4)
//FeePayer (1)
//DeliveryPkScript (final delivery)
// First byte length then pkscript
//ChangePkScript (change for extra from inputs)
// First byte length then pkscript
//CommitSig
// First byte length then sig
//Inputs: Create the TxIns
// First byte is number of inputs
// For each input, it's 32bytes txin & 4bytes index
// ReservationID (8)
// Channel Type (1)
// Funding Amount (8)
// Revocation Hash (20)
// Commitment Pubkey (32)
// Reserve Amount (8)
// Minimum Transaction Fee Per Kb (8)
// MinDepth (4)
// LockTime (4)
// FeePayer (1)
// DeliveryPkScript (final delivery)
// First byte length then pkscript
// ChangePkScript (change for extra from inputs)
// First byte length then pkscript
// CommitSig
// First byte length then sig
// Inputs: Create the TxIns
// First byte is number of inputs
// For each input, it's 32bytes txin & 4bytes index
err := readElements(r,
&c.ReservationID,
&c.ChannelType,
@ -80,27 +80,27 @@ func (c *FundingResponse) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new FundingResponse
// Creates a new FundingResponse
func NewFundingResponse() *FundingResponse {
return &FundingResponse{}
}
//Serializes the item from the FundingResponse struct
//Writes the data to w
// Serializes the item from the FundingResponse struct
// Writes the data to w
func (c *FundingResponse) Encode(w io.Writer, pver uint32) error {
//ReservationID (8)
//Channel Type (1)
//Funding Amount (8)
//Revocation Hash (20)
//Commitment Pubkey (32)
//Reserve Amount (8)
//Minimum Transaction Fee Per Kb (8)
//LockTime (4)
//FeePayer (1)
//DeliveryPkScript (final delivery)
//ChangePkScript (change for extra from inputs)
//CommitSig
//Inputs
// ReservationID (8)
// Channel Type (1)
// Funding Amount (8)
// Revocation Hash (20)
// Commitment Pubkey (32)
// Reserve Amount (8)
// Minimum Transaction Fee Per Kb (8)
// LockTime (4)
// FeePayer (1)
// DeliveryPkScript (final delivery)
// ChangePkScript (change for extra from inputs)
// CommitSig
// Inputs
err := writeElements(w,
c.ReservationID,
c.ChannelType,
@ -128,15 +128,15 @@ func (c *FundingResponse) Command() 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
}
//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 {
var err error
//No negative values
// No negative values
if c.ResponderFundingAmount < 0 {
return fmt.Errorf("ResponderFundingAmount cannot be negative")
}
@ -149,29 +149,29 @@ func (c *FundingResponse) Validate() error {
return fmt.Errorf("MinFeePerKb cannot be negative")
}
//Validation of what makes sense...
// Validation of what makes sense...
if c.ResponderFundingAmount < c.ResponderReserveAmount {
return fmt.Errorf("Reserve must be below Funding Amount")
}
//Make sure there's not more than 127 inputs
// Make sure there's not more than 127 inputs
if len(c.Inputs) > 127 {
return fmt.Errorf("Too many inputs")
}
//Delivery PkScript is either P2SH or P2PKH
// Delivery PkScript is either P2SH or P2PKH
err = ValidatePkScript(c.DeliveryPkScript)
if err != nil {
return err
}
//Change PkScript is either P2SH or P2PKH
// Change PkScript is either P2SH or P2PKH
err = ValidatePkScript(c.ChangePkScript)
if err != nil {
return err
}
//We're good!
// We're good!
return nil
}

View File

@ -6,10 +6,10 @@ import (
)
var (
//Need to do this here
// Need to do this here
_ = copy(revocationHash[:], revocationHashBytes)
//funding response
// funding response
fundingResponse = &FundingResponse{
ChannelType: uint8(1),
ReservationID: uint64(12345678),
@ -17,7 +17,7 @@ var (
ResponderReserveAmount: btcutil.Amount(131072),
MinFeePerKb: btcutil.Amount(20000),
MinDepth: uint32(6),
LockTime: uint32(4320), //30 block-days
LockTime: uint32(4320), // 30 block-days
FeePayer: uint8(1),
RevocationHash: revocationHash,
Pubkey: pubKey,
@ -31,19 +31,19 @@ var (
)
func TestFundingResponseEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, fundingResponse, fundingResponseSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewFundingResponse()
DeserializeTest(t, s, newMessage, fundingResponse)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, fundingResponse, fundingResponseSerializedMessage)
}

View File

@ -9,18 +9,18 @@ import (
type FundingSignAccept struct {
ReservationID uint64
CommitSig *btcec.Signature //Requester's Commitment
CommitSig *btcec.Signature // Requester's Commitment
FundingTXSigs []*btcec.Signature
}
func (c *FundingSignAccept) Decode(r io.Reader, pver uint32) error {
//ReservationID (8)
//CommitSig (73)
// First byte length then sig
//FundingTXSigs
// First byte is number of FundingTxSigs
// Sorted list of the requester's input signatures
// (originally provided in the Funding Request)
// ReservationID (8)
// CommitSig (73)
// First byte length then sig
// FundingTXSigs
// First byte is number of FundingTxSigs
// Sorted list of the requester's input signatures
// (originally provided in the Funding Request)
err := readElements(r,
&c.ReservationID,
&c.CommitSig,
@ -32,17 +32,17 @@ func (c *FundingSignAccept) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new FundingSignAccept
// Creates a new FundingSignAccept
func NewFundingSignAccept() *FundingSignAccept {
return &FundingSignAccept{}
}
//Serializes the item from the FundingSignAccept struct
//Writes the data to w
// Serializes the item from the FundingSignAccept struct
// Writes the data to w
func (c *FundingSignAccept) Encode(w io.Writer, pver uint32) error {
//ReservationID
//CommitSig
//FundingTxSigs
// ReservationID
// CommitSig
// FundingTxSigs
err := writeElements(w,
c.ReservationID,
c.CommitSig,
@ -59,13 +59,13 @@ func (c *FundingSignAccept) Command() uint32 {
}
func (c *FundingSignAccept) MaxPayloadLength(uint32) uint32 {
//8 (base size) + 73 + (73maxSigSize*127maxInputs)
// 8 (base size) + 73 + (73maxSigSize*127maxInputs)
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 {
//We're good!
// We're good!
return nil
}

View File

@ -5,7 +5,7 @@ import (
)
var (
//funding sign accept
// funding sign accept
fundingSignAccept = &FundingSignAccept{
ReservationID: uint64(12345678),
CommitSig: commitSig,
@ -16,19 +16,19 @@ var (
)
func TestFundingSignAcceptEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, fundingSignAccept, fundingSignAcceptSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewFundingSignAccept()
DeserializeTest(t, s, newMessage, fundingSignAccept)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, fundingSignAccept, fundingSignAcceptSerializedMessage)
}

View File

@ -15,12 +15,12 @@ type FundingSignComplete struct {
}
func (c *FundingSignComplete) Decode(r io.Reader, pver uint32) error {
//ReservationID (8)
//TxID (32)
//FundingTXSigs
// First byte is number of FundingTxSigs
// Sorted list of the requester's input signatures
// (originally provided in the Funding Request)
// ReservationID (8)
// TxID (32)
// FundingTXSigs
// First byte is number of FundingTxSigs
// Sorted list of the requester's input signatures
// (originally provided in the Funding Request)
err := readElements(r,
&c.ReservationID,
&c.TxID,
@ -32,13 +32,13 @@ func (c *FundingSignComplete) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new FundingSignComplete
// Creates a new FundingSignComplete
func NewFundingSignComplete() *FundingSignComplete {
return &FundingSignComplete{}
}
//Serializes the item from the FundingSignComplete struct
//Writes the data to w
// Serializes the item from the FundingSignComplete struct
// Writes the data to w
func (c *FundingSignComplete) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ReservationID,
@ -56,13 +56,13 @@ func (c *FundingSignComplete) Command() uint32 {
}
func (c *FundingSignComplete) MaxPayloadLength(uint32) uint32 {
//8 (base size) + 32 + (73maxSigSize*127maxInputs)
// 8 (base size) + 32 + (73maxSigSize*127maxInputs)
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 {
//We're good!
// We're good!
return nil
}

View File

@ -5,7 +5,7 @@ import (
)
var (
//funding response
// funding response
fundingSignComplete = &FundingSignComplete{
ReservationID: uint64(12345678),
TxID: txid,
@ -16,19 +16,19 @@ var (
)
func TestFundingSignCompleteEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, fundingSignComplete, fundingSignCompleteSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewFundingSignComplete()
DeserializeTest(t, s, newMessage, fundingSignComplete)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, fundingSignComplete, fundingSignCompleteSerializedMessage)
}

View File

@ -11,8 +11,8 @@ type HTLCAddAccept struct {
}
func (c *HTLCAddAccept) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//HTLCKey(8)
// ChannelID(8)
// HTLCKey(8)
err := readElements(r,
&c.ChannelID,
&c.HTLCKey,
@ -24,13 +24,13 @@ func (c *HTLCAddAccept) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new HTLCAddAccept
// Creates a new HTLCAddAccept
func NewHTLCAddAccept() *HTLCAddAccept {
return &HTLCAddAccept{}
}
//Serializes the item from the HTLCAddAccept struct
//Writes the data to w
// Serializes the item from the HTLCAddAccept struct
// Writes the data to w
func (c *HTLCAddAccept) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -49,13 +49,13 @@ func (c *HTLCAddAccept) Command() uint32 {
}
func (c *HTLCAddAccept) MaxPayloadLength(uint32) uint32 {
//16 base size
// 16 base size
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 {
//We're good!
// We're good!
return nil
}

View File

@ -14,19 +14,19 @@ var (
)
func TestHTLCAddAcceptEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, htlcAddAccept, htlcAddAcceptSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewHTLCAddAccept()
DeserializeTest(t, s, newMessage, htlcAddAccept)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, htlcAddAccept, htlcAddAcceptSerializedMessage)
}

View File

@ -11,11 +11,11 @@ type HTLCAddReject struct {
}
func (c *HTLCAddReject) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//CommitmentHeight(8)
//NextResponderCommitmentRevocationHash(20)
//ResponderRevocationPreimage(20)
//ResponderCommitSig(2+73max)
// ChannelID(8)
// CommitmentHeight(8)
// NextResponderCommitmentRevocationHash(20)
// ResponderRevocationPreimage(20)
// ResponderCommitSig(2+73max)
err := readElements(r,
&c.ChannelID,
&c.HTLCKey,
@ -27,13 +27,13 @@ func (c *HTLCAddReject) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new HTLCAddReject
// Creates a new HTLCAddReject
func NewHTLCAddReject() *HTLCAddReject {
return &HTLCAddReject{}
}
//Serializes the item from the HTLCAddReject struct
//Writes the data to w
// Serializes the item from the HTLCAddReject struct
// Writes the data to w
func (c *HTLCAddReject) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -52,13 +52,13 @@ func (c *HTLCAddReject) Command() uint32 {
}
func (c *HTLCAddReject) MaxPayloadLength(uint32) uint32 {
//16 base size
// 16 base size
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 {
//We're good!
// We're good!
return nil
}

View File

@ -14,19 +14,19 @@ var (
)
func TestHTLCAddRejectEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, htlcAddReject, htlcAddRejectSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewHTLCAddReject()
DeserializeTest(t, s, newMessage, htlcAddReject)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, htlcAddReject, htlcAddRejectSerializedMessage)
}

View File

@ -5,46 +5,46 @@ import (
"io"
)
//Multiple Clearing Requests are possible by putting this inside an array of
//clearing requests
// Multiple Clearing Requests are possible by putting this inside an array of
// clearing requests
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
//ID of this request
// ID of this request
HTLCKey HTLCKey
//When the HTLC expires
// When the HTLC expires
Expiry uint32
//Amount to pay in the hop
//Difference between hop and first item in blob is the fee to complete
// Amount to pay in the hop
// Difference between hop and first item in blob is the fee to complete
Amount CreditsAmount
//RefundContext is for payment cancellation
//TODO (j): not currently in use, add later
// RefundContext is for payment cancellation
// TODO (j): not currently in use, add later
RefundContext HTLCKey
//Contract Type
//first 4 bits is n, second for is m, in n-of-m "multisig"
// Contract Type
// first 4 bits is n, second for is m, in n-of-m "multisig"
ContractType uint8
//Redemption Hashes
// Redemption Hashes
RedemptionHashes []*[20]byte
//Data to parse&pass on to the next node
//Eventually, we need to make this into a group of 2 nested structs?
// Data to parse&pass on to the next node
// Eventually, we need to make this into a group of 2 nested structs?
Blob []byte
}
func (c *HTLCAddRequest) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//HTLCKey(8)
//Expiry(4)
//Amount(4)
//ContractType(1)
//RedemptionHashes (numOfHashes * 20 + numOfHashes)
//Blob(2+blobsize)
// ChannelID(8)
// HTLCKey(8)
// Expiry(4)
// Amount(4)
// ContractType(1)
// RedemptionHashes (numOfHashes * 20 + numOfHashes)
// Blob(2+blobsize)
err := readElements(r,
&c.ChannelID,
&c.HTLCKey,
@ -61,13 +61,13 @@ func (c *HTLCAddRequest) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new HTLCAddRequest
// Creates a new HTLCAddRequest
func NewHTLCAddRequest() *HTLCAddRequest {
return &HTLCAddRequest{}
}
//Serializes the item from the HTLCAddRequest struct
//Writes the data to w
// Serializes the item from the HTLCAddRequest struct
// Writes the data to w
func (c *HTLCAddRequest) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -90,19 +90,19 @@ func (c *HTLCAddRequest) Command() uint32 {
}
func (c *HTLCAddRequest) MaxPayloadLength(uint32) uint32 {
//base size ~110, but blob can be variable.
//shouldn't be bigger than 8K though...
// base size ~110, but blob can be variable.
// shouldn't be bigger than 8K though...
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 {
if c.Amount < 0 {
//While fees can be negative, it's too confusing to allow
//negative payments. Maybe for some wallets, but not this one!
// While fees can be negative, it's too confusing to allow
// negative payments. Maybe for some wallets, but not this one!
return fmt.Errorf("Amount paid cannot be negative.")
}
//We're good!
// We're good!
return nil
}

View File

@ -5,7 +5,7 @@ import (
)
var (
//Need to to do this here
// Need to to do this here
_ = copy(revocationHash[:], revocationHashBytes)
_ = copy(redemptionHash[:], redemptionHashBytes)
emptyRedemptionHashes = []*[20]byte{}
@ -26,19 +26,19 @@ var (
)
func TestHTLCAddRequestEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, htlcAddRequest, htlcAddRequestSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewHTLCAddRequest()
DeserializeTest(t, s, newMessage, htlcAddRequest)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, htlcAddRequest, htlcAddRequestSerializedMessage)
}

View File

@ -5,19 +5,19 @@ import (
"io"
)
//Multiple Clearing Requests are possible by putting this inside an array of
//clearing requests
// Multiple Clearing Requests are possible by putting this inside an array of
// clearing requests
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
//ID of this request
// ID of this request
HTLCKey HTLCKey
}
func (c *HTLCSettleAccept) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//HTLCKey(8)
// ChannelID(8)
// HTLCKey(8)
err := readElements(r,
&c.ChannelID,
&c.HTLCKey,
@ -29,13 +29,13 @@ func (c *HTLCSettleAccept) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new HTLCSettleAccept
// Creates a new HTLCSettleAccept
func NewHTLCSettleAccept() *HTLCSettleAccept {
return &HTLCSettleAccept{}
}
//Serializes the item from the HTLCSettleAccept struct
//Writes the data to w
// Serializes the item from the HTLCSettleAccept struct
// Writes the data to w
func (c *HTLCSettleAccept) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -53,13 +53,13 @@ func (c *HTLCSettleAccept) Command() uint32 {
}
func (c *HTLCSettleAccept) MaxPayloadLength(uint32) uint32 {
//16
// 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 {
//We're good!
// We're good!
return nil
}

View File

@ -14,19 +14,19 @@ var (
)
func TestHTLCSettleAcceptEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, htlcSettleAccept, htlcSettleAcceptSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewHTLCSettleAccept()
DeserializeTest(t, s, newMessage, htlcSettleAccept)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, htlcSettleAccept, htlcSettleAcceptSerializedMessage)
}

View File

@ -5,28 +5,28 @@ import (
"io"
)
//Multiple Clearing Requests are possible by putting this inside an array of
//clearing requests
// Multiple Clearing Requests are possible by putting this inside an array of
// clearing requests
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
//ID of this request
// ID of this request
HTLCKey HTLCKey
//Redemption Proofs (R-Values)
// Redemption Proofs (R-Values)
RedemptionProofs []*[20]byte
}
func (c *HTLCSettleRequest) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//HTLCKey(8)
//Expiry(4)
//Amount(4)
//NextHop(20)
//ContractType(1)
//RedemptionHashes (numOfHashes * 20 + numOfHashes)
//Blob(2+blobsize)
// ChannelID(8)
// HTLCKey(8)
// Expiry(4)
// Amount(4)
// NextHop(20)
// ContractType(1)
// RedemptionHashes (numOfHashes * 20 + numOfHashes)
// Blob(2+blobsize)
err := readElements(r,
&c.ChannelID,
&c.HTLCKey,
@ -39,13 +39,13 @@ func (c *HTLCSettleRequest) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new HTLCSettleRequest
// Creates a new HTLCSettleRequest
func NewHTLCSettleRequest() *HTLCSettleRequest {
return &HTLCSettleRequest{}
}
//Serializes the item from the HTLCSettleRequest struct
//Writes the data to w
// Serializes the item from the HTLCSettleRequest struct
// Writes the data to w
func (c *HTLCSettleRequest) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -64,13 +64,13 @@ func (c *HTLCSettleRequest) Command() uint32 {
}
func (c *HTLCSettleRequest) MaxPayloadLength(uint32) uint32 {
//21*15+16
// 21*15+16
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 {
//We're good!
// We're good!
return nil
}

View File

@ -5,7 +5,7 @@ import (
)
var (
//Need to to do this here
// Need to to do this here
_ = copy(redemptionHash[:], redemptionHashBytes)
emptyRedemptionProofs = []*[20]byte{}
redemptionProofs = append(emptyRedemptionProofs, &redemptionHash)
@ -20,19 +20,19 @@ var (
)
func TestHTLCSettleRequestEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, htlcSettleRequest, htlcSettleRequestSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewHTLCSettleRequest()
DeserializeTest(t, s, newMessage, htlcSettleRequest)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, htlcSettleRequest, htlcSettleRequestSerializedMessage)
}

View File

@ -5,19 +5,19 @@ import (
"io"
)
//Multiple Clearing Requests are possible by putting this inside an array of
//clearing requests
// Multiple Clearing Requests are possible by putting this inside an array of
// clearing requests
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
//ID of this request
// ID of this request
HTLCKey HTLCKey
}
func (c *HTLCTimeoutAccept) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//HTLCKey(8)
// ChannelID(8)
// HTLCKey(8)
err := readElements(r,
&c.ChannelID,
&c.HTLCKey,
@ -29,13 +29,13 @@ func (c *HTLCTimeoutAccept) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new HTLCTimeoutAccept
// Creates a new HTLCTimeoutAccept
func NewHTLCTimeoutAccept() *HTLCTimeoutAccept {
return &HTLCTimeoutAccept{}
}
//Serializes the item from the HTLCTimeoutAccept struct
//Writes the data to w
// Serializes the item from the HTLCTimeoutAccept struct
// Writes the data to w
func (c *HTLCTimeoutAccept) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -53,13 +53,13 @@ func (c *HTLCTimeoutAccept) Command() uint32 {
}
func (c *HTLCTimeoutAccept) MaxPayloadLength(uint32) uint32 {
//16
// 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 {
//We're good!
// We're good!
return nil
}

View File

@ -14,19 +14,19 @@ var (
)
func TestHTLCTimeoutAcceptEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, htlcTimeoutAccept, htlcTimeoutAcceptSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewHTLCTimeoutAccept()
DeserializeTest(t, s, newMessage, htlcTimeoutAccept)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, htlcTimeoutAccept, htlcTimeoutAcceptSerializedMessage)
}

View File

@ -5,19 +5,19 @@ import (
"io"
)
//Multiple Clearing Requests are possible by putting this inside an array of
//clearing requests
// Multiple Clearing Requests are possible by putting this inside an array of
// clearing requests
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
//ID of this request
// ID of this request
HTLCKey HTLCKey
}
func (c *HTLCTimeoutRequest) Decode(r io.Reader, pver uint32) error {
//ChannelID(8)
//HTLCKey(8)
// ChannelID(8)
// HTLCKey(8)
err := readElements(r,
&c.ChannelID,
&c.HTLCKey,
@ -29,13 +29,13 @@ func (c *HTLCTimeoutRequest) Decode(r io.Reader, pver uint32) error {
return nil
}
//Creates a new HTLCTimeoutRequest
// Creates a new HTLCTimeoutRequest
func NewHTLCTimeoutRequest() *HTLCTimeoutRequest {
return &HTLCTimeoutRequest{}
}
//Serializes the item from the HTLCTimeoutRequest struct
//Writes the data to w
// Serializes the item from the HTLCTimeoutRequest struct
// Writes the data to w
func (c *HTLCTimeoutRequest) Encode(w io.Writer, pver uint32) error {
err := writeElements(w,
c.ChannelID,
@ -53,13 +53,13 @@ func (c *HTLCTimeoutRequest) Command() uint32 {
}
func (c *HTLCTimeoutRequest) MaxPayloadLength(uint32) uint32 {
//16
// 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 {
//We're good!
// We're good!
return nil
}

View File

@ -14,19 +14,19 @@ var (
)
func TestHTLCTimeoutRequestEncodeDecode(t *testing.T) {
//All of these types being passed are of the message interface type
//Test serialization, runs: message.Encode(b, 0)
//Returns bytes
//Compares the expected serialized string from the original
// All of these types being passed are of the message interface type
// Test serialization, runs: message.Encode(b, 0)
// Returns bytes
// Compares the expected serialized string from the original
s := SerializeTest(t, htlcTimeoutRequest, htlcTimeoutRequestSerializedString, filename)
//Test deserialization, runs: message.Decode(s, 0)
//Makes sure the deserialized struct is the same as the original
// Test deserialization, runs: message.Decode(s, 0)
// Makes sure the deserialized struct is the same as the original
newMessage := NewHTLCTimeoutRequest()
DeserializeTest(t, s, newMessage, htlcTimeoutRequest)
//Test message using Message interface
//Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
//Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
// Test message using Message interface
// Serializes into buf: WriteMessage(buf, message, uint32(1), wire.TestNet3)
// Deserializes into msg: _, msg, _ , err := ReadMessage(buf, uint32(1), wire.TestNet3)
MessageSerializeDeserializeTest(t, htlcTimeoutRequest, htlcTimeoutRequestSerializedMessage)
}

View File

@ -13,31 +13,31 @@ import (
var MAX_SLICE_LENGTH = 65535
//Actual pkScript, not redeemScript
// Actual pkScript, not redeemScript
type PkScript []byte
type HTLCKey uint64
type CommitHeight uint64
//Subsatoshi amount (Micro-Satoshi, 1/1000th)
//Should be a signed int to account for negative fees
//
//"In any science-fiction movie, anywhere in the galaxy, currency is referred
//to as 'credits.'"
// --Sam Humphries. Ebert, Roger (1999). Ebert's bigger little movie
// glossary. Andrews McMeel. p. 172.
//
//https://en.wikipedia.org/wiki/List_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
type CreditsAmount int32 //Credits (XCB, accountants should use XCB :^)
//US Display format: 1 BTC = 100,000,000'000 XCB
//Or in BTC = 1.00000000'000
// Subsatoshi amount (Micro-Satoshi, 1/1000th)
// Should be a signed int to account for negative fees
//
// "In any science-fiction movie, anywhere in the galaxy, currency is referred
// to as 'credits.'"
// --Sam Humphries. Ebert, Roger (1999). Ebert's bigger little movie
// glossary. Andrews McMeel. p. 172.
//
// https:// en.wikipedia.org/wiki/List_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
type CreditsAmount int32 // Credits (XCB, accountants should use XCB :^)
// US Display format: 1 BTC = 100,000,000'000 XCB
// Or in BTC = 1.00000000'000
//Writes the big endian representation of element
//Unified function to call when writing different types
//Pre-allocate a byte-array of the correct size for cargo-cult security
//More copies but whatever...
// Writes the big endian representation of element
// Unified function to call when writing different types
// Pre-allocate a byte-array of the correct size for cargo-cult security
// More copies but whatever...
func writeElement(w io.Writer, element interface{}) error {
var err error
switch e := element.(type) {
@ -107,12 +107,12 @@ func writeElement(w io.Writer, element interface{}) error {
if numItems > 65535 {
return fmt.Errorf("Too many []uint64s")
}
//Write the size
// Write the size
err = writeElement(w, uint16(numItems))
if err != nil {
return err
}
//Write the data
// Write the data
for i := 0; i < numItems; i++ {
err = writeElement(w, e[i])
if err != nil {
@ -125,12 +125,12 @@ func writeElement(w io.Writer, element interface{}) error {
if numSigs > 127 {
return fmt.Errorf("Too many signatures!")
}
//Write the size
// Write the size
err = writeElement(w, uint8(numSigs))
if err != nil {
return err
}
//Write the data
// Write the data
for i := 0; i < numSigs; i++ {
err = writeElement(w, e[i])
if err != nil {
@ -144,12 +144,12 @@ func writeElement(w io.Writer, element interface{}) error {
if sigLength > 73 {
return fmt.Errorf("Signature too long!")
}
//Write the size
// Write the size
err = writeElement(w, uint8(sigLength))
if err != nil {
return err
}
//Write the data
// Write the data
_, err = w.Write(sig)
if err != nil {
return err
@ -162,13 +162,13 @@ func writeElement(w io.Writer, element interface{}) error {
}
return nil
case []*[20]byte:
//Get size of slice and dump in slice
// Get size of slice and dump in slice
sliceSize := len(e)
err = writeElement(w, uint16(sliceSize))
if err != nil {
return err
}
//Write in each sequentially
// Write in each sequentially
for _, element := range e {
err = writeElement(w, &element)
if err != nil {
@ -200,12 +200,12 @@ func writeElement(w io.Writer, element interface{}) error {
if sliceLength > MAX_SLICE_LENGTH {
return fmt.Errorf("Slice length too long!")
}
//Write the size
// Write the size
err = writeElement(w, uint16(sliceLength))
if err != nil {
return err
}
//Write the data
// Write the data
_, err = w.Write(e)
if err != nil {
return err
@ -213,16 +213,16 @@ func writeElement(w io.Writer, element interface{}) error {
return nil
case PkScript:
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 {
return fmt.Errorf("PkScript too long!")
}
//Write the size (1-byte)
// Write the size (1-byte)
err = writeElement(w, uint8(scriptLength))
if err != nil {
return err
}
//Write the data
// Write the data
_, err = w.Write(e)
if err != nil {
return err
@ -233,19 +233,19 @@ func writeElement(w io.Writer, element interface{}) error {
if strlen > 65535 {
return fmt.Errorf("String too long!")
}
//Write the size (2-bytes)
// Write the size (2-bytes)
err = writeElement(w, uint16(strlen))
if err != nil {
return err
}
//Write the data
// Write the data
_, err = w.Write([]byte(e))
if err != nil {
return err
}
case []*wire.TxIn:
//Append the unsigned(!!!) txins
//Write the size (1-byte)
// Append the unsigned(!!!) txins
// Write the size (1-byte)
if len(e) > 127 {
return fmt.Errorf("Too many txins")
}
@ -253,8 +253,8 @@ func writeElement(w io.Writer, element interface{}) error {
if err != nil {
return err
}
//Append the actual TxIns (Size: NumOfTxins * 36)
//Do not include the sequence number to eliminate funny business
// Append the actual TxIns (Size: NumOfTxins * 36)
// Do not include the sequence number to eliminate funny business
for _, in := range e {
err = writeElement(w, in)
if err != nil {
@ -263,14 +263,14 @@ func writeElement(w io.Writer, element interface{}) error {
}
return nil
case *wire.TxIn:
//Hash
// Hash
var h [32]byte
copy(h[:], e.PreviousOutPoint.Hash.Bytes())
_, err = w.Write(h[:])
if err != nil {
return err
}
//Index
// Index
var idx [4]byte
binary.BigEndian.PutUint32(idx[:], e.PreviousOutPoint.Index)
_, err = w.Write(idx[:])
@ -381,11 +381,11 @@ func readElement(r io.Reader, element interface{}) error {
if err != nil {
return err
}
//if numItems > 65535 {
// return fmt.Errorf("Too many items in []uint64")
//}
// if numItems > 65535 {
// return fmt.Errorf("Too many items in []uint64")
// }
//Read the number of items
// Read the number of items
var items []uint64
for i := uint16(0); i < numItems; i++ {
var item uint64
@ -407,7 +407,7 @@ func readElement(r io.Reader, element interface{}) error {
return fmt.Errorf("Too many signatures!")
}
//Read that number of signatures
// Read that number of signatures
var sigs []*btcec.Signature
for i := uint8(0); i < numSigs; i++ {
sig := new(btcec.Signature)
@ -430,7 +430,7 @@ func readElement(r io.Reader, element interface{}) error {
return fmt.Errorf("Signature too long!")
}
//Read the sig length
// Read the sig length
l := io.LimitReader(r, int64(sigLength))
sig, err := ioutil.ReadAll(l)
if err != nil {
@ -446,14 +446,14 @@ func readElement(r io.Reader, element interface{}) error {
*e = &*btcecSig
return nil
case *[]*[20]byte:
//How many to read
// How many to read
var sliceSize uint16
err = readElement(r, &sliceSize)
if err != nil {
return err
}
var data []*[20]byte
//Append the actual
// Append the actual
for i := uint16(0); i < sliceSize; i++ {
var element [20]byte
err = readElement(r, &element)
@ -479,20 +479,20 @@ func readElement(r io.Reader, element interface{}) error {
*e = wire.BitcoinNet(binary.BigEndian.Uint32(b[:]))
return nil
case *[]byte:
//Get the blob length first
// Get the blob length first
var blobLength uint16
err = readElement(r, &blobLength)
if err != nil {
return err
}
//Shouldn't need to do this, since it's uint16, but we
//might have a different value for MAX_SLICE_LENGTH...
// Shouldn't need to do this, since it's uint16, but we
// might have a different value for MAX_SLICE_LENGTH...
if int(blobLength) > MAX_SLICE_LENGTH {
return fmt.Errorf("Slice length too long!")
}
//Read the slice length
// Read the slice length
l := io.LimitReader(r, int64(blobLength))
*e, err = ioutil.ReadAll(l)
if err != nil {
@ -503,7 +503,7 @@ func readElement(r io.Reader, element interface{}) error {
}
return nil
case *PkScript:
//Get the script length first
// Get the script length first
var scriptLength uint8
err = readElement(r, &scriptLength)
if err != nil {
@ -514,7 +514,7 @@ func readElement(r io.Reader, element interface{}) error {
return fmt.Errorf("PkScript too long!")
}
//Read the script length
// Read the script length
l := io.LimitReader(r, int64(scriptLength))
*e, err = ioutil.ReadAll(l)
if err != nil {
@ -525,13 +525,13 @@ func readElement(r io.Reader, element interface{}) error {
}
return nil
case *string:
//Get the string length first
// Get the string length first
var strlen uint16
err = readElement(r, &strlen)
if err != nil {
return err
}
//Read the string for the length
// Read the string for the length
l := io.LimitReader(r, int64(strlen))
b, err := ioutil.ReadAll(l)
if len(b) != int(strlen) {
@ -543,7 +543,7 @@ func readElement(r io.Reader, element interface{}) error {
}
return nil
case *[]*wire.TxIn:
//Read the size (1-byte number of txins)
// Read the size (1-byte number of txins)
var numScripts uint8
err = readElement(r, &numScripts)
if err != nil {
@ -553,7 +553,7 @@ func readElement(r io.Reader, element interface{}) error {
return fmt.Errorf("Too many txins")
}
//Append the actual TxIns
// Append the actual TxIns
var txins []*wire.TxIn
for i := uint8(0); i < numScripts; i++ {
outpoint := new(wire.OutPoint)
@ -567,7 +567,7 @@ func readElement(r io.Reader, element interface{}) error {
*e = *&txins
return nil
case **wire.TxIn:
//Hash
// Hash
var h [32]byte
_, err = io.ReadFull(r, h[:])
if err != nil {
@ -578,7 +578,7 @@ func readElement(r io.Reader, element interface{}) error {
return err
}
(*e).PreviousOutPoint.Hash = *hash
//Index
// Index
var idxBytes [4]byte
_, err = io.ReadFull(r, idxBytes[:])
if err != nil {
@ -603,31 +603,31 @@ func readElements(r io.Reader, elements ...interface{}) error {
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 {
if &pkScript == nil {
return fmt.Errorf("PkScript should not be empty!")
}
if len(pkScript) == 25 {
//P2PKH
//Begins with OP_DUP OP_HASH160 PUSHDATA(20)
// P2PKH
// Begins with OP_DUP OP_HASH160 PUSHDATA(20)
if !bytes.Equal(pkScript[0:3], []byte{118, 169, 20}) ||
//Ends with OP_EQUALVERIFY OP_CHECKSIG
// Ends with OP_EQUALVERIFY OP_CHECKSIG
!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")
}
} else if len(pkScript) == 23 {
//P2SH
//Begins with OP_HASH160 PUSHDATA(20)
// P2SH
// Begins with OP_HASH160 PUSHDATA(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}) {
//If it's not correct, return error
// If it's not correct, return error
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
}
} else {
//Length not 23 or 25
// Length not 23 or 25
return fmt.Errorf("PkScript only allows P2SH or P2PKH")
}

View File

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

View File

@ -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
import (
@ -9,7 +9,7 @@ import (
"github.com/btcsuite/btcd/wire"
)
// message type identifyer bytes
// message type identifyer bytes
const (
MSGID_FUNDREQUEST = 0x30
MSGID_FUNDRESPONSE = 0x31
@ -23,52 +23,52 @@ const (
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 MaxMessagePayload = 1024 * 1024 * 32 // 32MB
const MaxMessagePayload = 1024 * 1024 * 32 // 32MB
const (
//Funding channel open
// Funding channel open
CmdFundingRequest = uint32(200)
CmdFundingResponse = uint32(210)
CmdFundingSignAccept = uint32(220)
CmdFundingSignComplete = uint32(230)
//Close channel
// Close channel
CmdCloseRequest = uint32(300)
CmdCloseComplete = uint32(310)
//TODO Renumber to 1100
//HTLC payment
// TODO Renumber to 1100
// HTLC payment
CmdHTLCAddRequest = uint32(1000)
CmdHTLCAddAccept = uint32(1010)
CmdHTLCAddReject = uint32(1020)
//TODO Renumber to 1200
//HTLC settlement
// TODO Renumber to 1200
// HTLC settlement
CmdHTLCSettleRequest = uint32(1100)
CmdHTLCSettleAccept = uint32(1110)
//HTLC timeout
// HTLC timeout
CmdHTLCTimeoutRequest = uint32(1300)
CmdHTLCTimeoutAccept = uint32(1310)
//Commitments
// Commitments
CmdCommitSignature = uint32(2000)
CmdCommitRevocation = uint32(2010)
//Error
// Error
CmdErrorGeneric = uint32(4000)
)
//Every message has these functions:
// Every message has these functions:
type Message interface {
Decode(io.Reader, uint32) error //(io, protocol version)
Encode(io.Writer, uint32) error //(io, protocol version)
Command() uint32 //returns ID of the message
MaxPayloadLength(uint32) uint32 //(version) maxpayloadsize
Validate() error //Validates the data struct
Decode(io.Reader, uint32) error // (io, protocol version)
Encode(io.Writer, uint32) error // (io, protocol version)
Command() uint32 // returns ID of the message
MaxPayloadLength(uint32) uint32 // (version) maxpayloadsize
Validate() error // Validates the data struct
String() string
}
@ -116,10 +116,10 @@ func makeEmptyMessage(command uint32) (Message, error) {
}
type messageHeader struct {
//NOTE(j): We don't need to worry about the magic overlapping with
//bitcoin since this is inside encrypted comms anyway, but maybe we
//should use the XOR (^wire.TestNet3) just in case???
magic wire.BitcoinNet //which Blockchain Technology(TM) to use
// NOTE(j): We don't need to worry about the magic overlapping with
// bitcoin since this is inside encrypted comms anyway, but maybe we
// should use the XOR (^wire.TestNet3) just in case???
magic wire.BitcoinNet // which Blockchain Technology(TM) to use
command uint32
length uint32
}
@ -145,12 +145,12 @@ func readMessageHeader(r io.Reader) (int, *messageHeader, error) {
return n, &hdr, nil
}
// 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
// prevent rogue nodes from causing massive memory allocation through forging
// header length.
// 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
// prevent rogue nodes from causing massive memory allocation through forging
// header length.
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
bytesRemaining := n % maxSize
if n > 0 {
@ -170,7 +170,7 @@ func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet wire.BitcoinNet)
cmd := msg.Command()
//Encode the message payload
// Encode the message payload
var bw bytes.Buffer
err := msg.Encode(&bw, pver)
if err != nil {
@ -179,37 +179,37 @@ func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet wire.BitcoinNet)
payload := bw.Bytes()
lenp := len(payload)
//Enforce maximum overall message payload
// Enforce maximum overall message payload
if 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)
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)
}
//Create header for the message
// Create header for the message
hdr := messageHeader{}
hdr.magic = btcnet
hdr.command = cmd
hdr.length = uint32(lenp)
// Encode the header for the message. This is done to a buffer
// rather than directly to the writer since writeElements doesn't
// return the number of bytes written.
// Encode the header for the message. This is done to a buffer
// rather than directly to the writer since writeElements doesn't
// return the number of bytes written.
hw := bytes.NewBuffer(make([]byte, 0, MessageHeaderSize))
writeElements(hw, hdr.magic, hdr.command, hdr.length)
//Write header
// Write header
n, err := w.Write(hw.Bytes())
totalBytes += n
if err != nil {
return totalBytes, err
}
//Write payload
// Write payload
n, err = w.Write(payload)
totalBytes += n
if err != nil {
@ -227,18 +227,18 @@ func ReadMessage(r io.Reader, pver uint32, btcnet wire.BitcoinNet) (int, Message
return totalBytes, nil, nil, err
}
//Enforce maximum message payload
// Enforce maximum message payload
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)
}
//Check for messages in the wrong bitcoin network
// Check for messages in the wrong bitcoin network
if hdr.magic != btcnet {
discardInput(r, hdr.length)
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
msg, err := makeEmptyMessage(command)
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())
}
//Check for maximum length based on the message type
// Check for maximum length based on the message type
mpl := msg.MaxPayloadLength(pver)
if hdr.length > mpl {
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)
}
//Read payload
// Read payload
payload := make([]byte, hdr.length)
n, err = io.ReadFull(r, payload)
totalBytes += n
@ -261,19 +261,19 @@ func ReadMessage(r io.Reader, pver uint32, btcnet wire.BitcoinNet) (int, Message
return totalBytes, nil, nil, err
}
//Unmarshal message
// Unmarshal message
pr := bytes.NewBuffer(payload)
err = msg.Decode(pr, pver)
if err != nil {
return totalBytes, nil, nil, err
}
//Validate the data
// Validate the data
err = msg.Validate()
if err != nil {
return totalBytes, nil, nil, err
}
//We're good!
// We're good!
return totalBytes, msg, payload, nil
}