lnwallet

package
v0.2.1-alpha Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2017 License: MIT Imports: 32 Imported by: 0

README

lnwallet

Build Status MIT licensed GoDoc

The lnwallet package implements an abstracted wallet controller that is able to drive channel funding workflows, a number of script utilities, witness generation functions for the various Lightning scripts, revocation key derivation, and the commitment update state machine.

The package is used within lnd as the core wallet of the daemon. The wallet itself is composed of several distinct interfaces that decouple the implementation of things like signing and blockchain access. This separation allows new WalletController implementations to be be easily dropped into lnd without disrupting the code base. A series of integration tests at the interface level are also in place to ensure conformance of the implementation with the interface.

Installation and Updating

$ go get -u github.com/lightningnetwork/lnd/lnwallet

Documentation

Index

Constants

View Source
const (
	// Add is an update type that adds a new HTLC entry into the log.
	// Either side can add a new pending HTLC by adding a new Add entry
	// into their update log.
	Add updateType = iota

	// Fail is an update type which removes a prior HTLC entry from the
	// log. Adding a Fail entry to ones log will modify the _remote_
	// parties update log once a new commitment view has been evaluated
	// which contains the Fail entry.
	Fail

	// Settle is an update type which settles a prior HTLC crediting the
	// balance of the receiving node. Adding a Settle entry to a log will
	// result in the settle entry being removed on the log as well as the
	// original add entry from the remote party's log after the next state
	// transition.
	Settle
)
View Source
const (

	// P2WSHSize 34 bytes
	//	- OP_0: 1 byte
	//	- OP_DATA: 1 byte (WitnessScriptSHA256 length)
	//	- WitnessScriptSHA256: 32 bytes
	P2WSHSize = 1 + 1 + 32

	// P2WPKHSize 22 bytes
	//	- OP_0: 1 byte
	//	- OP_DATA: 1 byte (PublicKeyHASH160 length)
	//	- PublicKeyHASH160: 20 bytes
	P2WPKHSize = 1 + 1 + 20

	// MultiSigSize 71 bytes
	//	- OP_2: 1 byte
	//	- OP_DATA: 1 byte (pubKeyAlice length)
	//	- pubKeyAlice: 33 bytes
	//	- OP_DATA: 1 byte (pubKeyBob length)
	//	- pubKeyBob: 33 bytes
	//	- OP_2: 1 byte
	//	- OP_CHECKMULTISIG: 1 byte
	MultiSigSize = 1 + 1 + 33 + 1 + 33 + 1 + 1

	// WitnessSize 222 bytes
	//	- NumberOfWitnessElements: 1 byte
	//	- NilLength: 1 byte
	//	- sigAliceLength: 1 byte
	//	- sigAlice: 73 bytes
	//	- sigBobLength: 1 byte
	//	- sigBob: 73 bytes
	//	- WitnessScriptLength: 1 byte
	//	- WitnessScript (MultiSig)
	WitnessSize = 1 + 1 + 1 + 73 + 1 + 73 + 1 + MultiSigSize

	// FundingInputSize 41 bytes
	//	- PreviousOutPoint:
	//		- Hash: 32 bytes
	//		- Index: 4 bytes
	//	- OP_DATA: 1 byte (ScriptSigLength)
	//	- ScriptSig: 0 bytes
	//	- Witness <----	we use "Witness" instead of "ScriptSig" for
	// 			transaction validation, but "Witness" is stored
	// 			separately and cost for it size is smaller. So
	// 			we separate the calculation of ordinary data
	// 			from witness data.
	//	- Sequence: 4 bytes
	FundingInputSize = 32 + 4 + 1 + 4

	// CommitmentDelayOutput 43 bytes
	//	- Value: 8 bytes
	//	- VarInt: 1 byte (PkScript length)
	//	- PkScript (P2WSH)
	CommitmentDelayOutput = 8 + 1 + P2WSHSize

	// CommitmentKeyHashOutput 31 bytes
	//	- Value: 8 bytes
	//	- VarInt: 1 byte (PkScript length)
	//	- PkScript (P2WPKH)
	CommitmentKeyHashOutput = 8 + 1 + P2WPKHSize

	// HTLCSize 43 bytes
	//	- Value: 8 bytes
	//	- VarInt: 1 byte (PkScript length)
	//	- PkScript (PW2SH)
	HTLCSize = 8 + 1 + P2WSHSize

	// WitnessHeaderSize 2 bytes
	//	- Flag: 1 byte
	//	- Marker: 1 byte
	WitnessHeaderSize = 1 + 1

	// BaseCommitmentTxSize 125 43 * num-htlc-outputs bytes
	//	- Version: 4 bytes
	//	- WitnessHeader <---- part of the witness data
	//	- CountTxIn: 1 byte
	//	- TxIn: 41 bytes
	//		FundingInput
	//	- CountTxOut: 1 byte
	//	- TxOut: 74 + 43 * num-htlc-outputs bytes
	//		OutputPayingToThem,
	//		OutputPayingToUs,
	//		....HTLCOutputs...
	//	- LockTime: 4 bytes
	BaseCommitmentTxSize = 4 + 1 + FundingInputSize + 1 +
		CommitmentDelayOutput + CommitmentKeyHashOutput + 4

	// BaseCommitmentTxCost 500 weight
	BaseCommitmentTxCost = blockchain.WitnessScaleFactor * BaseCommitmentTxSize

	// WitnessCommitmentTxCost 224 weight
	WitnessCommitmentTxCost = WitnessHeaderSize + WitnessSize

	// HTLCCost 172 weight
	HTLCCost = blockchain.WitnessScaleFactor * HTLCSize

	// MaxHTLCNumber shows as the maximum number HTLCs which can be
	// included in commitment transaction. This numbers was calculated by
	// Rusty Russel in "BOLT #5: Recommendations for On-chain Transaction
	// Handling", based on the fact that we need to sweep all HTLCs within
	// one penalty transaction.
	MaxHTLCNumber = 1253
)
View Source
const (
	// InitialRevocationWindow is the number of revoked commitment
	// transactions allowed within the commitment chain. This value allows
	// a greater degree of de-synchronization by allowing either parties to
	// extend the other's commitment chain non-interactively, and also
	// serves as a flow control mechanism to a degree.
	InitialRevocationWindow = 1
)
View Source
const (
	// StateHintSize is the total number of bytes used between the sequence
	// number and locktime of the commitment transaction use to encode a hint
	// to the state number of a particular commitment transaction.
	StateHintSize = 6
)

Variables

View Source
var (
	// ErrChanClosing is returned when a caller attempts to close a channel
	// that has already been closed or is in the process of being closed.
	ErrChanClosing = fmt.Errorf("channel is being closed, operation disallowed")

	// ErrNoWindow is returned when revocation window is exausted.
	ErrNoWindow = fmt.Errorf("unable to sign new commitment, the current" +
		" revocation window is exhausted")

	// ErrMaxWeightCost is returned when the cost/weight (see segwit)
	// exceeds the widely used maximum allowed policy weight limit. In this
	// case the commitment transaction can't be propagated through the
	// network.
	ErrMaxWeightCost = fmt.Errorf("commitment transaction exceed max " +
		"available cost")

	// ErrMaxHTLCNumber is returned when a proposed HTLC would exceed the
	// maximum number of allowed HTLC's if committed in a state transition
	ErrMaxHTLCNumber = fmt.Errorf("commitment transaction exceed max " +
		"htlc number")
)
View Source
var (

	// SequenceLockTimeSeconds is the 22nd bit which indicates the lock
	// time is in seconds.
	SequenceLockTimeSeconds = uint32(1 << 22)

	OP_CHECKSEQUENCEVERIFY byte = txscript.OP_NOP3

	// TimelockShift is used to make sure the commitment transaction is
	// spendable by setting the locktime with it so that it is larger than
	// 500,000,000, thus interpreting it as Unix epoch timestamp and not
	// a block height. It is also smaller than the current timestamp which
	// has bit (1 << 30) set, so there is no risk of having the commitment
	// transaction be rejected. This way we can safely use the lower 24 bits
	// of the locktime field for part of the obscured commitment transaction
	// number.
	TimelockShift = uint32(1 << 29)
)
View Source
var ErrNotMine = errors.New("the passed output doesn't belong to the wallet")

ErrNotMine is an error denoting that a WalletController instance is unable to spend a specifid output.

Functions

func CommitSpendNoDelay

func CommitSpendNoDelay(signer Signer, signDesc *SignDescriptor,
	sweepTx *wire.MsgTx) (wire.TxWitness, error)

CommitSpendNoDelay constructs a valid witness allowing a node to spend their settled no-delay output on the counterparty's commitment transaction.

func CommitSpendRevoke

func CommitSpendRevoke(signer Signer, signDesc *SignDescriptor,
	sweepTx *wire.MsgTx) (wire.TxWitness, error)

CommitSpendRevoke constructs a valid witness allowing a node to sweep the settled output of a malicious counterparty who broadcasts a revoked commitment transaction.

func CommitSpendTimeout

func CommitSpendTimeout(signer Signer, signDesc *SignDescriptor,
	sweepTx *wire.MsgTx) (wire.TxWitness, error)

CommitSpendTimeout constructs a valid witness allowing the owner of a particular commitment transaction to spend the output returning settled funds back to themselves after a relative block timeout. In order to properly spend the transaction, the target input's sequence number should be set accordingly based off of the target relative block timeout within the redeem script. Additionally, OP_CSV requires that the version of the transaction spending a pkscript with OP_CSV within it *must* be >= 2.

func CreateCommitTx

func CreateCommitTx(fundingOutput *wire.TxIn, selfKey, theirKey *btcec.PublicKey,
	revokeKey *btcec.PublicKey, csvTimeout uint32, amountToSelf,
	amountToThem, dustLimit btcutil.Amount) (*wire.MsgTx, error)

CreateCommitTx creates a commitment transaction, spending from specified funding output. The commitment transaction contains two outputs: one paying to the "owner" of the commitment transaction which can be spent after a relative block delay or revocation event, and the other paying the the counterparty within the channel, which can be spent immediately.

func CreateCooperativeCloseTx

func CreateCooperativeCloseTx(fundingTxIn *wire.TxIn,
	localDust, remoteDust, ourBalance, theirBalance btcutil.Amount,
	ourDeliveryScript, theirDeliveryScript []byte,
	initiator bool) *wire.MsgTx

CreateCooperativeCloseTx creates a transaction which if signed by both parties, then broadcast cooperatively closes an active channel. The creation of the closure transaction is modified by a boolean indicating if the party constructing the channel is the initiator of the closure. Currently it is expected that the initiator pays the transaction fees for the closing transaction in full.

func DefaultDustLimit

func DefaultDustLimit() btcutil.Amount

DefaultDustLimit is used to calculate the dust HTLC amount which will be send to other node during funding process.

func DeriveRevocationPrivKey

func DeriveRevocationPrivKey(commitPrivKey *btcec.PrivateKey,
	revokePreimage []byte) *btcec.PrivateKey

DeriveRevocationPrivKey derives the revocation private key given a node's commitment private key, and the preimage to a previously seen revocation hash. Using this derived private key, a node is able to claim the output within the commitment transaction of a node in the case that they broadcast a previously revoked commitment transaction.

The private key is derived as follwos:

revokePriv := commitPriv + revokePreimage mod N

Where N is the order of the sub-group.

func DeriveRevocationPubkey

func DeriveRevocationPubkey(commitPubKey *btcec.PublicKey,
	revokePreimage []byte) *btcec.PublicKey

DeriveRevocationPubkey derives the revocation public key given the counterparty's commitment key, and revocation preimage derived via a pseudo-random-function. In the event that we (for some reason) broadcast a revoked commitment transaction, then if the other party knows the revocation preimage, then they'll be able to derive the corresponding private key to this private key by exploiting the homomorphism in the elliptic curve group:

