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  }