decred.org/dcrwallet/v3@v3.1.0/wallet/udb/cfilters.go (about) 1 // Copyright (c) 2018 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package udb 6 7 import ( 8 "decred.org/dcrwallet/v3/errors" 9 "decred.org/dcrwallet/v3/wallet/walletdb" 10 "github.com/decred/dcrd/chaincfg/chainhash" 11 gcs2 "github.com/decred/dcrd/gcs/v4" 12 "github.com/decred/dcrd/gcs/v4/blockcf2" 13 ) 14 15 // CFilterV2 returns the saved regular compact filter v2 for a block along with 16 // the key necessary to query it for matches. 17 func (s *Store) CFilterV2(dbtx walletdb.ReadTx, blockHash *chainhash.Hash) ([gcs2.KeySize]byte, *gcs2.FilterV2, error) { 18 ns := dbtx.ReadBucket(wtxmgrBucketKey) 19 k, v, err := fetchRawCFilter2(ns, blockHash[:]) 20 if err != nil { 21 return [16]byte{}, nil, err 22 } 23 vc := make([]byte, len(v)) // Copy for FromBytesV2 which stores passed slice 24 copy(vc, v) 25 filter, err := gcs2.FromBytesV2(blockcf2.B, blockcf2.M, vc) 26 if err != nil { 27 return k, nil, err 28 } 29 return k, filter, err 30 } 31 32 // ImportCFiltersV2 imports the given list of cfilters into the wallet, 33 // starting at the provided block height. 34 func (s *Store) ImportCFiltersV2(dbtx walletdb.ReadWriteTx, startHeight int32, filterData [][]byte) error { 35 ns := dbtx.ReadWriteBucket(wtxmgrBucketKey) 36 blockIter := makeReadBlockIterator(ns, startHeight) 37 for i, fd := range filterData { 38 if !blockIter.next() { 39 return errors.E(errors.NotExist, errors.Errorf("block height of %d unknown", startHeight+int32(i))) 40 } 41 42 // Ensure this is actually a valid slice of cfilter data. 43 _, err := gcs2.FromBytesV2(blockcf2.B, blockcf2.M, fd) 44 if err != nil { 45 return err 46 } 47 48 // Find out the key for this filter based on the underlying 49 // block header. 50 bh := blockIter.elem.Hash 51 header, err := fetchRawBlockHeader(ns, keyBlockHeader(&bh)) 52 if err != nil { 53 return err 54 } 55 merkleRoot := extractBlockHeaderMerkleRoot(header) 56 var bcf2Key [gcs2.KeySize]byte 57 copy(bcf2Key[:], merkleRoot) 58 59 // Store the cfilter data and query key. 60 err = putRawCFilter(ns, bh[:], valueRawCFilter2(bcf2Key, fd)) 61 if err != nil { 62 return err 63 } 64 } 65 66 return nil 67 }