The derivation is performed as follows:

revokeKey := commitKey + revokePoint
          := G*k + G*h
          := G * (k+h)

Therefore, once we divulge the revocation preimage, the remote peer is able to compute the proper private key for the revokeKey by computing:

revokePriv := commitPriv + revokePreimge mod N

Where N is the order of the sub-group.

func DisableLog

func DisableLog()

DisableLog disables all library log output. Logging output is disabled by default until either UseLogger or SetLogWriter are called.

func FindScriptOutputIndex

func FindScriptOutputIndex(tx *wire.MsgTx, script []byte) (bool, uint32)

FindScriptOutputIndex finds the index of the public key script output matching 'script'. Additionally, a boolean is returned indicating if a matching output was found at all.

NOTE: The search stops after the first matching script is found.

func GenFundingPkScript

func GenFundingPkScript(aPub, bPub []byte, amt int64) ([]byte, *wire.TxOut, error)

GenFundingPkScript creates a redeem script, and its matching p2wsh output for the funding transaction.

func GetStateNumHint

func GetStateNumHint(commitTx *wire.MsgTx, obsfucator [StateHintSize]byte) uint64

GetStateNumHint recovers the current state number given a commitment transaction which has previously had the state number encoded within it via setStateNumHint and a shared obsfucator.

See setStateNumHint for further details w.r.t exactly how the state-hints are encoded.

func RegisterWallet

func RegisterWallet(driver *WalletDriver) error

RegisterWallet registers a WalletDriver which is capable of driving a concrete WalletController interface. In the case that this driver has already been registered, an error is returned.

NOTE: This function is safe for concurrent access.

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 SetStateNumHint

func SetStateNumHint(commitTx *wire.MsgTx, stateNum uint64,
	obsfucator [StateHintSize]byte) error

SetStateNumHint encodes the current state number within the passed commitment transaction by re-purposing the locktime and sequence fields in the commitment transaction to encode the obfuscated state number. The state number is encoded using 48 bits. The lower 24 bits of the locktime are the lower 24 bits of the obfuscated state number and the lower 24 bits of the sequence field are the higher 24 bits. Finally before encoding, the obfuscater is XOR'd against the state number in order to hide the exact state number from the PoV of outside parties. TODO(roasbeef): unexport function after bobNode is gone

func SpendMultiSig

func SpendMultiSig(witnessScript, pubA, sigA, pubB, sigB []byte) [][]byte

SpendMultiSig generates the witness stack required to redeem the 2-of-2 p2wsh multi-sig output.

func SupportedWallets

func SupportedWallets() []string

SupportedWallets returns a slice of strings that represents the wallet drivers that have been registered and are therefore supported.

NOTE: This function is safe for concurrent access.

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 AddressType

type AddressType uint8

AddressType is a enum-like type which denotes the possible address types WalletController supports.

const (
	// WitnessPubKey represents a p2wkh address.
	WitnessPubKey AddressType = iota

	// NestedWitnessPubKey represents a p2sh output which is itself a
	// nested p2wkh output.
	NestedWitnessPubKey

	// PubKeyHash represents a regular p2pkh output.
	PubKeyHash
)

type BlockChainIO

type BlockChainIO interface {
	// GetBestBlock returns the current height and block hash of the valid
	// most-work chain the implementation is aware of.
	GetBestBlock() (*chainhash.Hash, int32, error)

	// GetTxOut returns the original output referenced by the passed
	// outpoint.
	GetUtxo(txid *chainhash.Hash, index uint32) (*wire.TxOut, error)

	// GetTransaction returns the full transaction identified by the passed
	// transaction ID.
	GetTransaction(txid *chainhash.Hash) (*wire.MsgTx, error)

	// GetBlockHash returns the hash of the block in the best blockchain
	// at the given height.
	GetBlockHash(blockHeight int64) (*chainhash.Hash, error)

	// GetBlock returns the block in the main chain identified by the given
	// hash.
	GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error)
}

BlockChainIO is a dedicated source which will be used to obtain queries related to the current state of the blockchain. The data returned by each of the defined methods within this interface should always return the most up to date data possible.

TODO(roasbeef): move to diff package perhaps? TODO(roasbeef): move publish txn here?

type BreachRetribution

type BreachRetribution struct {
	// BreachTransaction is the transaction which breached the channel
	// contract by spending from the funding multi-sig with a revoked
	// commitment transaction.
	BreachTransaction *wire.MsgTx

	// RevokedStateNum is the revoked state number which was broadcast.
	RevokedStateNum uint64

	// PendingHTLCs is a slice of the HTLCs which were pending at this
	// point within the channel's history transcript.
	PendingHTLCs []*channeldb.HTLC

	// LocalOutputSignDesc is a SignDescriptor which is capable of
	// generating the signature necessary to sweep the output within the
	// BreachTransaction that pays directly us.
	LocalOutputSignDesc *SignDescriptor

	// LocalOutpoint is the outpoint of the output paying to us (the local
	// party) within the breach transaction.
	LocalOutpoint wire.OutPoint

	// RemoteOutputSignDesc is a SignDescriptor which is capable of
	// generating the signature required to claim the funds as described
	// within the revocation clause of the remote party's commitment
	// output.
	RemoteOutputSignDesc *SignDescriptor

	// RemoteOutpoint is the output of the output paying to the remote
	// party within the breach transaction.
	RemoteOutpoint wire.OutPoint
}

BreachRetribution contains all the data necessary to bring a channel counterparty to justice claiming ALL lingering funds within the channel in the scenario that they broadcast a revoked commitment transaction. A BreachRetribution is created by the closeObserver if it detects an uncooperative close of the channel which uses a revoked commitment transaction. The BreachRetribution is then sent over the ContractBreach channel in order to allow the subscriber of the channel to dispatch justice.

type ChannelContribution

