diff --git a/blockchain/indexers/cbfindex.go b/blockchain/indexers/cbfindex.go new file mode 100644 index 000000000..9933ffcac --- /dev/null +++ b/blockchain/indexers/cbfindex.go @@ -0,0 +1,111 @@ +// Copyright (c) 2017 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package indexers + +import ( + "errors" + + "github.com/btcsuite/btcd/blockchain" + "github.com/btcsuite/btcd/database" + "github.com/btcsuite/btcutil" +) + +const ( + // cbfIndexName is the human-readable name for the index. + cbfIndexName = "committed bloom filter index" +) + +var ( + // cbfIndexKey is the name of the db bucket used to house the + // block hash -> CBF index. + cbfIndexKey = []byte("cbfbyhashidx") + + // errNoCBFEntry is an error that indicates a requested entry does + // not exist in the CBF index. + errCBFEntry = errors.New("no entry in the block ID index") +) + +// The serialized format for keys and values in the block hash to CBF bucket is: +// = +// +// Field Type Size +// hash chainhash.Hash 32 bytes +// CBF []byte variable +// ----- +// Total: > 32 bytes + +// CBFIndex implements a CBF by hash index. +type CBFIndex struct { + db database.DB +} + +// Ensure the CBFIndex type implements the Indexer interface. +var _ Indexer = (*CBFIndex)(nil) + +// Init initializes the hash-based CBF index. +// +// This is part of the Indexer interface. +func (idx *CBFIndex) Init() error { + return nil +} + +// Key returns the database key to use for the index as a byte slice. +// +// This is part of the Indexer interface. +func (idx *CBFIndex) Key() []byte { + return cbfIndexKey +} + +// Name returns the human-readable name of the index. +// +// This is part of the Indexer interface. +func (idx *CBFIndex) Name() string { + return cbfIndexName +} + +// Create is invoked when the indexer manager determines the index needs +// to be created for the first time. It creates the buckets for the hash-based +// CBF index. +// +// This is part of the Indexer interface. +func (idx *CBFIndex) Create(dbTx database.Tx) error { + meta := dbTx.Metadata() + _, err := meta.CreateBucket(cbfIndexKey) + return err +} + +// ConnectBlock is invoked by the index manager when a new block has been +// connected to the main chain. This indexer adds a hash-to-CBF mapping for +// every passed block. +// +// This is part of the Indexer interface. +func (idx *CBFIndex) ConnectBlock(dbTx database.Tx, block *btcutil.Block, view *blockchain.UtxoViewpoint) error { + return nil +} + +// DisconnectBlock is invoked by the index manager when a block has been +// disconnected from the main chain. This indexer removes the hash-to-CBF +// mapping for every passed block. +// +// This is part of the Indexer interface. +func (idx *CBFIndex) DisconnectBlock(dbTx database.Tx, block *btcutil.Block, view *blockchain.UtxoViewpoint) error { + return nil +} + +// NewCBFIndex returns a new instance of an indexer that is used to create a +// mapping of the hashes of all blocks in the blockchain to their respective +// committed bloom filters. +// +// It implements the Indexer interface which plugs into the IndexManager that in +// turn is used by the blockchain package. This allows the index to be +// seamlessly maintained along with the chain. +func NewCBFIndex(db database.DB) *CBFIndex { + return &CBFIndex{db: db} +} + +// DropCBFIndex drops the CBF index from the provided database if exists. +func DropCBFIndex(db database.DB) error { + return dropIndex(db, cbfIndexKey, cbfIndexName) +}