routing/chainview: add new chainview package for watching subsets of the UTXO set

This commit creates a new package as sub-package within the routing
package: chainview. This package is centered around a single interface
definition: the FilteredChainView. This interface is to be used to
allow the routing package to watch a _subset_ of the UTXO set for any
modifications. In the case of LN, the subset of the UTXO set that we
care about is the set of currently opened channels.

In a future commit the routing package will be modified to remove the
current full block scanning with processing of FilteredBlock
notification, and proper updates to the filter as observed by the
FilteredChainView.
This commit is contained in:
Olaoluwa Osuntokun 2017-05-10 17:02:39 -07:00
parent 2f0639f1af
commit 7bdd7023f4
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
2 changed files with 121 additions and 0 deletions

@ -0,0 +1,67 @@
package chainview
import (
"github.com/roasbeef/btcd/chaincfg/chainhash"
"github.com/roasbeef/btcd/wire"
)
// FilteredChainView repersents a subscription to a certain subset of of the
// UTXO set for a particular chain. This interface is useful from the point of
// view of maintaining an up-to-date channel graph for the Lighting Network.
// The subset of the UTXO to be subscribed is that of all the currently opened
// channels. Each time a channel is closed (the output is spent), a
// notification is to be sent allowing the graph to be pruned.
// NOTE: As FilteredBlocks are generated, it is recommended that
// implementations reclaim the space occupied by newly spent outputs.
type FilteredChainView interface {
// FilteredBlocks returns the channel that filtered blocks are to be
// sent over. Each time a block is connected to the end of a main
// chain, and appropriate FilteredBlock which contains the transactions
// which mutate our watched UTXO set is to be returned.
FilteredBlocks() <-chan *FilteredBlock
// DisconnectedBlocks returns a receive only channel which will be sent
// upon with the empty filtered blocks of blocks which are disconnected
// from the main chain in the case of a re-org.
DisconnectedBlocks() <-chan *FilteredBlock
// UpdateFilter updates the UTXO filter which is to be consulted when
// creating FilteredBlocks to be sent to subscribed clients. This
// method is cumulative meaning repeated calls to this method should
// _expand_ the size of the UTXO sub-set currently being watched. If
// the set updateHeight is _lower_ than the best known height of the
// implementation, then the state should be rewound to ensure all
// relevant notifications are dispatched.
UpdateFilter(ops []wire.OutPoint, updateHeight uint32) error
// FilterBlock takes a block hash, and returns a FilteredBlocks which
// is the result of applying the current registered UTXO sub-set on the
// block corresponding to that block hash.
//
// TODO(roasbeef): make a version that does by height also?
FilterBlock(blockHash *chainhash.Hash) (*FilteredBlock, error)
// Start starts all goroutine necessary for the operation of the
// FilteredChainView implementation.
Start() error
// Stop stops all goroutines which we launched by the prior call to the
// Start method.
Stop() error
}
// FilteredBlock is a block which includes the transactions that modify the
// subscribed sub-set of the UTXO set registered to the current
// FilteredChainView concrete implementation.
type FilteredBlock struct {
// Hash is the hash of the newly filtered block.
Hash chainhash.Hash
// Height is the height of the newly filtered block.
Height uint32
// Transactions is the set of transactions which modify (spend) the
// subscribed UTXO subset.
Transactions []*wire.MsgTx
}

54
routing/chainview/log.go Normal file

@ -0,0 +1,54 @@
package chainview
import (
"errors"
"io"
"github.com/btcsuite/btclog"
)
// log is a logger that is initialized with no output filters. This
// means the package will not perform any logging by default until the caller
// requests it.
var log btclog.Logger
// The default amount of logging is none.
func init() {
DisableLog()
}
// DisableLog disables all library log output. Logging output is disabled
// by default until either UseLogger or SetLogWriter are called.
func DisableLog() {
log = btclog.Disabled
}
// 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.
func UseLogger(logger btclog.Logger) {
log = logger
}
// 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 SetLogWriter(w io.Writer, level string) error {
if w == nil {
return errors.New("nil writer")
}
lvl, ok := btclog.LogLevelFromString(level)
if !ok {
return errors.New("invalid log level")
}
l, err := btclog.NewLoggerFromWriter(w, lvl)
if err != nil {
return err
}
UseLogger(l)
return nil
}