lnwallet

package
v0.0.0-...-1e35018 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 13, 2016 License: MIT Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// TODO(roasbeef): make not random value
	MaxPendingPayments = 10
)

Variables

View Source
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
)
View Source
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

func SetLogWriter(w io.Writer, level string) error

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.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

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:

  1. 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.
  2. 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().
  3. 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) CancelHTLC

func (lc *LightningChannel) CancelHTLC() error

CancelHTLC...

func (*LightningChannel) ForceClose

func (lc *LightningChannel) ForceClose() error

ForceClose...

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

type PaymentRequest struct {
	PaymentPreImage [20]byte
	Value           btcutil.Amount
}

PaymentRequest... TODO(roasbeef): serialization (bip 70, QR code, etc)

  • routing handled by upper layer

type WaddrmgrEncryptorDecryptor

type WaddrmgrEncryptorDecryptor struct {
	M *waddrmgr.Manager
}

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL