Documentation
¶
Index ¶
- Constants
- Variables
- func AuthDial(localPriv *btcec.PrivateKey, netAddr *lnwire.NetAddress, ...) (wtserver.Peer, error)
- func DeriveSessionKey(keyRing SecretKeyRing, index uint32) (*btcec.PrivateKey, error)
- func DisableLog()
- func UseLogger(logger btclog.Logger)
- type AuthDialer
- type Client
- type Config
- type DB
- type Dial
- type NegotiatorConfig
- type SecretKeyRing
- type SessionNegotiator
- type TowerCandidateIterator
- type TowerClient
Constants ¶
const ( // DefaultReadTimeout specifies the default duration we will wait during // a read before breaking out of a blocking read. DefaultReadTimeout = 15 * time.Second // DefaultWriteTimeout specifies the default duration we will wait during // a write before breaking out of a blocking write. DefaultWriteTimeout = 15 * time.Second // DefaultStatInterval specifies the default interval between logging // metrics about the client's operation. DefaultStatInterval = 30 * time.Second )
Variables ¶
var ( // ErrClientExiting signals that the watchtower client is shutting down. ErrClientExiting = errors.New("watchtower client shutting down") // ErrTowerCandidatesExhausted signals that a TowerCandidateIterator has // cycled through all available candidates. ErrTowerCandidatesExhausted = errors.New("exhausted all tower " + "candidates") // ErrPermanentTowerFailure signals that the tower has reported that it // has permanently failed or the client believes this has happened based // on the tower's behavior. ErrPermanentTowerFailure = errors.New("permanent tower failure") // ErrNegotiatorExiting signals that the SessionNegotiator is shutting // down. ErrNegotiatorExiting = errors.New("negotiator exiting") // ErrNoTowerAddrs signals that the client could not be created because // we have no addresses with which we can reach a tower. ErrNoTowerAddrs = errors.New("no tower addresses") // ErrFailedNegotiation signals that the session negotiator could not // acquire a new session as requested. ErrFailedNegotiation = errors.New("session negotiation unsuccessful") // ErrUnregisteredChannel signals that the client was unable to backup a // revoked state becuase the channel had not been previously registered // with the client. ErrUnregisteredChannel = errors.New("channel is not registered") )
Functions ¶
func AuthDial ¶
func AuthDial(localPriv *btcec.PrivateKey, netAddr *lnwire.NetAddress, dialer func(string, string) (net.Conn, error)) (wtserver.Peer, error)
AuthDial is the watchtower client's default method of dialing.
func DeriveSessionKey ¶
func DeriveSessionKey(keyRing SecretKeyRing, index uint32) (*btcec.PrivateKey, error)
DeriveSessionKey accepts an session key index for an existing session and derives the HD private key to be used to authenticate the brontide transport and authenticate requests sent to the tower. The key will use the keychain.KeyFamilyTowerSession and the provided index, giving a BIP43 derivation path of:
- m/1017'/coinType'/8/0/index
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.
Types ¶
type AuthDialer ¶
type AuthDialer func(localPriv *btcec.PrivateKey, netAddr *lnwire.NetAddress, dialer func(string, string) (net.Conn, error)) (wtserver.Peer, error)
AuthDialer connects to a remote node using an authenticated transport, such as brontide. The dialer argument is used to specify a resolver, which allows this method to be used over Tor or clear net connections.
type Client ¶
type Client interface { // RegisterChannel persistently initializes any channel-dependent // parameters within the client. This should be called during link // startup to ensure that the client is able to support the link during // operation. RegisterChannel(lnwire.ChannelID) error // BackupState initiates a request to back up a particular revoked // state. If the method returns nil, the backup is guaranteed to be // successful unless the client is force quit, or the justice // transaction would create dust outputs when trying to abide by the // negotiated policy. BackupState(*lnwire.ChannelID, *lnwallet.BreachRetribution) error // Start initializes the watchtower client, allowing it process requests // to backup revoked channel states. Start() error // Stop attempts a graceful shutdown of the watchtower client. In doing // so, it will attempt to flush the pipeline and deliver any queued // states to the tower before exiting. Stop() error // ForceQuit will forcibly shutdown the watchtower client. Calling this // may lead to queued states being dropped. ForceQuit() }
Client is the primary interface used by the daemon to control a client's lifecycle and backup revoked states.
type Config ¶
type Config struct { // Signer provides access to the wallet so that the client can sign // justice transactions that spend from a remote party's commitment // transaction. Signer input.Signer // NewAddress generates a new on-chain sweep pkscript. NewAddress func() ([]byte, error) // SecretKeyRing is used to derive the session keys used to communicate // with the tower. The client only stores the KeyLocators internally so // that we never store private keys on disk. SecretKeyRing SecretKeyRing // Dial connects to an addr using the specified net and returns the // connection object. Dial Dial // AuthDialer establishes a brontide connection over an onion or clear // network. AuthDial AuthDialer // DB provides access to the client's stable storage medium. DB DB // Policy is the session policy the client will propose when creating // new sessions with the tower. If the policy differs from any active // sessions recorded in the database, those sessions will be ignored and // new sessions will be requested immediately. Policy wtpolicy.Policy // PrivateTower is the net address of a private tower. The client will // try to create all sessions with this tower. PrivateTower *lnwire.NetAddress // ChainHash identifies the chain that the client is on and for which // the tower must be watching to monitor for breaches. ChainHash chainhash.Hash // ForceQuitDelay is the duration after attempting to shutdown that the // client will automatically abort any pending backups if an unclean // shutdown is detected. If the value is less than or equal to zero, a // call to Stop may block indefinitely. The client can always be // ForceQuit externally irrespective of the chosen parameter. ForceQuitDelay time.Duration // ReadTimeout is the duration we will wait during a read before // breaking out of a blocking read. If the value is less than or equal // to zero, the default will be used instead. ReadTimeout time.Duration // WriteTimeout is the duration we will wait during a write before // breaking out of a blocking write. If the value is less than or equal // to zero, the default will be used instead. WriteTimeout time.Duration // MinBackoff defines the initial backoff applied to connections with // watchtowers. Subsequent backoff durations will grow exponentially up // until MaxBackoff. MinBackoff time.Duration // MaxBackoff defines the maximum backoff applied to conenctions with // watchtowers. If the exponential backoff produces a timeout greater // than this value, the backoff will be clamped to MaxBackoff. MaxBackoff time.Duration }
Config provides the TowerClient with access to the resources it requires to perform its duty. All nillable fields must be non-nil for the tower to be initialized properly.
type DB ¶
type DB interface { // CreateTower initialize an address record used to communicate with a // watchtower. Each Tower is assigned a unique ID, that is used to // amortize storage costs of the public key when used by multiple // sessions. CreateTower(*lnwire.NetAddress) (*wtdb.Tower, error) // LoadTower retrieves a tower by its tower ID. LoadTower(uint64) (*wtdb.Tower, error) // NextSessionKeyIndex reserves a new session key derivation index for a // particular tower id. The index is reserved for that tower until // CreateClientSession is invoked for that tower and index, at which // point a new index for that tower can be reserved. Multiple calls to // this method before CreateClientSession is invoked should return the // same index. NextSessionKeyIndex(uint64) (uint32, error) // CreateClientSession saves a newly negotiated client session to the // client's database. This enables the session to be used across // restarts. CreateClientSession(*wtdb.ClientSession) error // ListClientSessions returns all sessions that have not yet been // exhausted. This is used on startup to find any sessions which may // still be able to accept state updates. ListClientSessions() (map[wtdb.SessionID]*wtdb.ClientSession, error) // FetchChanPkScripts returns a map of all sweep pkscripts for // registered channels. This is used on startup to cache the sweep // pkscripts of registered channels in memory. FetchChanPkScripts() (map[lnwire.ChannelID][]byte, error) // AddChanPkScript inserts a newly generated sweep pkscript for the // given channel. AddChanPkScript(lnwire.ChannelID, []byte) error // MarkBackupIneligible records that the state identified by the // (channel id, commit height) tuple was ineligible for being backed up // under the current policy. This state can be retried later under a // different policy. MarkBackupIneligible(chanID lnwire.ChannelID, commitHeight uint64) error // CommitUpdate writes the next state update for a particular // session, so that we can be sure to resend it after a restart if it // hasn't been ACK'd by the tower. The sequence number of the update // should be exactly one greater than the existing entry, and less that // or equal to the session's MaxUpdates. CommitUpdate(id *wtdb.SessionID, seqNum uint16, update *wtdb.CommittedUpdate) (uint16, error) // AckUpdate records an acknowledgment from the watchtower that the // update identified by seqNum was received and saved. The returned // lastApplied will be recorded. AckUpdate(id *wtdb.SessionID, seqNum, lastApplied uint16) error }
DB abstracts the required database operations required by the watchtower client.
type NegotiatorConfig ¶
type NegotiatorConfig struct { // DB provides access to a persistent storage medium used by the tower // to properly allocate session ephemeral keys and record successfully // negotiated sessions. DB DB // SecretKeyRing allows the client to derive new session private keys // when attempting to negotiate session with a tower. SecretKeyRing SecretKeyRing // Candidates is an abstract set of tower candidates that the negotiator // will traverse serially when attempting to negotiate a new session. Candidates TowerCandidateIterator // Policy defines the session policy that will be proposed to towers // when attempting to negotiate a new session. This policy will be used // across all negotiation proposals for the lifetime of the negotiator. Policy wtpolicy.Policy // Dial initiates an outbound brontide connection to the given address // using a specified private key. The peer is returned in the event of a // successful connection. Dial func(*btcec.PrivateKey, *lnwire.NetAddress) (wtserver.Peer, error) // SendMessage writes a wtwire message to remote peer. SendMessage func(wtserver.Peer, wtwire.Message) error // ReadMessage reads a message from a remote peer and returns the // decoded wtwire message. ReadMessage func(wtserver.Peer) (wtwire.Message, error) // ChainHash the genesis hash identifying the chain for any negotiated // sessions. Any state updates sent to that session should also // originate from this chain. ChainHash chainhash.Hash // MinBackoff defines the initial backoff applied by the session // negotiator after all tower candidates have been exhausted and // reattempting negotiation with the same set of candidates. Subsequent // backoff durations will grow exponentially. MinBackoff time.Duration // MaxBackoff defines the maximum backoff applied by the session // negotiator after all tower candidates have been exhausted and // reattempting negotation with the same set of candidates. If the // exponential backoff produces a timeout greater than this value, the // backoff duration will be clamped to MaxBackoff. MaxBackoff time.Duration }
NegotiatorConfig provides access to the resources required by a SessionNegotiator to faithfully carry out its duties. All nil-able field must be initialized.
type SecretKeyRing ¶
type SecretKeyRing interface { // DerivePrivKey derives the private key from the root seed using a // key descriptor specifying the key's derivation path. DerivePrivKey(loc keychain.KeyDescriptor) (*btcec.PrivateKey, error) }
SecretKeyRing abstracts the ability to derive HD private keys given a description of the derivation path.
type SessionNegotiator ¶
type SessionNegotiator interface { // RequestSession signals to the session negotiator that the client // needs another session. Once the session is negotiated, it should be // returned via NewSessions. RequestSession() // NewSessions is a read-only channel where newly negotiated sessions // will be delivered. NewSessions() <-chan *wtdb.ClientSession // Start safely initializes the session negotiator. Start() error // Stop safely shuts down the session negotiator. Stop() error }
SessionNegotiator is an interface for asynchronously requesting new sessions.
type TowerCandidateIterator ¶
type TowerCandidateIterator interface { // Reset clears any internal iterator state, making previously taken // candidates available as long as they remain in the set. Reset() error // Next returns the next candidate tower. The iterator is not required // to return results in any particular order. If no more candidates are // available, ErrTowerCandidatesExhausted is returned. Next() (*wtdb.Tower, error) }
TowerCandidateIterator provides an abstraction for iterating through possible watchtower addresses when attempting to create a new session.
type TowerClient ¶
type TowerClient struct {
// contains filtered or unexported fields
}
TowerClient is a concrete implementation of the Client interface, offering a non-blocking, reliable subsystem for backing up revoked states to a specified private tower.
func New ¶
func New(config *Config) (*TowerClient, error)
New initializes a new TowerClient from the provide Config. An error is returned if the client could not initialized.
func (*TowerClient) BackupState ¶
func (c *TowerClient) BackupState(chanID *lnwire.ChannelID, breachInfo *lnwallet.BreachRetribution) error
BackupState initiates a request to back up a particular revoked state. If the method returns nil, the backup is guaranteed to be successful unless the:
- client is force quit,
- justice transaction would create dust outputs when trying to abide by the negotiated policy, or
- breached outputs contain too little value to sweep at the target sweep fee rate.
func (*TowerClient) ForceQuit ¶
func (c *TowerClient) ForceQuit()
ForceQuit idempotently initiates an unclean shutdown of the watchtower client. This should only be executed if Stop is unable to exit cleanly.
func (*TowerClient) RegisterChannel ¶
func (c *TowerClient) RegisterChannel(chanID lnwire.ChannelID) error
RegisterChannel persistently initializes any channel-dependent parameters within the client. This should be called during link startup to ensure that the client is able to support the link during operation.
func (*TowerClient) Start ¶
func (c *TowerClient) Start() error
Start initializes the watchtower client by loading or negotiating an active session and then begins processing backup tasks from the request pipeline.
func (*TowerClient) Stop ¶
func (c *TowerClient) Stop() error
Stop idempotently initiates a graceful shutdown of the watchtower client.