blockchain/indexers: Store filter hashes with cfindex.
This commit is contained in:
parent
d07fd2f333
commit
e617483b44
1 changed files with 57 additions and 24 deletions
|
@ -44,7 +44,18 @@ var (
|
||||||
[]byte("cf1headerbyhashidx"),
|
[]byte("cf1headerbyhashidx"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cfHashKeys is an array of db bucket names used to house indexes of
|
||||||
|
// block hashes to cf hashes.
|
||||||
|
cfHashKeys = [][]byte{
|
||||||
|
[]byte("cf0hashbyhashidx"),
|
||||||
|
[]byte("cf1hashbyhashidx"),
|
||||||
|
}
|
||||||
|
|
||||||
maxFilterType = uint8(len(cfHeaderKeys) - 1)
|
maxFilterType = uint8(len(cfHeaderKeys) - 1)
|
||||||
|
|
||||||
|
// zeroHash is the chainhash.Hash value of all zero bytes, defined here for
|
||||||
|
// convenience.
|
||||||
|
zeroHash chainhash.Hash
|
||||||
)
|
)
|
||||||
|
|
||||||
// dbFetchFilterIdxEntry retrieves a data blob from the filter index database.
|
// dbFetchFilterIdxEntry retrieves a data blob from the filter index database.
|
||||||
|
@ -118,23 +129,14 @@ func (idx *CfIndex) Create(dbTx database.Tx) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firstHeader := make([]byte, chainhash.HashSize)
|
for _, bucketName := range cfHashKeys {
|
||||||
err = dbStoreFilterIdxEntry(
|
_, err = cfIndexParentBucket.CreateBucket(bucketName)
|
||||||
dbTx,
|
if err != nil {
|
||||||
cfHeaderKeys[wire.GCSFilterRegular],
|
return err
|
||||||
&idx.chainParams.GenesisBlock.Header.PrevBlock,
|
}
|
||||||
firstHeader,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dbStoreFilterIdxEntry(
|
return nil
|
||||||
dbTx,
|
|
||||||
cfHeaderKeys[wire.GCSFilterExtended],
|
|
||||||
&idx.chainParams.GenesisBlock.Header.PrevBlock,
|
|
||||||
firstHeader,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// storeFilter stores a given filter, and performs the steps needed to
|
// storeFilter stores a given filter, and performs the steps needed to
|
||||||
|
@ -148,6 +150,7 @@ func storeFilter(dbTx database.Tx, block *btcutil.Block, f *gcs.Filter,
|
||||||
// Figure out which buckets to use.
|
// Figure out which buckets to use.
|
||||||
fkey := cfIndexKeys[filterType]
|
fkey := cfIndexKeys[filterType]
|
||||||
hkey := cfHeaderKeys[filterType]
|
hkey := cfHeaderKeys[filterType]
|
||||||
|
hashkey := cfHashKeys[filterType]
|
||||||
|
|
||||||
// Start by storing the filter.
|
// Start by storing the filter.
|
||||||
h := block.Hash()
|
h := block.Hash()
|
||||||
|
@ -160,18 +163,34 @@ func storeFilter(dbTx database.Tx, block *btcutil.Block, f *gcs.Filter,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then fetch the previous block's filter header.
|
// Next store the filter hash.
|
||||||
ph := &block.MsgBlock().Header.PrevBlock
|
filterHash, err := builder.GetFilterHash(f)
|
||||||
pfh, err := dbFetchFilterIdxEntry(dbTx, hkey, ph)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = dbStoreFilterIdxEntry(dbTx, hashkey, h, filterHash[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the new block's filter header, and store it.
|
// Then fetch the previous block's filter header.
|
||||||
prevHeader, err := chainhash.NewHash(pfh)
|
var prevHeader *chainhash.Hash
|
||||||
if err != nil {
|
ph := &block.MsgBlock().Header.PrevBlock
|
||||||
return err
|
if ph.IsEqual(&zeroHash) {
|
||||||
|
prevHeader = &zeroHash
|
||||||
|
} else {
|
||||||
|
pfh, err := dbFetchFilterIdxEntry(dbTx, hkey, ph)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the new block's filter header, and store it.
|
||||||
|
prevHeader, err = chainhash.NewHash(pfh)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fh, err := builder.MakeHeaderForFilter(f, *prevHeader)
|
fh, err := builder.MakeHeaderForFilter(f, *prevHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -190,8 +209,8 @@ func (idx *CfIndex) ConnectBlock(dbTx database.Tx, block *btcutil.Block,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := storeFilter(dbTx, block, f,
|
err = storeFilter(dbTx, block, f, wire.GCSFilterRegular)
|
||||||
wire.GCSFilterRegular); err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +242,13 @@ func (idx *CfIndex) DisconnectBlock(dbTx database.Tx, block *btcutil.Block,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, key := range cfHashKeys {
|
||||||
|
err := dbDeleteFilterIdxEntry(dbTx, key, block.Hash())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +285,13 @@ func (idx *CfIndex) FilterHeaderByBlockHash(h *chainhash.Hash,
|
||||||
return idx.entryByBlockHash(cfHeaderKeys, filterType, h)
|
return idx.entryByBlockHash(cfHeaderKeys, filterType, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilterHeaderByBlockHash returns the serialized contents of a block's basic
|
||||||
|
// or extended committed filter hash.
|
||||||
|
func (idx *CfIndex) FilterHashByBlockHash(h *chainhash.Hash,
|
||||||
|
filterType wire.FilterType) ([]byte, error) {
|
||||||
|
return idx.entryByBlockHash(cfHashKeys, filterType, h)
|
||||||
|
}
|
||||||
|
|
||||||
// NewCfIndex returns a new instance of an indexer that is used to create a
|
// NewCfIndex 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
|
// mapping of the hashes of all blocks in the blockchain to their respective
|
||||||
// committed filters.
|
// committed filters.
|
||||||
|
|
Loading…
Add table
Reference in a new issue