Documentation ¶
Index ¶
- Constants
- Variables
- type ChannelContribution
- type ChannelReservation
- func (r *ChannelReservation) Cancel() error
- func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte, commitmentSig []byte) error
- func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx
- func (r *ChannelReservation) OurContribution() *ChannelContribution
- func (r *ChannelReservation) OurSignatures() ([][]byte, []byte)
- func (r *ChannelReservation) ProcessContribution(theirContribution *ChannelContribution) error
- func (r *ChannelReservation) TheirContribution() *ChannelContribution
- func (r *ChannelReservation) TheirSignatures() ([][]byte, []byte)
- func (r *ChannelReservation) WaitForChannelOpen() *LightningChannel
- type ChannelUpdate
- func (c *ChannelUpdate) Commit(pastRevokePreimage []byte) error
- func (c *ChannelUpdate) PreviousRevocationPreImage() ([]byte, error)
- func (c *ChannelUpdate) RevocationHash() ([]byte, error)
- func (c *ChannelUpdate) SignCounterPartyCommitment() ([]byte, error)
- func (c *ChannelUpdate) VerifyNewCommitmentSigs(ourSig, theirSig []byte) error
- type Config
- type FundingType
- type LightningChannel
- func (lc *LightningChannel) AddHTLC(timeout uint32, value btcutil.Amount, rHash, revocation PaymentHash, ...) (*ChannelUpdate, error)
- func (lc *LightningChannel) CancelHTLC() error
- func (lc *LightningChannel) ForceClose() error
- func (lc *LightningChannel) OurBalance() btcutil.Amount
- func (lc *LightningChannel) RequestPayment(amount btcutil.Amount) error
- func (lc *LightningChannel) SettleHTLC(rValue [20]byte, newRevocation [20]byte) (*ChannelUpdate, error)
- func (lc *LightningChannel) TheirBalance() btcutil.Amount
- type LightningWallet
- type PaymentDescriptor
- type PaymentHash
- type PaymentRequest
Constants ¶
const (
// TODO(roasbeef): make not random value
MaxPendingPayments = 10
)
Variables ¶
var ( // TODO(roasbeef): remove these and use the one's defined in txscript // within testnet-L. SequenceLockTimeSeconds = uint32(1 << 22) SequenceLockTimeMask = uint32(0x0000ffff) OP_CHECKSEQUENCEVERIFY byte = txscript.OP_NOP3 )
var ( // Error types ErrInsufficientFunds = errors.New("not enough available outputs to " + "create funding transaction") )
Functions ¶
This section is empty.
Types ¶
type ChannelContribution ¶
type ChannelContribution struct { // Amount of funds contributed to the funding transaction. FundingAmount btcutil.Amount // Inputs to the funding transaction. Inputs []*wire.TxIn // Outputs to be used in the case that the total value of the fund // ing inputs is greather than the total potential channel capacity. ChangeOutputs []*wire.TxOut // The key to be used for the funding transaction's P2SH multi-sig // 2-of-2 output. MultiSigKey *btcec.PublicKey // The key to be used for this party's version of the commitment // transaction. CommitKey *btcec.PublicKey // Address to be used for delivery of cleared channel funds in the scenario // of a cooperative channel closure. DeliveryAddress btcutil.Address // Hash to be used as the revocation for the initial version of this // party's commitment transaction. RevocationHash [20]byte // The delay (in blocks) to be used for the pay-to-self output in this // party's version of the commitment transaction. CsvDelay uint32 }
ChannelContribution is the primary constituent of the funding workflow within lnwallet. Each side first exchanges their respective contributions along with channel specific paramters like the min fee/KB. Once contributions have been exchanged, each side will then produce signatures for all their inputs to the funding transactions, and finally a signature for the other party's version of the commitment transaction.
type ChannelReservation ¶
type ChannelReservation struct { // This mutex MUST be held when either reading or modifying any of the // fields below. sync.RWMutex // contains filtered or unexported fields }
ChannelReservation represents an intent to open a lightning payment channel a counterpaty. The funding proceses from reservation to channel opening is a 3-step process. In order to allow for full concurrency during the reservation workflow, resources consumed by a contribution are "locked" themselves. This prevents a number of race conditions such as two funding transactions double-spending the same input. A reservation can also be cancelled, which removes the resources from limbo, allowing another reservation to claim them.
The reservation workflow consists of the following three steps:
- lnwallet.InitChannelReservation * One requests the wallet to allocate the neccessary resources for a channel reservation. These resources a put in limbo for the lifetime of a reservation. * Once completed the reservation will have the wallet's contribution accessible via the .OurContribution() method. This contribution contains the neccessary items to allow the remote party to build both the funding, and commitment transactions.
- ChannelReservation.ProcessContribution * The counterparty presents their contribution to the payment channel. This allows us to build the funding, and commitment transactions ourselves. * We're now able to sign our inputs to the funding transactions, and the counterparty's version of the commitment transaction. * All signatures crafted by us, are now available via .OurSignatures().
- ChannelReservation.CompleteReservation * The final step in the workflow. The counterparty presents the signatures for all their inputs to the funding transation, as well as a signature to our version of the commitment transaction. * We then verify the validity of all signatures before considering the channel "open".
func (*ChannelReservation) Cancel ¶
func (r *ChannelReservation) Cancel() error
Cancel abandons this channel reservation. This method should be called in the scenario that communications with the counterparty break down. Upon cancellation, all resources previously reserved for this pending payment channel are returned to the free pool, allowing subsequent reservations to utilize the now freed resources.
func (*ChannelReservation) CompleteReservation ¶
func (r *ChannelReservation) CompleteReservation(fundingSigs [][]byte, commitmentSig []byte) error
CompleteFundingReservation finalizes the pending channel reservation, transitioning from a pending payment channel, to an open payment channel. All passed signatures to the counterparty's inputs to the funding transaction will be fully verified. Signatures are expected to be passed in sorted order according to BIP-69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki. Additionally, verification is performed in order to ensure that the counterparty supplied a valid signature to our version of the commitment transaction. Once this method returns, caller's should then call .WaitForChannelOpen() which will block until the funding transaction obtains the configured number of confirmations. Once the method unblocks, a LightningChannel instance is returned, marking the channel available for updates.
func (*ChannelReservation) FinalFundingTx ¶
func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx
FinalFundingTx returns the finalized, fully signed funding transaction for this reservation.
func (*ChannelReservation) OurContribution ¶
func (r *ChannelReservation) OurContribution() *ChannelContribution
OurContribution returns the wallet's fully populated contribution to the pending payment channel. See 'ChannelContribution' for further details regarding the contents of a contribution. NOTE: This SHOULD NOT be modified. TODO(roasbeef): make copy?
func (*ChannelReservation) OurSignatures ¶
func (r *ChannelReservation) OurSignatures() ([][]byte, []byte)
OurSignatures retrieves the wallet's signatures to all inputs to the funding transaction belonging to itself, and also a signature for the counterparty's version of the commitment transaction. The signatures for the wallet's inputs to the funding transaction are returned in sorted order according to BIP-69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki. NOTE: These signatures will only be populated after a call to .ProcesContribution()
func (*ChannelReservation) ProcessContribution ¶
func (r *ChannelReservation) ProcessContribution(theirContribution *ChannelContribution) error
ProcesContribution verifies the counterparty's contribution to the pending payment channel. As a result of this incoming message, lnwallet is able to build the funding transaction, and both commitment transactions. Once this message has been processed, all signatures to inputs to the funding transaction belonging to the wallet are available. Additionally, the wallet will generate a signature to the counterparty's version of the commitment transaction.
func (*ChannelReservation) TheirContribution ¶
func (r *ChannelReservation) TheirContribution() *ChannelContribution
TheirContribution returns the counterparty's pending contribution to the payment channel. See 'ChannelContribution' for further details regarding the contents of a contribution. This attribute will ONLY be available after a call to .ProcesContribution(). NOTE: This SHOULD NOT be modified.
func (*ChannelReservation) TheirSignatures ¶
func (r *ChannelReservation) TheirSignatures() ([][]byte, []byte)
OurSignatures returns the counterparty's signatures to all inputs to the funding transaction belonging to them, as well as their signature for the wallet's version of the commitment transaction. This methods is provided for additional verification, such as needed by tests. NOTE: These attributes will be unpopulated before a call to .CompleteReservation().
func (*ChannelReservation) WaitForChannelOpen ¶
func (r *ChannelReservation) WaitForChannelOpen() *LightningChannel
WaitForChannelOpen blocks until the funding transaction for this pending payment channel obtains the configured number of confirmations. Once confirmations have been obtained, a fully initialized LightningChannel instance is returned, allowing for channel updates. NOTE: If this method is called before .CompleteReservation(), it will block indefinitely.
type ChannelUpdate ¶
type ChannelUpdate struct {
// contains filtered or unexported fields
}
ChannelUpdate...
func (*ChannelUpdate) Commit ¶
func (c *ChannelUpdate) Commit(pastRevokePreimage []byte) error
Commit...
func (*ChannelUpdate) PreviousRevocationPreImage ¶
func (c *ChannelUpdate) PreviousRevocationPreImage() ([]byte, error)
PreviousRevocationPreImage...
func (*ChannelUpdate) RevocationHash ¶
func (c *ChannelUpdate) RevocationHash() ([]byte, error)
RevocationHash...
func (*ChannelUpdate) SignCounterPartyCommitment ¶
func (c *ChannelUpdate) SignCounterPartyCommitment() ([]byte, error)
SignCounterPartyCommitment...
func (*ChannelUpdate) VerifyNewCommitmentSigs ¶
func (c *ChannelUpdate) VerifyNewCommitmentSigs(ourSig, theirSig []byte) error
VerifyNewCommitmentSigs...
type Config ¶
type Config struct { DataDir string LogDir string DebugLevel string RpcHost string // localhost:18334 RpcUser string RpcPass string RPCCert string RPCKey string CACert []byte PrivatePass []byte PublicPass []byte HdSeed []byte // Which bitcoin network are we using? NetParams *chaincfg.Params }
Config...
type FundingType ¶
type FundingType uint16
FundingType represents the type of the funding transaction. The type of funding transaction available depends entirely on the level of upgrades to Script on the current network. Across the network it's possible for asymmetric funding types to exist across hop. However, for direct links, the funding type supported by both parties must be identical. The most 'powerful' funding type is SEGWIT. This funding type also assumes that both CSV+CLTV are available on the network. NOTE: Ultimately, this will most likely be deprecated...
const ( // Use SegWit, assumes CSV+CLTV SEGWIT FundingType = iota // Use SIGHASH_NOINPUT, assumes CSV+CLTV SIGHASH // Use CSV without reserve CSV // Use CSV with reserve // Reserve is a permanent amount of funds locked and the capacity. CSV_RESERVE // CLTV with reserve. CLTV_RESERVE )
type LightningChannel ¶
type LightningChannel struct {
// contains filtered or unexported fields
}
LightningChannel... TODO(roasbeef): future peer struct should embed this struct
func (*LightningChannel) AddHTLC ¶
func (lc *LightningChannel) AddHTLC(timeout uint32, value btcutil.Amount, rHash, revocation PaymentHash, payToUs bool) (*ChannelUpdate, error)
AddHTLC... 1. request R_Hash from receiver (only if single hop, would be out of band) 2. propose HTLC
- timeout
- value
- r_hash
- next revocation hash
3. they accept
- their next revocation hash
- their sig for our new commitment tx (verify correctness)
Can buld both new commitment txns at this point 4. we give sigs
- our sigs for their new commitment tx
- the pre-image to our old commitment tx
5. they complete
- the pre-image to their old commitment tx (verify is part of their chain, is pre-image)
func (*LightningChannel) OurBalance ¶
func (lc *LightningChannel) OurBalance() btcutil.Amount
OurBalance...
func (*LightningChannel) RequestPayment ¶
func (lc *LightningChannel) RequestPayment(amount btcutil.Amount) error
RequestPayment...
func (*LightningChannel) SettleHTLC ¶
func (lc *LightningChannel) SettleHTLC(rValue [20]byte, newRevocation [20]byte) (*ChannelUpdate, error)
SettleHTLC... R-VALUE, NEW REVOKE HASH accept, sig
func (*LightningChannel) TheirBalance ¶
func (lc *LightningChannel) TheirBalance() btcutil.Amount
TheirBalance...
type LightningWallet ¶
type LightningWallet struct { // This mutex is to be held when generating external keys to be used // as multi-sig, and commitment keys within the channel. KeyGenMtx sync.RWMutex // A wrapper around a namespace within boltdb reserved for ln-based // wallet meta-data. See the 'channeldb' package for further // information. ChannelDB *channeldb.DB // The core wallet, all non Lightning Network specific interaction is // proxied to the internal wallet. *btcwallet.Wallet // contains filtered or unexported fields }
LightningWallet is a domain specific, yet general Bitcoin wallet capable of executing workflow required to interact with the Lightning Network. It is domain specific in the sense that it understands all the fancy scripts used within the Lightning Network, channel lifetimes, etc. However, it embedds a general purpose Bitcoin wallet within it. Therefore, it is also able to serve as a regular Bitcoin wallet which uses HD keys. The wallet is highly concurrent internally. All communication, and requests towards the wallet are dispatched as messages over channels, ensuring thread safety across all operations. Interaction has been designed independant of any peer-to-peer communication protocol, allowing the wallet to be self-contained and embeddable within future projects interacting with the Lightning Network. NOTE: At the moment the wallet requires a btcd full node, as it's dependant on btcd's websockets notifications as even triggers during the lifetime of a channel. However, once the chainntnfs package is complete, the wallet will be compatible with multiple RPC/notification services such as Electrum, Bitcoin Core + ZeroMQ, etc. Eventually, the wallet won't require a full-node at all, as SPV support is integrated inot btcwallet.
func NewLightningWallet ¶
func NewLightningWallet(config *Config) (*LightningWallet, walletdb.DB, error)
NewLightningWallet creates/opens and initializes a LightningWallet instance. If the wallet has never been created (according to the passed dataDir), first-time setup is executed. TODO(roasbeef): fin...add config
func (*LightningWallet) InitChannelReservation ¶
func (l *LightningWallet) InitChannelReservation(a btcutil.Amount, t FundingType, theirID [32]byte, csvDelay uint32) (*ChannelReservation, error)
InitChannelReservation kicks off the 3-step workflow required to succesfully open a payment channel with a remote node. As part of the funding reservation, the inputs selected for the funding transaction are 'locked'. This ensures that multiple channel reservations aren't double spending the same inputs in the funding transaction. If reservation initialization is succesful, a ChannelReservation containing our completed contribution is returned. Our contribution contains all the items neccessary to allow the counter party to build the funding transaction, and both versions of the commitment transaction. Otherwise, an error occured a nil pointer along with an error are returned.
Once a ChannelReservation has been obtained, two additional steps must be processed before a payment channel can be considered 'open'. The second step validates, and processes the counterparty's channel contribution. The third, and final step verifies all signatures for the inputs of the funding transaction, and that the signature we records for our version of the commitment transaction is valid.
func (*LightningWallet) Shutdown ¶
func (l *LightningWallet) Shutdown() error
Shutdown gracefully stops the wallet, and all active goroutines.
func (*LightningWallet) Startup ¶
func (l *LightningWallet) Startup() error
Startup establishes a connection to the RPC source, and spins up all goroutines required to handle incoming messages.
type PaymentDescriptor ¶
type PaymentDescriptor struct { RHash [20]byte Timeout uint32 Value btcutil.Amount OurRevocation [20]byte // TODO(roasbeef): don't need these? TheirRevocation [20]byte PayToUs bool }
PaymentDescriptor...
type PaymentHash ¶
type PaymentHash [20]byte
PaymentHash presents the hash160 of a random value. This hash is used to uniquely track incoming/outgoing payments within this channel, as well as payments requested by the wallet/daemon.
type PaymentRequest ¶
PaymentRequest... TODO(roasbeef): serialization (bip 70, QR code, etc)
- routing handled by upper layer