github.com/btcsuite/btcd@v0.24.0/blockchain/indexers/common.go (about) 1 // Copyright (c) 2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 /* 6 Package indexers implements optional block chain indexes. 7 */ 8 package indexers 9 10 import ( 11 "encoding/binary" 12 "errors" 13 14 "github.com/btcsuite/btcd/blockchain" 15 "github.com/btcsuite/btcd/btcutil" 16 "github.com/btcsuite/btcd/database" 17 ) 18 19 var ( 20 // byteOrder is the preferred byte order used for serializing numeric 21 // fields for storage in the database. 22 byteOrder = binary.LittleEndian 23 24 // errInterruptRequested indicates that an operation was cancelled due 25 // to a user-requested interrupt. 26 errInterruptRequested = errors.New("interrupt requested") 27 ) 28 29 // NeedsInputser provides a generic interface for an indexer to specify the it 30 // requires the ability to look up inputs for a transaction. 31 type NeedsInputser interface { 32 NeedsInputs() bool 33 } 34 35 // Indexer provides a generic interface for an indexer that is managed by an 36 // index manager such as the Manager type provided by this package. 37 type Indexer interface { 38 // Key returns the key of the index as a byte slice. 39 Key() []byte 40 41 // Name returns the human-readable name of the index. 42 Name() string 43 44 // Create is invoked when the indexer manager determines the index needs 45 // to be created for the first time. 46 Create(dbTx database.Tx) error 47 48 // Init is invoked when the index manager is first initializing the 49 // index. This differs from the Create method in that it is called on 50 // every load, including the case the index was just created. 51 Init() error 52 53 // ConnectBlock is invoked when a new block has been connected to the 54 // main chain. The set of output spent within a block is also passed in 55 // so indexers can access the pevious output scripts input spent if 56 // required. 57 ConnectBlock(database.Tx, *btcutil.Block, []blockchain.SpentTxOut) error 58 59 // DisconnectBlock is invoked when a block has been disconnected from 60 // the main chain. The set of outputs scripts that were spent within 61 // this block is also returned so indexers can clean up the prior index 62 // state for this block 63 DisconnectBlock(database.Tx, *btcutil.Block, []blockchain.SpentTxOut) error 64 } 65 66 // AssertError identifies an error that indicates an internal code consistency 67 // issue and should be treated as a critical and unrecoverable error. 68 type AssertError string 69 70 // Error returns the assertion error as a huma-readable string and satisfies 71 // the error interface. 72 func (e AssertError) Error() string { 73 return "assertion failed: " + string(e) 74 } 75 76 // errDeserialize signifies that a problem was encountered when deserializing 77 // data. 78 type errDeserialize string 79 80 // Error implements the error interface. 81 func (e errDeserialize) Error() string { 82 return string(e) 83 } 84 85 // isDeserializeErr returns whether or not the passed error is an errDeserialize 86 // error. 87 func isDeserializeErr(err error) bool { 88 _, ok := err.(errDeserialize) 89 return ok 90 } 91 92 // internalBucket is an abstraction over a database bucket. It is used to make 93 // the code easier to test since it allows mock objects in the tests to only 94 // implement these functions instead of everything a database.Bucket supports. 95 type internalBucket interface { 96 Get(key []byte) []byte 97 Put(key []byte, value []byte) error 98 Delete(key []byte) error 99 } 100 101 // interruptRequested returns true when the provided channel has been closed. 102 // This simplifies early shutdown slightly since the caller can just use an if 103 // statement instead of a select. 104 func interruptRequested(interrupted <-chan struct{}) bool { 105 select { 106 case <-interrupted: 107 return true 108 default: 109 } 110 111 return false 112 }