type ChannelContribution struct {
	// FundingOutpoint is the amount of funds contributed to the funding
	// transaction.
	FundingAmount btcutil.Amount

	// Inputs to the funding transaction.
	Inputs []*wire.TxIn

	// ChangeOutputs are the Outputs to be used in the case that the total
	// value of the funding inputs is greater than the total potential
	// channel capacity.
	ChangeOutputs []*wire.TxOut

	// MultiSigKey is the the key to be used for the funding transaction's
	// P2SH multi-sig 2-of-2 output.
	// TODO(roasbeef): replace with CDP
	MultiSigKey *btcec.PublicKey

	// CommitKey is the key to be used for this party's version of the
	// commitment transaction.
	CommitKey *btcec.PublicKey

	// DeliveryAddress is the address to be used for delivery of cleared
	// channel funds in the scenario of a cooperative channel closure.
	DeliveryAddress btcutil.Address

	// RevocationKey is the key to be used in the revocation clause for the
	// initial version of this party's commitment transaction.
	RevocationKey *btcec.PublicKey

	// CsvDelay 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 parameters 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 counterparty. The funding processes 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 necessary 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 necessary items to allow the remote party to build both the funding, and commitment transactions.
  2. ChannelReservation.ProcessContribution/ChannelReservation.ProcessSingleContribution * 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/ChannelReservation.CompleteReservationSingle * The final step in the workflow. The counterparty presents the signatures for all their inputs to the funding transaction, 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 NewChannelReservation

func NewChannelReservation(capacity, fundingAmt btcutil.Amount, minFeeRate btcutil.Amount,
	wallet *LightningWallet, id uint64, numConfs uint16,
	pushSat btcutil.Amount) *ChannelReservation

NewChannelReservation creates a new channel reservation. This function is used only internally by lnwallet. In order to concurrent safety, the creation of all channel reservations should be carried out via the lnwallet.InitChannelReservation interface.

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(fundingInputScripts []*InputScript,
	commitmentSig []byte) (*channeldb.OpenChannel, error)

CompleteReservation 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) CompleteReservationSingle

func (r *ChannelReservation) CompleteReservationSingle(
	revocationKey *btcec.PublicKey, fundingPoint *wire.OutPoint,
	commitSig []byte, obsfucator [StateHintSize]byte) (*channeldb.OpenChannel, error)

CompleteReservationSingle finalizes the pending single funder channel reservation. Using the funding outpoint of the constructed funding transaction, and the initiator's signature for our version of the commitment transaction, we are able to verify the correctness of our committment transaction as crafted by the initiator. Once this method returns, our signature for the initiator's version of the commitment transaction is available via the .OurSignatures() method. As this method should only be called as a response to a single funder channel, only a commitment signature will be populated.

func (*ChannelReservation) FinalFundingTx

func (r *ChannelReservation) FinalFundingTx() *wire.MsgTx

FinalFundingTx returns the finalized, fully signed funding transaction for this reservation.

NOTE: If this reservation was created as the non-initiator to a single funding workflow, then the full funding transaction will not be available. Instead we will only have the final outpoint of the funding transaction.

func (*ChannelReservation) FundingOutpoint

func (r *ChannelReservation) FundingOutpoint() *wire.OutPoint

FundingOutpoint returns the outpoint of the funding transaction.

NOTE: The pointer returned will only be set once the .ProcesContribution() method is called in the case of the initiator of a single funder workflow, and after the .CompleteReservationSingle() method is called in the case of a responder to a single funder workflow.

func (*ChannelReservation) FundingRedeemScript

func (r *ChannelReservation) FundingRedeemScript() []byte

FundingRedeemScript returns the fully populated funding redeem script.

NOTE: This method will only return a non-nil value after either ProcesContribution or ProcessSingleContribution have been executed and returned without error.

func (*ChannelReservation) LocalCommitTx

func (r *ChannelReservation) LocalCommitTx() *wire.MsgTx

LocalCommitTx returns the commitment transaction for the local node involved in this funding 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() ([]*InputScript, []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

ProcessContribution 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) ProcessSingleContribution

func (r *ChannelReservation) ProcessSingleContribution(theirContribution *ChannelContribution) error

ProcessSingleContribution verifies, and records the initiator's contribution to this pending single funder channel. Internally, no further action is taken other than recording the initiator's contribution to the single funder channel.

func (*ChannelReservation) SetTheirDustLimit

func (r *ChannelReservation) SetTheirDustLimit(dustLimit btcutil.Amount)

SetTheirDustLimit set dust limit of the remote party.

func (*ChannelReservation) StateNumObfuscator

func (r *ChannelReservation) StateNumObfuscator() [StateHintSize]byte

StateNumObfuscator returns the bytes to be used to obsfucate the state number hints for all future states of the commitment transaction for this workflow.

NOTE: This value will only be available for a single funder workflow after the CompleteReservation or CompleteReservationSingle methods have been successfully executed.

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() ([]*InputScript, []byte)

TheirSignatures 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().

type Config

type Config struct {
}

Config is a struct which houses configuration parameters which modify the behaviour of LightningWallet.

type ErrInsufficientFunds

type ErrInsufficientFunds struct {
	// contains filtered or unexported fields
}

ErrInsufficientFunds is a type matching the error interface which is returned when coin selection for a new funding transaction fails to due having an insufficient amount of confirmed funds.

func (*ErrInsufficientFunds) Error

func (e *ErrInsufficientFunds) Error() string

type ForceCloseSummary

type ForceCloseSummary struct {
	// CloseTx is the transaction which closed the channel on-chain. If we
	// initiate the force close, then this'll be our latest commitment
	// state. Otherwise, this'll be the state that the remote peer
	// broadcasted on-chain.
	CloseTx *wire.MsgTx

	// SelfOutpoint is the output created by the above close tx which is
	// spendable by us after a relative time delay.
	SelfOutpoint wire.OutPoint

	// SelfOutputMaturity is the relative maturity period before the above
	// output can be claimed.
	SelfOutputMaturity uint32

	// SelfOutputSignDesc is a fully populated sign descriptor capable of
	// generating a valid signature to sweep the self output.
	SelfOutputSignDesc *SignDescriptor
}

ForceCloseSummary describes the final commitment state before the channel is locked-down to initiate a force closure by broadcasting the latest state on-chain. The summary includes all the information required to claim all rightfully owned outputs. TODO(roasbeef): generalize, add HTLC info, etc.

type InputScript

type InputScript struct {
	Witness   [][]byte
	ScriptSig []byte
}

InputScript represents any script inputs required to redeem a previous output. This struct is used rather than just a witness, or scripSig in order to accommodate nested p2sh which utilizes both types of input scripts.

type LightningChannel

type LightningChannel struct {
	sync.RWMutex

	// Capcity is the total capacity of this channel.
	Capacity btcutil.Amount

	LocalDeliveryScript  []byte
	RemoteDeliveryScript []byte

	// FundingWitnessScript is the witness script for the 2-of-2 multi-sig
	// that opened the channel.
	FundingWitnessScript []byte

	// ForceCloseSignal is a channel that is closed to indicate that a
	// local system has initiated a force close by broadcasting the current
	// commitment transaction directly on-chain.
	ForceCloseSignal chan struct{}

	// UnilateralCloseSignal is a channel that is closed to indicate that
	// the remote party has performed a unilateral close by broadcasting
	// their version of the commitment transaction on-chain.
	UnilateralCloseSignal chan struct{}

	// ContractBreach is a channel that is used to communicate the data
	// necessary to fully resolve the channel in the case that a contract
	// breach is detected. A contract breach occurs it is detected that the
	// counterparty has broadcast a prior *revoked* state.
	ContractBreach chan *BreachRetribution

	// LocalFundingKey is the public key under control by the wallet that
	// was used for the 2-of-2 funding output which created this channel.
	LocalFundingKey *btcec.PublicKey

	// RemoteFundingKey is the public key for the remote channel counter
	// party  which used for the 2-of-2 funding output which created this
	// channel.
	RemoteFundingKey *btcec.PublicKey
	// contains filtered or unexported fields
}

LightningChannel implements the state machine which corresponds to the current commitment protocol wire spec. The state machine implemented allows for asynchronous fully desynchronized, batched+pipelined updates to commitment transactions allowing for a high degree of non-blocking bi-directional payment throughput.

In order to allow updates to be fully non-blocking, either side is able to create multiple new commitment states up to a pre-determined window size. This window size is encoded within InitialRevocationWindow. Before the start of a session, both side should send out revocation messages with nil preimages in order to populate their revocation window for the remote party. Ths method .ExtendRevocationWindow() is used to extend the revocation window by a single revocation.

The state machine has for main methods:

  • .SignNextCommitment()
  • Called one one wishes to sign the next commitment, either initiating a new state update, or responding to a received commitment.
  • .ReceiveNewCommitment()
  • Called upon receipt of a new commitment from the remote party. If the new commitment is valid, then a revocation should immediately be generated and sent.
  • .RevokeCurrentCommitment()
  • Revokes the current commitment. Should be called directly after receiving a new commitment.
  • .ReceiveRevocation()
  • Processes a revocation from the remote party. If successful creates a new defacto broadcastable state.

See the individual comments within the above methods for further details.

func NewLightningChannel

func NewLightningChannel(signer Signer, events chainntnfs.ChainNotifier,
	state *channeldb.OpenChannel) (*LightningChannel, error)

NewLightningChannel creates a new, active payment channel given an implementation of the chain notifier, channel database, and the current settled channel state. Throughout state transitions, then channel will automatically persist pertinent state to the database in an efficient manner.

func (*LightningChannel) AddHTLC

func (lc *LightningChannel) AddHTLC(htlc *lnwire.UpdateAddHTLC) (uint64, error)

AddHTLC adds an HTLC to the state machine's local update log. This method should be called when preparing to send an outgoing HTLC.

TODO(roasbeef): check for duplicates below? edge case during restart w/ HTLC persistence

func (*LightningChannel) ChannelPoint

func (lc *LightningChannel) ChannelPoint() *wire.OutPoint

ChannelPoint returns the outpoint of the original funding transaction which created this active channel. This outpoint is used throughout various subsystems to uniquely identify an open channel.

func (*LightningChannel) CompleteCooperativeClose

func (lc *LightningChannel) CompleteCooperativeClose(remoteSig []byte) (*wire.MsgTx, error)

CompleteCooperativeClose completes the cooperative closure of the target active lightning channel. This method should be called in response to the remote node initiating a cooperative channel closure. A fully signed closure transaction is returned. It is the duty of the responding node to broadcast a signed+valid closure transaction to the network.

NOTE: The passed remote sig is expected to be a fully complete signature including the proper sighash byte.

func (*LightningChannel) DeleteState

func (lc *LightningChannel) DeleteState() error

DeleteState deletes all state concerning the channel from the underlying database, only leaving a small summary describing metadata of the channel's lifetime.

func (*LightningChannel) ExtendRevocationWindow

func (lc *LightningChannel) ExtendRevocationWindow() (*lnwire.RevokeAndAck, error)

ExtendRevocationWindow extends our revocation window by a single revocation, increasing the number of new commitment updates the remote party can initiate without our cooperation.

func (*LightningChannel) FailHTLC

func (lc *LightningChannel) FailHTLC(rHash [32]byte) (uint64, error)

FailHTLC attempts to fail a targeted HTLC by its payment hash, inserting an entry which will remove the target log entry within the next commitment update. This method is intended to be called in order to cancel in _incoming_ HTLC.

func (*LightningChannel) ForceClose

func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error)

ForceClose executes a unilateral closure of the transaction at the current lowest commitment height of the channel. Following a force closure, all state transitions, or modifications to the state update logs will be rejected. Additionally, this function also returns a ForceCloseSummary which includes the necessary details required to sweep all the time-locked within the commitment transaction.

TODO(roasbeef): all methods need to abort if in dispute state TODO(roasbeef): method to generate CloseSummaries for when the remote peer does a unilateral close

func (*LightningChannel) FullySynced

func (lc *LightningChannel) FullySynced() bool

FullySynced returns a boolean value reflecting if both commitment chains (remote+local) are fully in sync. Both commitment chains are fully in sync if the tip of each chain includes the latest committed changes from both sides.

func (*LightningChannel) InitCooperativeClose

func (lc *LightningChannel) InitCooperativeClose() ([]byte, *chainhash.Hash, error)

InitCooperativeClose initiates a cooperative closure of an active lightning channel. This method should only be executed once all pending HTLCs (if any) on the channel have been cleared/removed. Upon completion, the source channel will shift into the "closing" state, which indicates that all incoming/outgoing HTLC requests should be rejected. A signature for the closing transaction, and the txid of the closing transaction are returned. The initiator of the channel closure should then watch the blockchain for a confirmation of the closing transaction before considering the channel terminated. In the case of an unresponsive remote party, the initiator can either choose to execute a force closure, or backoff for a period of time, and retry the cooperative closure.

TODO(roasbeef): caller should initiate signal to reject all incoming HTLCs, settle any inflight.

func (*LightningChannel) NextRevocationkey

func (lc *LightningChannel) NextRevocationkey() (*btcec.PublicKey, error)

NextRevocationkey returns the revocation key for the _next_ commitment height. The pubkey returned by this function is required by the remote party to extend our commitment chain with a new commitment.

TODO(roasbeef): after commitment tx re-write add methdod to ingest revocation key

func (*LightningChannel) ReceiveFailHTLC

func (lc *LightningChannel) ReceiveFailHTLC(logIndex uint64) error

ReceiveFailHTLC attempts to cancel a targeted HTLC by its log index, inserting an entry which will remove the target log entry within the next commitment update. This method should be called in response to the upstream party cancelling an outgoing HTLC.

func (*LightningChannel) ReceiveHTLC

func (lc *LightningChannel) ReceiveHTLC(htlc *lnwire.UpdateAddHTLC) (uint64, error)

ReceiveHTLC adds an HTLC to the state machine's remote update log. This method should be called in response to receiving a new HTLC from the remote party.

func (*LightningChannel) ReceiveHTLCSettle

func (lc *LightningChannel) ReceiveHTLCSettle(preimage [32]byte, logIndex uint64) error

ReceiveHTLCSettle attempts to settle an existing outgoing HTLC indexed by an index into the local log. If the specified index doesn't exist within the log, and error is returned. Similarly if the preimage is invalid w.r.t to the referenced of then a distinct error is returned.

func (*LightningChannel) ReceiveNewCommitment

func (lc *LightningChannel) ReceiveNewCommitment(rawSig []byte) error

ReceiveNewCommitment process a signature for a new commitment state sent by the remote party. This method will should be called in response to the remote party initiating a new change, or when the remote party sends a signature fully accepting a new state we've initiated. If we are able to successfully validate the signature, then the generated commitment is added to our local commitment chain. Once we send a revocation for our prior state, then this newly added commitment becomes our current accepted channel state.

func (*LightningChannel) ReceiveRevocation

func (lc *LightningChannel) ReceiveRevocation(revMsg *lnwire.RevokeAndAck) ([]*PaymentDescriptor, error)

ReceiveRevocation processes a revocation sent by the remote party for the lowest unrevoked commitment within their commitment chain. We receive a revocation either during the initial session negotiation wherein revocation windows are extended, or in response to a state update that we initiate. If successful, then the remote commitment chain is advanced by a single commitment, and a log compaction is attempted. In addition, a slice of HTLC's which can be forwarded upstream are returned.

func (*LightningChannel) RevokeCurrentCommitment

func (lc *LightningChannel) RevokeCurrentCommitment() (*lnwire.RevokeAndAck, error)

RevokeCurrentCommitment revokes the next lowest unrevoked commitment transaction in the local commitment chain. As a result the edge of our revocation window is extended by one, and the tail of our local commitment chain is advanced by a single commitment. This now lowest unrevoked commitment becomes our currently accepted state within the channel.

func (*LightningChannel) SettleHTLC

func (lc *LightningChannel) SettleHTLC(preimage [32]byte) (uint64, error)

SettleHTLC attempts to settle an existing outstanding received HTLC. The remote log index of the HTLC settled is returned in order to facilitate creating the corresponding wire message. In the case the supplied preimage is invalid, an error is returned.

func (*LightningChannel) SignNextCommitment

func (lc *LightningChannel) SignNextCommitment() ([]byte, error)

SignNextCommitment signs a new commitment which includes any previous unsettled HTLCs, any new HTLCs, and any modifications to prior HTLCs committed in previous commitment updates. Signing a new commitment decrements the available revocation window by 1. After a successful method call, the remote party's commitment chain is extended by a new commitment which includes all updates to the HTLC log prior to this method invocation.

func (*LightningChannel) StateSnapshot

func (lc *LightningChannel) StateSnapshot() *channeldb.ChannelSnapshot

StateSnapshot returns a snapshot of the current fully committed state within the channel.

func (*LightningChannel) Stop

func (lc *LightningChannel) Stop()

Stop gracefully shuts down any active goroutines spawned by the LightningChannel during regular duties.

type LightningWallet

type LightningWallet struct {

	// A wrapper around a namespace within boltdb reserved for ln-based
	// wallet metadata. See the 'channeldb' package for further
	// information.
	ChannelDB *channeldb.DB

	// wallet is the the core wallet, all non Lightning Network specific
	// interaction is proxied to the internal wallet.
	WalletController

	// Signer is the wallet's current Signer implementation. This Signer is
	// used to generate signature for all inputs to potential funding
	// transactions, as well as for spends from the funding transaction to
	// update the commitment state.
	Signer Signer

	// ChainIO is an instance of the BlockChainIO interface. ChainIO is
	// used to lookup the existence of outputs within the UTXO set.
	ChainIO BlockChainIO
	// 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 independent 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 dependent 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(cdb *channeldb.DB, notifier chainntnfs.ChainNotifier,
	wallet WalletController, signer Signer, bio BlockChainIO,
	netParams *chaincfg.Params) (*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.

NOTE: The passed channeldb, and ChainNotifier should already be fully initialized/started before being passed as a function arugment.

func (*LightningWallet) ActiveReservations

func (l *LightningWallet) ActiveReservations() []*ChannelReservation

ActiveReservations returns a slice of all the currently active (non-cancalled) reservations.

func (*LightningWallet) GetIdentitykey

func (l *LightningWallet) GetIdentitykey() (*btcec.PrivateKey, error)

GetIdentitykey returns the identity private key of the wallet. TODO(roasbeef): should be moved elsewhere

func (*LightningWallet) InitChannelReservation

func (l *LightningWallet) InitChannelReservation(capacity,
	ourFundAmt btcutil.Amount, theirID *btcec.PublicKey,
	theirAddr *net.TCPAddr, numConfs uint16,
	csvDelay uint32, ourDustLimit btcutil.Amount,
	pushSat btcutil.Amount) (*ChannelReservation, error)

InitChannelReservation kicks off the 3-step workflow required to successfully 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 successful, a ChannelReservation containing our completed contribution is returned. Our contribution contains all the items necessary to allow the counterparty to build the funding transaction, and both versions of the commitment transaction. Otherwise, an error occurred 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) LockedOutpoints

func (l *LightningWallet) LockedOutpoints() []*wire.OutPoint

LockedOutpoints returns a list of all currently locked outpoint.

func (*LightningWallet) ResetReservations

func (l *LightningWallet) ResetReservations()

ResetReservations reset the volatile wallet state which trakcs all currently active reservations.

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 MessageSigner

type MessageSigner struct {
	// contains filtered or unexported fields
}

MessageSigner is used for creation the signatures using the node identity key. By message we mean the whole range of data that might require our approve, starting from node, channel, channel update announcements and ending by user data.

func NewMessageSigner

func NewMessageSigner(key *btcec.PrivateKey) *MessageSigner

NewMessageSigner returns the new instance of message signer.

func (*MessageSigner) SignData

func (s *MessageSigner) SignData(data []byte) (*btcec.Signature, error)

SignData sign the message with the node private key.

type OpenChannelDetails

type OpenChannelDetails struct {
	// Channel is the active channel created by an instance of a
	// ChannelReservation and the required funding workflow.
	Channel *LightningChannel

	// ConfirmationHeight is the block height within the chain that included
	// the channel.
	ConfirmationHeight uint32

	// TransactionIndex is the index within the confirming block that the
	// transaction resides.
	TransactionIndex uint32
}

OpenChannelDetails wraps the finalized fully confirmed channel which resulted from a ChannelReservation instance with details concerning exactly _where_ in the chain the channel was ultimately opened.

type PaymentDescriptor

type PaymentDescriptor struct {
	// RHash is the payment hash for this HTLC. The HTLC can be settled iff
	// the preimage to this hash is presented.
	RHash PaymentHash

	// RPreimage is the preimage that settles the HTLC pointed to wthin the
	// log by the ParentIndex.
	RPreimage PaymentHash

	// Timeout is the absolute timeout in blocks, after which this HTLC
	// expires.
	Timeout uint32

	// Amount is the HTLC amount in satoshis.
	Amount btcutil.Amount

	// Index is the log entry number that his HTLC update has within the
	// log. Depending on if IsIncoming is true, this is either an entry the
	// remote party added, or one that we added locally.
	Index uint64

	// ParentIndex is the index of the log entry that this HTLC update
	// settles or times out.
	ParentIndex uint64

	// Payload is an opaque blob which is used to complete multi-hop
	// routing.
	Payload []byte

	// EntryType denotes the exact type of the PaymentDescriptor. In the
	// case of a Timeout, or Settle type, then the Parent field will point
	// into the log to the HTLC being modified.
	EntryType updateType
	// contains filtered or unexported fields
}

PaymentDescriptor represents a commitment state update which either adds, settles, or removes an HTLC. PaymentDescriptors encapsulate all necessary metadata w.r.t to an HTLC, and additional data pairing a settle message to the original added HTLC. TODO(roasbeef): LogEntry interface??

  • need to separate attrs for cancel/add/settle

type PaymentHash

type PaymentHash [32]byte

PaymentHash represents the sha256 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 SignDescriptor

type SignDescriptor struct {
	// Pubkey is the public key to which the signature should be generated
	// over. The Signer should then generate a signature with the private
	// key corresponding to this public key.
	PubKey *btcec.PublicKey

	// PrivateTweak is a scalar value that should be added to the private
	// key corresponding to the above public key to obtain the private key
	// to be used to sign this input. This value is typically a leaf node
	// from the revocation tree.
	//
	// NOTE: If this value is nil, then the input can be signed using only
	// the above public key.
	PrivateTweak []byte

	// WitnessScript is the full script required to properly redeem the
	// output. This field will only be populated if a p2wsh or a p2sh
	// output is being signed.
	WitnessScript []byte

	// Output is the target output which should be signed. The PkScript and
	// Value fields within the output should be properly populated,
	// otherwise an invalid signature may be generated.
	Output *wire.TxOut

	// HashType is the target sighash type that should be used when
	// generating the final sighash, and signature.
	HashType txscript.SigHashType

	// SigHashes is the pre-computed sighash midstate to be used when
	// generating the final sighash for signing.
	SigHashes *txscript.TxSigHashes

	// InputIndex is the target input within the transaction that should be
	// signed.
	InputIndex int
}

SignDescriptor houses the necessary information required to successfully sign a given output. This struct is used by the Signer interface in order to gain access to critical data needed to generate a valid signature.

type Signer

type Signer interface {
	// SignOutputRaw generates a signature for the passed transaction
	// according to the data within the passed SignDescriptor.
	//
	// NOTE: The resulting signature should be void of a sighash byte.
	SignOutputRaw(tx *wire.MsgTx, signDesc *SignDescriptor) ([]byte, error)

	// ComputeInputScript generates a complete InputIndex for the passed
	// transaction with the signature as defined within the passed
	// SignDescriptor. This method should be capable of generating the
	// proper input script for both regular p2wkh output and p2wkh outputs
	// nested within a regular p2sh output.
	ComputeInputScript(tx *wire.MsgTx, signDesc *SignDescriptor) (*InputScript, error)
}

Signer represents an abstract object capable of generating raw signatures as well as full complete input scripts given a valid SignDescriptor and transaction. This interface fully abstracts away signing paving the way for Signer implementations such as hardware wallets, hardware tokens, HSM's, or simply a regular wallet.

type TransactionDetail

type TransactionDetail struct {
	// Hash is the transaction hash of the transaction.
	Hash chainhash.Hash

	// Value is the net value of this transaction (in satoshis) from the
	// PoV of the wallet. If this transaction purely spends from the
	// wallet's funds, then this value will be negative. Similarly, if this
	// transaction credits the wallet, then this value will be positive.
	Value btcutil.Amount

	// NumConfirmations is the number of confirmations this transaction
	// has. If the transaction is unconfirmed, then this value will be
	// zero.
	NumConfirmations int32

	// BlockHeight is the hash of the block which includes this
	// transaction. Unconfirmed transactions will have a nil value for this
	// field.
	BlockHash *chainhash.Hash

	// BlockHeight is the height of the block including this transaction.
	// Unconfirmed transaction will show a height of zero.
	BlockHeight int32

	// Timestamp is the unix timestamp of the block including this
	// transaction. If the transaction is unconfirmed, then this will be a
	// timestamp of txn creation.
	Timestamp int64

	// TotalFees is the total fee in satoshis paid by this transaction.
	TotalFees int64
}

TransactionDetail describes a transaction with either inputs which belong to the wallet, or has outputs that pay to the wallet.

type TransactionSubscription

type TransactionSubscription interface {
	// ConfirmedTransactions returns a channel which will be sent on as new
	// relevant transactions are confirmed.
	ConfirmedTransactions() chan *TransactionDetail

	// UnconfirmedTransactions returns a channel which will be sent on as
	// new relevant transactions are seen within the network.
	UnconfirmedTransactions() chan *TransactionDetail

	// Cancel finalizes the subscription, cleaning up any resources
	// allocated.
	Cancel()
}

TransactionSubscription is an interface which describes an object capable of receiving notifications of new transaction related to the underlying wallet. TODO(roasbeef): add balance updates?

type Utxo

type Utxo struct {
	Value btcutil.Amount
	wire.OutPoint
}

Utxo is an unspent output denoted by its outpoint, and output value of the original output.

type WalletController

type WalletController interface {
	// FetchInputInfo queries for the WalletController's knowledge of the
	// passed outpoint. If the base wallet determines this output is under
	// its control, then the original txout should be returned. Otherwise,
	// a non-nil error value of ErrNotMine should be returned instead.
	FetchInputInfo(prevOut *wire.OutPoint) (*wire.TxOut, error)

	// 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, witness bool) (btcutil.Amount, error)

	// NewAddress returns the next external or internal address for the
	// wallet dictated by the value of the `change` parameter. If change is
	// true, then an internal address should be used, otherwise an external
	// address should be returned. The type of address returned is dictated
	// by the wallet's capabilities, and may be of type: p2sh, p2pkh,
	// p2wkh, p2wsh, etc.
	NewAddress(addrType AddressType, change 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.
	//
	// NOTE: The wallet MUST watch for on-chain outputs created to a p2wpkh
	// script using keys returned by this function.
	NewRawKey() (*btcec.PublicKey, error)

	// FetchRootKey returns a root key which will be used by the
	// LightningWallet to deterministically generate secrets. The private
	// key returned by this method should remain constant in-between
	// WalletController restarts.
	FetchRootKey() (*btcec.PrivateKey, error)

	// SendOutputs 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, an error
	// should be returned.
	SendOutputs(outputs []*wire.TxOut) (*chainhash.Hash, 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) ([]*Utxo, error)

	// ListTransactionDetails returns a list of all transactions which are
	// relevant to the wallet.
	ListTransactionDetails() ([]*TransactionDetail, error)

	// LockOutpoint marks an outpoint as locked meaning it will no longer
	// be deemed as eligible 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 selection.
	UnlockOutpoint(o wire.OutPoint)

	// PublishTransaction performs cursory validation (dust checks, etc),
	// then finally broadcasts the passed transaction to the Bitcoin network.
	PublishTransaction(tx *wire.MsgTx) error

	// SubscribeTransactions returns a TransactionSubscription client which
	// is capable of receiving async notifications as new transactions
	// related to the wallet are seen within the network, or found in
	// blocks.
	//
	// NOTE: a non-nil error should be returned if notifications aren't
	// supported.
	//
	// TODO(roasbeef): make distinct interface?
	SubscribeTransactions() (TransactionSubscription, error)

	// IsSynced returns a boolean indicating if from the PoV of the wallet,
	// it has fully synced to the current best block in the main chain.
	IsSynced() (bool, error)

	// Start initializes the wallet, making any necessary 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
}

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 across all concrete implementations.

type WalletDriver

type WalletDriver struct {
	// WalletType is a string which uniquely identifes the WalletController
	// that this driver, drives.
	WalletType string

	// New creates a new instance of a concrete WalletController
	// implementation given a variadic set up arguments. The function takes
	// a varidaic number of interface parameters in order to provide
	// initialization flexibility, thereby accommodating several potential
	// WalletController implementations.
	New func(args ...interface{}) (WalletController, error)
}

WalletDriver represents a "driver" for a particular concrete WalletController implementation. A driver is identified by a globally unique string identifier along with a 'New()' method which is responsible for initializing a particular WalletController concrete implementation.

func RegisteredWallets

func RegisteredWallets() []*WalletDriver

RegisteredWallets returns a slice of all currently registered notifiers.

NOTE: This function is safe for concurrent access.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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