Documentation ¶
Index ¶
- Constants
- Variables
- func DisableLog()
- func SetLogWriter(w io.Writer, level string) error
- func UseLogger(logger btclog.Logger)
- 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
- type WaddrmgrEncryptorDecryptor
- type WalletController
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 ¶
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until either UseLogger or SetLogWriter are called.
func SetLogWriter ¶
SetLogWriter uses a specified io.Writer to output package logging info. This allows a caller to direct package logging output without needing a dependency on seelog. If the caller is also using btclog, UseLogger should be used instead.
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 RpcNoTLS bool 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 // 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, cdb *channeldb.DB) (*LightningWallet, 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
type WaddrmgrEncryptorDecryptor ¶
func (*WaddrmgrEncryptorDecryptor) Decrypt ¶
func (w *WaddrmgrEncryptorDecryptor) Decrypt(c []byte) ([]byte, error)
func (*WaddrmgrEncryptorDecryptor) Encrypt ¶
func (w *WaddrmgrEncryptorDecryptor) Encrypt(p []byte) ([]byte, error)
func (*WaddrmgrEncryptorDecryptor) OverheadSize ¶
func (w *WaddrmgrEncryptorDecryptor) OverheadSize() uint32
type WalletController ¶
type WalletController interface { // ConfirmedBalance returns the sum of all the wallet's unspent outputs // that have at least confs confirmations. If confs is set to zero, // then all unspent outputs, including those currently in the mempool // will be included in the final sum. ConfirmedBalance(confs int32) btcutil.Amount // NewAddress returns the next external address for the wallet. The // type of address returned is dictated by the wallet's capabilities, // and may be of type: p2sh, p2pkh, p2wkh, p2wsh, etc. NewAddress(witness bool) (btcutil.Address, error) // NewChangeAddress returns a new change address for the wallet. If the // underlying wallet supports hd key chains, then this address should be // dervied from an internal branch. NewChangeAddress(witness bool) (btcutil.Address, error) // GetPrivKey retrives the underlying private key associated with the // passed address. If the wallet is unable to locate this private key // due to the address not being under control of the wallet, then an // error should be returned. GetPrivKey(a *btcutil.Address) (*btcec.PrivateKey, error) // NewRawKey returns a raw private key controlled by the wallet. These // keys are used for the 2-of-2 multi-sig outputs for funding // transactions, as well as the pub key used for commitment transactions. // TODO(roasbeef): key pool due to cancelled reservations?? NewRawKey() (*btcec.PrivateKey, error) // FetchIdentityKey returns a private key which will be utilized as the // wallet's Lightning Network identity for authentication purposes. // TODO(roasbeef): rotate identity key? FetchIdentityKey() (*btcec.PrivateKey, error) // FundTransaction creates a new unsigned transactions paying to the // passed outputs, possibly using the specified change address. The // includeFee parameter dictates if the wallet should also provide // enough the funds necessary to create an adequate fee or not. FundTransaction(outputs []*wire.TxOut, changeAddr btcutil.Address, includeFee bool) (*wire.MsgTx, error) // SignTransaction performs potentially a sparse, or full signing of // all inputs within the passed transaction that are spendable by the // wallet. SignTransaction(tx *wire.MsgTx) error // BroadcastTransaction performs cursory validation (dust checks, etc), // then finally broadcasts the passed transaction to the Bitcoin network. BroadcastTransaction(tx *wire.MsgTx) error // SendMany funds, signs, and broadcasts a Bitcoin transaction paying // out to the specified outputs. In the case the wallet has insufficient // funds, or the outputs are non-standard, and error should be returned. SendMany(outputs []*wire.TxOut) (*wire.ShaHash, error) // ListUnspentWitness returns all unspent outputs which are version 0 // witness programs. The 'confirms' parameter indicates the minimum // number of confirmations an output needs in order to be returned by // this method. Passing -1 as 'confirms' indicates that even unconfirmed // outputs should be returned. ListUnspentWitness(confirms int32) ([]*wire.OutPoint, error) // LockOutpoint marks an outpoint as locked meaning it will no longer // be deemed as eligble for coin selection. Locking outputs are utilized // in order to avoid race conditions when selecting inputs for usage when // funding a channel. LockOutpoint(o wire.OutPoint) // UnlockOutpoint unlocks an previously locked output, marking it // eligible for coin seleciton. UnlockOutpoint(o wire.OutPoint) // ImportScript imports the serialize public key script, or redeem // script into the wallet's database. Scripts to be imported include // the 2-of-2 script for funding transactions, commitment scripts, // HTLCs scripts, and so on. ImportScript(b []byte) error // Start initializes the wallet, making any neccessary connections, // starting up required goroutines etc. Start() error // Stop signals the wallet for shutdown. Shutdown may entail closing // any active sockets, database handles, stopping goroutines, etc. Stop() error // WaitForShutdown blocks until the wallet finishes the shutdown // procedure triggered by a prior call to Stop(). WaitForShutdown() error }
WalletController defines an abstract interface for controlling a local Pure Go wallet, a local or remote wallet via an RPC mechanism, or possibly even a daemon assisted hardware wallet. This interface serves the purpose of allowing LightningWallet to be seamlessly compatible with several wallets such as: uspv, btcwallet, Bitcoin Core, Electrum, etc. This interface then serves as a "base wallet", with Lightning Network awareness taking place at a "higher" level of abstraction. Essentially, an overlay wallet. Implementors of this interface must closely adhere to the documented behavior of all interface methods in order to ensure identical behavior accross all concrete implementations.