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.
12 "github.com/btcsuite/btcd/blockchain"
13 "github.com/btcsuite/btcd/chaincfg"
14 "github.com/btcsuite/btcd/chaincfg/chainhash"
15 "github.com/btcsuite/btcd/database"
16 "github.com/btcsuite/btcd/txscript"
17 "github.com/btcsuite/btcd/wire"
18 "github.com/btcsuite/btcutil"
22 // addrIndexName is the human-readable name for the index.
23 addrIndexName = "address index"
25 // level0MaxEntries is the maximum number of transactions that are
26 // stored in level 0 of an address index entry. Subsequent levels store
27 // 2^n * level0MaxEntries entries, or in words, double the maximum of
28 // the previous level.
31 // addrKeySize is the number of bytes an address key consumes in the
32 // index. It consists of 1 byte address type + 20 bytes hash160.
35 // levelKeySize is the number of bytes a level key in the address index
36 // consumes. It consists of the address key + 1 byte for the level.
37 levelKeySize = addrKeySize + 1
39 // levelOffset is the offset in the level key which identifes the level.
40 levelOffset = levelKeySize - 1
42 // addrKeyTypePubKeyHash is the address type in an address key which
43 // represents both a pay-to-pubkey-hash and a pay-to-pubkey address.
44 // This is done because both are identical for the purposes of the
46 addrKeyTypePubKeyHash = 0
48 // addrKeyTypeScriptHash is the address type in an address key which
49 // represents a pay-to-script-hash address. This is necessary because
50 // the hash of a pubkey address might be the same as that of a script
52 addrKeyTypeScriptHash = 1
54 // addrKeyTypePubKeyHash is the address type in an address key which
55 // represents a pay-to-witness-pubkey-hash address. This is required
56 // as the 20-byte data push of a p2wkh witness program may be the same
57 // data push used a p2pkh address.
58 addrKeyTypeWitnessPubKeyHash = 2
60 // addrKeyTypeScriptHash is the address type in an address key which
61 // represents a pay-to-witness-script-hash address. This is required,
62 // as p2wsh are distinct from p2sh addresses since they use a new
63 // script template, as well as a 32-byte data push.
64 addrKeyTypeWitnessScriptHash = 3
66 // Size of a transaction entry. It consists of 4 bytes block id + 4
67 // bytes offset + 4 bytes length.
68 txEntrySize = 4 + 4 + 4
72 // addrIndexKey is the key of the address index and the db bucket used
74 addrIndexKey = []byte("txbyaddridx")
76 // errUnsupportedAddressType is an error that is used to signal an
77 // unsupported address type has been used.
78 errUnsupportedAddressType = errors.New("address type is not supported " +
79 "by the address index")
82 // -----------------------------------------------------------------------------
83 // The address index maps addresses referenced in the blockchain to a list of
84 // all the transactions involving that address. Transactions are stored
85 // according to their order of appearance in the blockchain. That is to say
86 // first by block height and then by offset inside the block. It is also
87 // important to note that this implementation requires the transaction index
88 // since it is needed in order to catch up old blocks due to the fact the spent
89 // outputs will already be pruned from the utxo set.
91 // The approach used to store the index is similar to a log-structured merge
92 // tree (LSM tree) and is thus similar to how leveldb works internally.
94 // Every address consists of one or more entries identified by a level starting
95 // from 0 where each level holds a maximum number of entries such that each
96 // subsequent level holds double the maximum of the previous one. In equation
97 // form, the number of entries each level holds is 2^n * firstLevelMaxSize.
99 // New transactions are appended to level 0 until it becomes full at which point
100 // the entire level 0 entry is appended to the level 1 entry and level 0 is
101 // cleared. This process continues until level 1 becomes full at which point it
102 // will be appended to level 2 and cleared and so on.
104 // The result of this is the lower levels contain newer transactions and the
105 // transactions within each level are ordered from oldest to newest.
107 // The intent of this approach is to provide a balance between space efficiency
108 // and indexing cost. Storing one entry per transaction would have the lowest
109 // indexing cost, but would waste a lot of space because the same address hash
110 // would be duplicated for every transaction key. On the other hand, storing a
111 // single entry with all transactions would be the most space efficient, but
112 // would cause indexing cost to grow quadratically with the number of
113 // transactions involving the same address. The approach used here provides
114 // logarithmic insertion and retrieval.
116 // The serialized key format is:
118 // <addr type><addr hash><level>
121 // addr type uint8 1 byte
122 // addr hash hash160 20 bytes
123 // level uint8 1 byte
127 // The serialized value format is:
129 // [<block id><start offset><tx length>,...]
132 // block id uint32 4 bytes
133 // start offset uint32 4 bytes
134 // tx length uint32 4 bytes
136 // Total: 12 bytes per indexed tx
137 // -----------------------------------------------------------------------------
139 // fetchBlockHashFunc defines a callback function to use in order to convert a
140 // serialized block ID to an associated block hash.
141 type fetchBlockHashFunc func(serializedID []byte) (*chainhash.Hash, error)
143 // serializeAddrIndexEntry serializes the provided block id and transaction
144 // location according to the format described in detail above.
145 func serializeAddrIndexEntry(blockID uint32, txLoc wire.TxLoc) []byte {
146 // Serialize the entry.
147 serialized := make([]byte, 12)
148 byteOrder.PutUint32(serialized, blockID)
149 byteOrder.PutUint32(serialized[4:], uint32(txLoc.TxStart))
150 byteOrder.PutUint32(serialized[8:], uint32(txLoc.TxLen))
154 // deserializeAddrIndexEntry decodes the passed serialized byte slice into the
155 // provided region struct according to the format described in detail above and
156 // uses the passed block hash fetching function in order to conver the block ID
157 // to the associated block hash.
158 func deserializeAddrIndexEntry(serialized []byte, region *database.BlockRegion, fetchBlockHash fetchBlockHashFunc) error {
159 // Ensure there are enough bytes to decode.
160 if len(serialized) < txEntrySize {
161 return errDeserialize("unexpected end of data")
164 hash, err := fetchBlockHash(serialized[0:4])
169 region.Offset = byteOrder.Uint32(serialized[4:8])
170 region.Len = byteOrder.Uint32(serialized[8:12])
174 // keyForLevel returns the key for a specific address and level in the address
176 func keyForLevel(addrKey [addrKeySize]byte, level uint8) [levelKeySize]byte {
177 var key [levelKeySize]byte
178 copy(key[:], addrKey[:])
179 key[levelOffset] = level
183 // dbPutAddrIndexEntry updates the address index to include the provided entry
184 // according to the level-based scheme described in detail above.
185 func dbPutAddrIndexEntry(bucket internalBucket, addrKey [addrKeySize]byte, blockID uint32, txLoc wire.TxLoc) error {
186 // Start with level 0 and its initial max number of entries.
188 maxLevelBytes := level0MaxEntries * txEntrySize
190 // Simply append the new entry to level 0 and return now when it will
191 // fit. This is the most common path.
192 newData := serializeAddrIndexEntry(blockID, txLoc)
193 level0Key := keyForLevel(addrKey, 0)
194 level0Data := bucket.Get(level0Key[:])
195 if len(level0Data)+len(newData) <= maxLevelBytes {
196 mergedData := newData
197 if len(level0Data) > 0 {
198 mergedData = make([]byte, len(level0Data)+len(newData))
199 copy(mergedData, level0Data)
200 copy(mergedData[len(level0Data):], newData)
202 return bucket.Put(level0Key[:], mergedData)
205 // At this point, level 0 is full, so merge each level into higher
206 // levels as many times as needed to free up level 0.
207 prevLevelData := level0Data
209 // Each new level holds twice as much as the previous one.
213 // Move to the next level as long as the current level is full.
214 curLevelKey := keyForLevel(addrKey, curLevel)
215 curLevelData := bucket.Get(curLevelKey[:])
216 if len(curLevelData) == maxLevelBytes {
217 prevLevelData = curLevelData
221 // The current level has room for the data in the previous one,
222 // so merge the data from previous level into it.
223 mergedData := prevLevelData
224 if len(curLevelData) > 0 {
225 mergedData = make([]byte, len(curLevelData)+
227 copy(mergedData, curLevelData)
228 copy(mergedData[len(curLevelData):], prevLevelData)
230 err := bucket.Put(curLevelKey[:], mergedData)
235 // Move all of the levels before the previous one up a level.
236 for mergeLevel := curLevel - 1; mergeLevel > 0; mergeLevel-- {
237 mergeLevelKey := keyForLevel(addrKey, mergeLevel)
238 prevLevelKey := keyForLevel(addrKey, mergeLevel-1)
239 prevData := bucket.Get(prevLevelKey[:])
240 err := bucket.Put(mergeLevelKey[:], prevData)
248 // Finally, insert the new entry into level 0 now that it is empty.
249 return bucket.Put(level0Key[:], newData)
252 // dbFetchAddrIndexEntries returns block regions for transactions referenced by
253 // the given address key and the number of entries skipped since it could have
254 // been less in the case where there are less total entries than the requested
255 // number of entries to skip.
256 func dbFetchAddrIndexEntries(bucket internalBucket, addrKey [addrKeySize]byte, numToSkip, numRequested uint32, reverse bool, fetchBlockHash fetchBlockHashFunc) ([]database.BlockRegion, uint32, error) {
257 // When the reverse flag is not set, all levels need to be fetched
258 // because numToSkip and numRequested are counted from the oldest
259 // transactions (highest level) and thus the total count is needed.
260 // However, when the reverse flag is set, only enough records to satisfy
261 // the requested amount are needed.
263 var serialized []byte
264 for !reverse || len(serialized) < int(numToSkip+numRequested)*txEntrySize {
265 curLevelKey := keyForLevel(addrKey, level)
266 levelData := bucket.Get(curLevelKey[:])
267 if levelData == nil {
268 // Stop when there are no more levels.
272 // Higher levels contain older transactions, so prepend them.
273 prepended := make([]byte, len(serialized)+len(levelData))
274 copy(prepended, levelData)
275 copy(prepended[len(levelData):], serialized)
276 serialized = prepended
280 // When the requested number of entries to skip is larger than the
281 // number available, skip them all and return now with the actual number
283 numEntries := uint32(len(serialized) / txEntrySize)
284 if numToSkip >= numEntries {
285 return nil, numEntries, nil
288 // Nothing more to do when there are no requested entries.
289 if numRequested == 0 {
290 return nil, numToSkip, nil
293 // Limit the number to load based on the number of available entries,
294 // the number to skip, and the number requested.
295 numToLoad := numEntries - numToSkip
296 if numToLoad > numRequested {
297 numToLoad = numRequested
300 // Start the offset after all skipped entries and load the calculated
302 results := make([]database.BlockRegion, numToLoad)
303 for i := uint32(0); i < numToLoad; i++ {
304 // Calculate the read offset according to the reverse flag.
307 offset = (numEntries - numToSkip - i - 1) * txEntrySize
309 offset = (numToSkip + i) * txEntrySize
312 // Deserialize and populate the result.
313 err := deserializeAddrIndexEntry(serialized[offset:],
314 &results[i], fetchBlockHash)
316 // Ensure any deserialization errors are returned as
317 // database corruption errors.
318 if isDeserializeErr(err) {
319 err = database.Error{
320 ErrorCode: database.ErrCorruption,
321 Description: fmt.Sprintf("failed to "+
322 "deserialized address index "+
323 "for key %x: %v", addrKey, err),
331 return results, numToSkip, nil
334 // minEntriesToReachLevel returns the minimum number of entries that are
335 // required to reach the given address index level.
336 func minEntriesToReachLevel(level uint8) int {
337 maxEntriesForLevel := level0MaxEntries
339 for l := uint8(1); l <= level; l++ {
340 minRequired += maxEntriesForLevel
341 maxEntriesForLevel *= 2
346 // maxEntriesForLevel returns the maximum number of entries allowed for the
347 // given address index level.
348 func maxEntriesForLevel(level uint8) int {
349 numEntries := level0MaxEntries
350 for l := level; l > 0; l-- {
356 // dbRemoveAddrIndexEntries removes the specified number of entries from from
357 // the address index for the provided key. An assertion error will be returned
358 // if the count exceeds the total number of entries in the index.
359 func dbRemoveAddrIndexEntries(bucket internalBucket, addrKey [addrKeySize]byte, count int) error {
360 // Nothing to do if no entries are being deleted.
365 // Make use of a local map to track pending updates and define a closure
366 // to apply it to the database. This is done in order to reduce the
367 // number of database reads and because there is more than one exit
368 // path that needs to apply the updates.
369 pendingUpdates := make(map[uint8][]byte)
370 applyPending := func() error {
371 for level, data := range pendingUpdates {
372 curLevelKey := keyForLevel(addrKey, level)
374 err := bucket.Delete(curLevelKey[:])
380 err := bucket.Put(curLevelKey[:], data)
388 // Loop forwards through the levels while removing entries until the
389 // specified number has been removed. This will potentially result in
390 // entirely empty lower levels which will be backfilled below.
391 var highestLoadedLevel uint8
392 numRemaining := count
393 for level := uint8(0); numRemaining > 0; level++ {
394 // Load the data for the level from the database.
395 curLevelKey := keyForLevel(addrKey, level)
396 curLevelData := bucket.Get(curLevelKey[:])
397 if len(curLevelData) == 0 && numRemaining > 0 {
398 return AssertError(fmt.Sprintf("dbRemoveAddrIndexEntries "+
399 "not enough entries for address key %x to "+
400 "delete %d entries", addrKey, count))
402 pendingUpdates[level] = curLevelData
403 highestLoadedLevel = level
405 // Delete the entire level as needed.
406 numEntries := len(curLevelData) / txEntrySize
407 if numRemaining >= numEntries {
408 pendingUpdates[level] = nil
409 numRemaining -= numEntries
413 // Remove remaining entries to delete from the level.
414 offsetEnd := len(curLevelData) - (numRemaining * txEntrySize)
415 pendingUpdates[level] = curLevelData[:offsetEnd]
419 // When all elements in level 0 were not removed there is nothing left
420 // to do other than updating the database.
421 if len(pendingUpdates[0]) != 0 {
422 return applyPending()
425 // At this point there are one or more empty levels before the current
426 // level which need to be backfilled and the current level might have
427 // had some entries deleted from it as well. Since all levels after
428 // level 0 are required to either be empty, half full, or completely
429 // full, the current level must be adjusted accordingly by backfilling
430 // each previous levels in a way which satisfies the requirements. Any
431 // entries that are left are assigned to level 0 after the loop as they
432 // are guaranteed to fit by the logic in the loop. In other words, this
433 // effectively squashes all remaining entries in the current level into
434 // the lowest possible levels while following the level rules.
436 // Note that the level after the current level might also have entries
437 // and gaps are not allowed, so this also keeps track of the lowest
438 // empty level so the code below knows how far to backfill in case it is
440 lowestEmptyLevel := uint8(255)
441 curLevelData := pendingUpdates[highestLoadedLevel]
442 curLevelMaxEntries := maxEntriesForLevel(highestLoadedLevel)
443 for level := highestLoadedLevel; level > 0; level-- {
444 // When there are not enough entries left in the current level
445 // for the number that would be required to reach it, clear the
446 // the current level which effectively moves them all up to the
447 // previous level on the next iteration. Otherwise, there are
448 // are sufficient entries, so update the current level to
449 // contain as many entries as possible while still leaving
450 // enough remaining entries required to reach the level.
451 numEntries := len(curLevelData) / txEntrySize
452 prevLevelMaxEntries := curLevelMaxEntries / 2
453 minPrevRequired := minEntriesToReachLevel(level - 1)
454 if numEntries < prevLevelMaxEntries+minPrevRequired {
455 lowestEmptyLevel = level
456 pendingUpdates[level] = nil
458 // This level can only be completely full or half full,
459 // so choose the appropriate offset to ensure enough
460 // entries remain to reach the level.
462 if numEntries-curLevelMaxEntries >= minPrevRequired {
463 offset = curLevelMaxEntries * txEntrySize
465 offset = prevLevelMaxEntries * txEntrySize
467 pendingUpdates[level] = curLevelData[:offset]
468 curLevelData = curLevelData[offset:]
471 curLevelMaxEntries = prevLevelMaxEntries
473 pendingUpdates[0] = curLevelData
474 if len(curLevelData) == 0 {
478 // When the highest loaded level is empty, it's possible the level after
479 // it still has data and thus that data needs to be backfilled as well.
480 for len(pendingUpdates[highestLoadedLevel]) == 0 {
481 // When the next level is empty too, the is no data left to
482 // continue backfilling, so there is nothing left to do.
483 // Otherwise, populate the pending updates map with the newly
484 // loaded data and update the highest loaded level accordingly.
485 level := highestLoadedLevel + 1
486 curLevelKey := keyForLevel(addrKey, level)
487 levelData := bucket.Get(curLevelKey[:])
488 if len(levelData) == 0 {
491 pendingUpdates[level] = levelData
492 highestLoadedLevel = level
494 // At this point the highest level is not empty, but it might
495 // be half full. When that is the case, move it up a level to
496 // simplify the code below which backfills all lower levels that
497 // are still empty. This also means the current level will be
498 // empty, so the loop will perform another another iteration to
499 // potentially backfill this level with data from the next one.
500 curLevelMaxEntries := maxEntriesForLevel(level)
501 if len(levelData)/txEntrySize != curLevelMaxEntries {
502 pendingUpdates[level] = nil
503 pendingUpdates[level-1] = levelData
505 curLevelMaxEntries /= 2
508 // Backfill all lower levels that are still empty by iteratively
509 // halfing the data until the lowest empty level is filled.
510 for level > lowestEmptyLevel {
511 offset := (curLevelMaxEntries / 2) * txEntrySize
512 pendingUpdates[level] = levelData[:offset]
513 levelData = levelData[offset:]
514 pendingUpdates[level-1] = levelData
516 curLevelMaxEntries /= 2
519 // The lowest possible empty level is now the highest loaded
521 lowestEmptyLevel = highestLoadedLevel
524 // Apply the pending updates.
525 return applyPending()
528 // addrToKey converts known address types to an addrindex key. An error is
529 // returned for unsupported types.
530 func addrToKey(addr btcutil.Address) ([addrKeySize]byte, error) {
531 switch addr := addr.(type) {
532 case *btcutil.AddressPubKeyHash:
533 var result [addrKeySize]byte
534 result[0] = addrKeyTypePubKeyHash
535 copy(result[1:], addr.Hash160()[:])
538 case *btcutil.AddressScriptHash:
539 var result [addrKeySize]byte
540 result[0] = addrKeyTypeScriptHash
541 copy(result[1:], addr.Hash160()[:])
544 case *btcutil.AddressPubKey:
545 var result [addrKeySize]byte
546 result[0] = addrKeyTypePubKeyHash
547 copy(result[1:], addr.AddressPubKeyHash().Hash160()[:])
550 case *btcutil.AddressWitnessScriptHash:
551 var result [addrKeySize]byte
552 result[0] = addrKeyTypeWitnessScriptHash
554 // P2WSH outputs utilize a 32-byte data push created by hashing
555 // the script with sha256 instead of hash160. In order to keep
556 // all address entries within the database uniform and compact,
557 // we use a hash160 here to reduce the size of the salient data
559 copy(result[1:], btcutil.Hash160(addr.ScriptAddress()))
562 case *btcutil.AddressWitnessPubKeyHash:
563 var result [addrKeySize]byte
564 result[0] = addrKeyTypeWitnessPubKeyHash
565 copy(result[1:], addr.Hash160()[:])
569 return [addrKeySize]byte{}, errUnsupportedAddressType
572 // AddrIndex implements a transaction by address index. That is to say, it
573 // supports querying all transactions that reference a given address because
574 // they are either crediting or debiting the address. The returned transactions
575 // are ordered according to their order of appearance in the blockchain. In
576 // other words, first by block height and then by offset inside the block.
578 // In addition, support is provided for a memory-only index of unconfirmed
579 // transactions such as those which are kept in the memory pool before inclusion
581 type AddrIndex struct {
582 // The following fields are set when the instance is created and can't
583 // be changed afterwards, so there is no need to protect them with a
586 chainParams *chaincfg.Params
588 // The following fields are used to quickly link transactions and
589 // addresses that have not been included into a block yet when an
590 // address index is being maintained. The are protected by the
591 // unconfirmedLock field.
593 // The txnsByAddr field is used to keep an index of all transactions
594 // which either create an output to a given address or spend from a
595 // previous output to it keyed by the address.
597 // The addrsByTx field is essentially the reverse and is used to
598 // keep an index of all addresses which a given transaction involves.
599 // This allows fairly efficient updates when transactions are removed
600 // once they are included into a block.
601 unconfirmedLock sync.RWMutex
602 txnsByAddr map[[addrKeySize]byte]map[chainhash.Hash]*btcutil.Tx
603 addrsByTx map[chainhash.Hash]map[[addrKeySize]byte]struct{}
606 // Ensure the AddrIndex type implements the Indexer interface.
607 var _ Indexer = (*AddrIndex)(nil)
609 // Ensure the AddrIndex type implements the NeedsInputser interface.
610 var _ NeedsInputser = (*AddrIndex)(nil)
612 // NeedsInputs signals that the index requires the referenced inputs in order
613 // to properly create the index.
615 // This implements the NeedsInputser interface.
616 func (idx *AddrIndex) NeedsInputs() bool {
620 // Init is only provided to satisfy the Indexer interface as there is nothing to
621 // initialize for this index.
623 // This is part of the Indexer interface.
624 func (idx *AddrIndex) Init() error {
629 // Key returns the database key to use for the index as a byte slice.
631 // This is part of the Indexer interface.
632 func (idx *AddrIndex) Key() []byte {
636 // Name returns the human-readable name of the index.
638 // This is part of the Indexer interface.
639 func (idx *AddrIndex) Name() string {
643 // Create is invoked when the indexer manager determines the index needs
644 // to be created for the first time. It creates the bucket for the address
647 // This is part of the Indexer interface.
648 func (idx *AddrIndex) Create(dbTx database.Tx) error {
649 _, err := dbTx.Metadata().CreateBucket(addrIndexKey)
653 // writeIndexData represents the address index data to be written for one block.
654 // It consistens of the address mapped to an ordered list of the transactions
655 // that involve the address in block. It is ordered so the transactions can be
656 // stored in the order they appear in the block.
657 type writeIndexData map[[addrKeySize]byte][]int
659 // indexPkScript extracts all standard addresses from the passed public key
660 // script and maps each of them to the associated transaction using the passed
662 func (idx *AddrIndex) indexPkScript(data writeIndexData, pkScript []byte, txIdx int) {
663 // Nothing to index if the script is non-standard or otherwise doesn't
664 // contain any addresses.
665 _, addrs, _, err := txscript.ExtractPkScriptAddrs(pkScript,
667 if err != nil || len(addrs) == 0 {
671 for _, addr := range addrs {
672 addrKey, err := addrToKey(addr)
674 // Ignore unsupported address types.
678 // Avoid inserting the transaction more than once. Since the
679 // transactions are indexed serially any duplicates will be
680 // indexed in a row, so checking the most recent entry for the
681 // address is enough to detect duplicates.
682 indexedTxns := data[addrKey]
683 numTxns := len(indexedTxns)
684 if numTxns > 0 && indexedTxns[numTxns-1] == txIdx {
687 indexedTxns = append(indexedTxns, txIdx)
688 data[addrKey] = indexedTxns
692 // indexBlock extract all of the standard addresses from all of the transactions
693 // in the passed block and maps each of them to the assocaited transaction using
695 func (idx *AddrIndex) indexBlock(data writeIndexData, block *btcutil.Block, view *blockchain.UtxoViewpoint) {
696 for txIdx, tx := range block.Transactions() {
697 // Coinbases do not reference any inputs. Since the block is
698 // required to have already gone through full validation, it has
699 // already been proven on the first transaction in the block is
702 for _, txIn := range tx.MsgTx().TxIn {
703 // The view should always have the input since
704 // the index contract requires it, however, be
705 // safe and simply ignore any missing entries.
706 origin := &txIn.PreviousOutPoint
707 entry := view.LookupEntry(&origin.Hash)
712 pkScript := entry.PkScriptByIndex(origin.Index)
713 idx.indexPkScript(data, pkScript, txIdx)
717 for _, txOut := range tx.MsgTx().TxOut {
718 idx.indexPkScript(data, txOut.PkScript, txIdx)
723 // ConnectBlock is invoked by the index manager when a new block has been
724 // connected to the main chain. This indexer adds a mapping for each address
725 // the transactions in the block involve.
727 // This is part of the Indexer interface.
728 func (idx *AddrIndex) ConnectBlock(dbTx database.Tx, block *btcutil.Block, view *blockchain.UtxoViewpoint) error {
729 // The offset and length of the transactions within the serialized
731 txLocs, err := block.TxLoc()
736 // Get the internal block ID associated with the block.
737 blockID, err := dbFetchBlockIDByHash(dbTx, block.Hash())
742 // Build all of the address to transaction mappings in a local map.
743 addrsToTxns := make(writeIndexData)
744 idx.indexBlock(addrsToTxns, block, view)
746 // Add all of the index entries for each address.
747 addrIdxBucket := dbTx.Metadata().Bucket(addrIndexKey)
748 for addrKey, txIdxs := range addrsToTxns {
749 for _, txIdx := range txIdxs {
750 err := dbPutAddrIndexEntry(addrIdxBucket, addrKey,
751 blockID, txLocs[txIdx])
761 // DisconnectBlock is invoked by the index manager when a block has been
762 // disconnected from the main chain. This indexer removes the address mappings
763 // each transaction in the block involve.
765 // This is part of the Indexer interface.
766 func (idx *AddrIndex) DisconnectBlock(dbTx database.Tx, block *btcutil.Block, view *blockchain.UtxoViewpoint) error {
767 // Build all of the address to transaction mappings in a local map.
768 addrsToTxns := make(writeIndexData)
769 idx.indexBlock(addrsToTxns, block, view)
771 // Remove all of the index entries for each address.
772 bucket := dbTx.Metadata().Bucket(addrIndexKey)
773 for addrKey, txIdxs := range addrsToTxns {
774 err := dbRemoveAddrIndexEntries(bucket, addrKey, len(txIdxs))
783 // TxRegionsForAddress returns a slice of block regions which identify each
784 // transaction that involves the passed address according to the specified
785 // number to skip, number requested, and whether or not the results should be
786 // reversed. It also returns the number actually skipped since it could be less
787 // in the case where there are not enough entries.
789 // NOTE: These results only include transactions confirmed in blocks. See the
790 // UnconfirmedTxnsForAddress method for obtaining unconfirmed transactions
791 // that involve a given address.
793 // This function is safe for concurrent access.
794 func (idx *AddrIndex) TxRegionsForAddress(dbTx database.Tx, addr btcutil.Address, numToSkip, numRequested uint32, reverse bool) ([]database.BlockRegion, uint32, error) {
795 addrKey, err := addrToKey(addr)
800 var regions []database.BlockRegion
802 err = idx.db.View(func(dbTx database.Tx) error {
803 // Create closure to lookup the block hash given the ID using
804 // the database transaction.
805 fetchBlockHash := func(id []byte) (*chainhash.Hash, error) {
806 // Deserialize and populate the result.
807 return dbFetchBlockHashBySerializedID(dbTx, id)
811 addrIdxBucket := dbTx.Metadata().Bucket(addrIndexKey)
812 regions, skipped, err = dbFetchAddrIndexEntries(addrIdxBucket,
813 addrKey, numToSkip, numRequested, reverse,
818 return regions, skipped, err
821 // indexUnconfirmedAddresses modifies the unconfirmed (memory-only) address
822 // index to include mappings for the addresses encoded by the passed public key
823 // script to the transaction.
825 // This function is safe for concurrent access.
826 func (idx *AddrIndex) indexUnconfirmedAddresses(pkScript []byte, tx *btcutil.Tx) {
827 // The error is ignored here since the only reason it can fail is if the
828 // script fails to parse and it was already validated before being
829 // admitted to the mempool.
830 _, addresses, _, _ := txscript.ExtractPkScriptAddrs(pkScript,
832 for _, addr := range addresses {
833 // Ignore unsupported address types.
834 addrKey, err := addrToKey(addr)
839 // Add a mapping from the address to the transaction.
840 idx.unconfirmedLock.Lock()
841 addrIndexEntry := idx.txnsByAddr[addrKey]
842 if addrIndexEntry == nil {
843 addrIndexEntry = make(map[chainhash.Hash]*btcutil.Tx)
844 idx.txnsByAddr[addrKey] = addrIndexEntry
846 addrIndexEntry[*tx.Hash()] = tx
848 // Add a mapping from the transaction to the address.
849 addrsByTxEntry := idx.addrsByTx[*tx.Hash()]
850 if addrsByTxEntry == nil {
851 addrsByTxEntry = make(map[[addrKeySize]byte]struct{})
852 idx.addrsByTx[*tx.Hash()] = addrsByTxEntry
854 addrsByTxEntry[addrKey] = struct{}{}
855 idx.unconfirmedLock.Unlock()
859 // AddUnconfirmedTx adds all addresses related to the transaction to the
860 // unconfirmed (memory-only) address index.
862 // NOTE: This transaction MUST have already been validated by the memory pool
863 // before calling this function with it and have all of the inputs available in
864 // the provided utxo view. Failure to do so could result in some or all
865 // addresses not being indexed.
867 // This function is safe for concurrent access.
868 func (idx *AddrIndex) AddUnconfirmedTx(tx *btcutil.Tx, utxoView *blockchain.UtxoViewpoint) {
869 // Index addresses of all referenced previous transaction outputs.
871 // The existence checks are elided since this is only called after the
872 // transaction has already been validated and thus all inputs are
873 // already known to exist.
874 for _, txIn := range tx.MsgTx().TxIn {
875 entry := utxoView.LookupEntry(&txIn.PreviousOutPoint.Hash)
877 // Ignore missing entries. This should never happen
878 // in practice since the function comments specifically
879 // call out all inputs must be available.
882 pkScript := entry.PkScriptByIndex(txIn.PreviousOutPoint.Index)
883 idx.indexUnconfirmedAddresses(pkScript, tx)
886 // Index addresses of all created outputs.
887 for _, txOut := range tx.MsgTx().TxOut {
888 idx.indexUnconfirmedAddresses(txOut.PkScript, tx)
892 // RemoveUnconfirmedTx removes the passed transaction from the unconfirmed
893 // (memory-only) address index.
895 // This function is safe for concurrent access.
896 func (idx *AddrIndex) RemoveUnconfirmedTx(hash *chainhash.Hash) {
897 idx.unconfirmedLock.Lock()
898 defer idx.unconfirmedLock.Unlock()
900 // Remove all address references to the transaction from the address
901 // index and remove the entry for the address altogether if it no longer
902 // references any transactions.
903 for addrKey := range idx.addrsByTx[*hash] {
904 delete(idx.txnsByAddr[addrKey], *hash)
905 if len(idx.txnsByAddr[addrKey]) == 0 {
906 delete(idx.txnsByAddr, addrKey)
910 // Remove the entry from the transaction to address lookup map as well.
911 delete(idx.addrsByTx, *hash)
914 // UnconfirmedTxnsForAddress returns all transactions currently in the
915 // unconfirmed (memory-only) address index that involve the passed address.
916 // Unsupported address types are ignored and will result in no results.
918 // This function is safe for concurrent access.
919 func (idx *AddrIndex) UnconfirmedTxnsForAddress(addr btcutil.Address) []*btcutil.Tx {
920 // Ignore unsupported address types.
921 addrKey, err := addrToKey(addr)
926 // Protect concurrent access.
927 idx.unconfirmedLock.RLock()
928 defer idx.unconfirmedLock.RUnlock()
930 // Return a new slice with the results if there are any. This ensures
932 if txns, exists := idx.txnsByAddr[addrKey]; exists {
933 addressTxns := make([]*btcutil.Tx, 0, len(txns))
934 for _, tx := range txns {
935 addressTxns = append(addressTxns, tx)
943 // NewAddrIndex returns a new instance of an indexer that is used to create a
944 // mapping of all addresses in the blockchain to the respective transactions
945 // that involve them.
947 // It implements the Indexer interface which plugs into the IndexManager that in
948 // turn is used by the blockchain package. This allows the index to be
949 // seamlessly maintained along with the chain.
950 func NewAddrIndex(db database.DB, chainParams *chaincfg.Params) *AddrIndex {
953 chainParams: chainParams,
954 txnsByAddr: make(map[[addrKeySize]byte]map[chainhash.Hash]*btcutil.Tx),
955 addrsByTx: make(map[chainhash.Hash]map[[addrKeySize]byte]struct{}),
959 // DropAddrIndex drops the address index from the provided database if it
961 func DropAddrIndex(db database.DB) error {
962 return dropIndex(db, addrIndexKey, addrIndexName)