github.com/palcoin-project/palcd@v1.0.0/blockchain/indexers/addrindex.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  package indexers
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"sync"
    11  
    12  	"github.com/palcoin-project/palcd/blockchain"
    13  	"github.com/palcoin-project/palcd/chaincfg"
    14  	"github.com/palcoin-project/palcd/chaincfg/chainhash"
    15  	"github.com/palcoin-project/palcd/database"
    16  	"github.com/palcoin-project/palcd/txscript"
    17  	"github.com/palcoin-project/palcd/wire"
    18  	"github.com/palcoin-project/palcutil"
    19  )
    20  
    21  const (
    22  	// addrIndexName is the human-readable name for the index.
    23  	addrIndexName = "address index"
    24  
    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.
    29  	level0MaxEntries = 8
    30  
    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.
    33  	addrKeySize = 1 + 20
    34  
    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
    38  
    39  	// levelOffset is the offset in the level key which identifes the level.
    40  	levelOffset = levelKeySize - 1
    41  
    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
    45  	// address index.
    46  	addrKeyTypePubKeyHash = 0
    47  
    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
    51  	// hash.
    52  	addrKeyTypeScriptHash = 1
    53  
    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
    59  
    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
    65  
    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
    69  )
    70  
    71  var (
    72  	// addrIndexKey is the key of the address index and the db bucket used
    73  	// to house it.
    74  	addrIndexKey = []byte("txbyaddridx")
    75  
    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")
    80  )
    81  
    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.
    90  //
    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.
    93  //
    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.
    98  //
    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.
   103  //
   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.
   106  //
   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.
   115  //
   116  // The serialized key format is:
   117  //
   118  //   <addr type><addr hash><level>
   119  //
   120  //   Field           Type      Size
   121  //   addr type       uint8     1 byte
   122  //   addr hash       hash160   20 bytes
   123  //   level           uint8     1 byte
   124  //   -----
   125  //   Total: 22 bytes
   126  //
   127  // The serialized value format is:
   128  //
   129  //   [<block id><start offset><tx length>,...]
   130  //
   131  //   Field           Type      Size
   132  //   block id        uint32    4 bytes
   133  //   start offset    uint32    4 bytes
   134  //   tx length       uint32    4 bytes
   135  //   -----
   136  //   Total: 12 bytes per indexed tx
   137  // -----------------------------------------------------------------------------
   138  
   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)
   142  
   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))
   151  	return serialized
   152  }
   153  
   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,
   159  	fetchBlockHash fetchBlockHashFunc) error {
   160  
   161  	// Ensure there are enough bytes to decode.
   162  	if len(serialized) < txEntrySize {
   163  		return errDeserialize("unexpected end of data")
   164  	}
   165  
   166  	hash, err := fetchBlockHash(serialized[0:4])
   167  	if err != nil {
   168  		return err
   169  	}
   170  	region.Hash = hash
   171  	region.Offset = byteOrder.Uint32(serialized[4:8])
   172  	region.Len = byteOrder.Uint32(serialized[8:12])
   173  	return nil
   174  }
   175  
   176  // keyForLevel returns the key for a specific address and level in the address
   177  // index entry.
   178  func keyForLevel(addrKey [addrKeySize]byte, level uint8) [levelKeySize]byte {
   179  	var key [levelKeySize]byte
   180  	copy(key[:], addrKey[:])
   181  	key[levelOffset] = level
   182  	return key
   183  }
   184  
   185  // dbPutAddrIndexEntry updates the address index to include the provided entry
   186  // according to the level-based scheme described in detail above.
   187  func dbPutAddrIndexEntry(bucket internalBucket, addrKey [addrKeySize]byte,
   188  	blockID uint32, txLoc wire.TxLoc) error {
   189  
   190  	// Start with level 0 and its initial max number of entries.
   191  	curLevel := uint8(0)
   192  	maxLevelBytes := level0MaxEntries * txEntrySize
   193  
   194  	// Simply append the new entry to level 0 and return now when it will
   195  	// fit.  This is the most common path.
   196  	newData := serializeAddrIndexEntry(blockID, txLoc)
   197  	level0Key := keyForLevel(addrKey, 0)
   198  	level0Data := bucket.Get(level0Key[:])
   199  	if len(level0Data)+len(newData) <= maxLevelBytes {
   200  		mergedData := newData
   201  		if len(level0Data) > 0 {
   202  			mergedData = make([]byte, len(level0Data)+len(newData))
   203  			copy(mergedData, level0Data)
   204  			copy(mergedData[len(level0Data):], newData)
   205  		}
   206  		return bucket.Put(level0Key[:], mergedData)
   207  	}
   208  
   209  	// At this point, level 0 is full, so merge each level into higher
   210  	// levels as many times as needed to free up level 0.
   211  	prevLevelData := level0Data
   212  	for {
   213  		// Each new level holds twice as much as the previous one.
   214  		curLevel++
   215  		maxLevelBytes *= 2
   216  
   217  		// Move to the next level as long as the current level is full.
   218  		curLevelKey := keyForLevel(addrKey, curLevel)
   219  		curLevelData := bucket.Get(curLevelKey[:])
   220  		if len(curLevelData) == maxLevelBytes {
   221  			prevLevelData = curLevelData
   222  			continue
   223  		}
   224  
   225  		// The current level has room for the data in the previous one,
   226  		// so merge the data from previous level into it.
   227  		mergedData := prevLevelData
   228  		if len(curLevelData) > 0 {
   229  			mergedData = make([]byte, len(curLevelData)+
   230  				len(prevLevelData))
   231  			copy(mergedData, curLevelData)
   232  			copy(mergedData[len(curLevelData):], prevLevelData)
   233  		}
   234  		err := bucket.Put(curLevelKey[:], mergedData)
   235  		if err != nil {
   236  			return err
   237  		}
   238  
   239  		// Move all of the levels before the previous one up a level.
   240  		for mergeLevel := curLevel - 1; mergeLevel > 0; mergeLevel-- {
   241  			mergeLevelKey := keyForLevel(addrKey, mergeLevel)
   242  			prevLevelKey := keyForLevel(addrKey, mergeLevel-1)
   243  			prevData := bucket.Get(prevLevelKey[:])
   244  			err := bucket.Put(mergeLevelKey[:], prevData)
   245  			if err != nil {
   246  				return err
   247  			}
   248  		}
   249  		break
   250  	}
   251  
   252  	// Finally, insert the new entry into level 0 now that it is empty.
   253  	return bucket.Put(level0Key[:], newData)
   254  }
   255  
   256  // dbFetchAddrIndexEntries returns block regions for transactions referenced by
   257  // the given address key and the number of entries skipped since it could have
   258  // been less in the case where there are less total entries than the requested
   259  // number of entries to skip.
   260  func dbFetchAddrIndexEntries(bucket internalBucket, addrKey [addrKeySize]byte,
   261  	numToSkip, numRequested uint32, reverse bool,
   262  	fetchBlockHash fetchBlockHashFunc) ([]database.BlockRegion, uint32, error) {
   263  
   264  	// When the reverse flag is not set, all levels need to be fetched
   265  	// because numToSkip and numRequested are counted from the oldest
   266  	// transactions (highest level) and thus the total count is needed.
   267  	// However, when the reverse flag is set, only enough records to satisfy
   268  	// the requested amount are needed.
   269  	var level uint8
   270  	var serialized []byte
   271  	for !reverse || len(serialized) < int(numToSkip+numRequested)*txEntrySize {
   272  		curLevelKey := keyForLevel(addrKey, level)
   273  		levelData := bucket.Get(curLevelKey[:])
   274  		if levelData == nil {
   275  			// Stop when there are no more levels.
   276  			break
   277  		}
   278  
   279  		// Higher levels contain older transactions, so prepend them.
   280  		prepended := make([]byte, len(serialized)+len(levelData))
   281  		copy(prepended, levelData)
   282  		copy(prepended[len(levelData):], serialized)
   283  		serialized = prepended
   284  		level++
   285  	}
   286  
   287  	// When the requested number of entries to skip is larger than the
   288  	// number available, skip them all and return now with the actual number
   289  	// skipped.
   290  	numEntries := uint32(len(serialized) / txEntrySize)
   291  	if numToSkip >= numEntries {
   292  		return nil, numEntries, nil
   293  	}
   294  
   295  	// Nothing more to do when there are no requested entries.
   296  	if numRequested == 0 {
   297  		return nil, numToSkip, nil
   298  	}
   299  
   300  	// Limit the number to load based on the number of available entries,
   301  	// the number to skip, and the number requested.
   302  	numToLoad := numEntries - numToSkip
   303  	if numToLoad > numRequested {
   304  		numToLoad = numRequested
   305  	}
   306  
   307  	// Start the offset after all skipped entries and load the calculated
   308  	// number.
   309  	results := make([]database.BlockRegion, numToLoad)
   310  	for i := uint32(0); i < numToLoad; i++ {
   311  		// Calculate the read offset according to the reverse flag.
   312  		var offset uint32
   313  		if reverse {
   314  			offset = (numEntries - numToSkip - i - 1) * txEntrySize
   315  		} else {
   316  			offset = (numToSkip + i) * txEntrySize
   317  		}
   318  
   319  		// Deserialize and populate the result.
   320  		err := deserializeAddrIndexEntry(serialized[offset:],
   321  			&results[i], fetchBlockHash)
   322  		if err != nil {
   323  			// Ensure any deserialization errors are returned as
   324  			// database corruption errors.
   325  			if isDeserializeErr(err) {
   326  				err = database.Error{
   327  					ErrorCode: database.ErrCorruption,
   328  					Description: fmt.Sprintf("failed to "+
   329  						"deserialized address index "+
   330  						"for key %x: %v", addrKey, err),
   331  				}
   332  			}
   333  
   334  			return nil, 0, err
   335  		}
   336  	}
   337  
   338  	return results, numToSkip, nil
   339  }
   340  
   341  // minEntriesToReachLevel returns the minimum number of entries that are
   342  // required to reach the given address index level.
   343  func minEntriesToReachLevel(level uint8) int {
   344  	maxEntriesForLevel := level0MaxEntries
   345  	minRequired := 1
   346  	for l := uint8(1); l <= level; l++ {
   347  		minRequired += maxEntriesForLevel
   348  		maxEntriesForLevel *= 2
   349  	}
   350  	return minRequired
   351  }
   352  
   353  // maxEntriesForLevel returns the maximum number of entries allowed for the
   354  // given address index level.
   355  func maxEntriesForLevel(level uint8) int {
   356  	numEntries := level0MaxEntries
   357  	for l := level; l > 0; l-- {
   358  		numEntries *= 2
   359  	}
   360  	return numEntries
   361  }
   362  
   363  // dbRemoveAddrIndexEntries removes the specified number of entries from from
   364  // the address index for the provided key.  An assertion error will be returned
   365  // if the count exceeds the total number of entries in the index.
   366  func dbRemoveAddrIndexEntries(bucket internalBucket, addrKey [addrKeySize]byte,
   367  	count int) error {
   368  
   369  	// Nothing to do if no entries are being deleted.
   370  	if count <= 0 {
   371  		return nil
   372  	}
   373  
   374  	// Make use of a local map to track pending updates and define a closure
   375  	// to apply it to the database.  This is done in order to reduce the
   376  	// number of database reads and because there is more than one exit
   377  	// path that needs to apply the updates.
   378  	pendingUpdates := make(map[uint8][]byte)
   379  	applyPending := func() error {
   380  		for level, data := range pendingUpdates {
   381  			curLevelKey := keyForLevel(addrKey, level)
   382  			if len(data) == 0 {
   383  				err := bucket.Delete(curLevelKey[:])
   384  				if err != nil {
   385  					return err
   386  				}
   387  				continue
   388  			}
   389  			err := bucket.Put(curLevelKey[:], data)
   390  			if err != nil {
   391  				return err
   392  			}
   393  		}
   394  		return nil
   395  	}
   396  
   397  	// Loop forwards through the levels while removing entries until the
   398  	// specified number has been removed.  This will potentially result in
   399  	// entirely empty lower levels which will be backfilled below.
   400  	var highestLoadedLevel uint8
   401  	numRemaining := count
   402  	for level := uint8(0); numRemaining > 0; level++ {
   403  		// Load the data for the level from the database.
   404  		curLevelKey := keyForLevel(addrKey, level)
   405  		curLevelData := bucket.Get(curLevelKey[:])
   406  		if len(curLevelData) == 0 && numRemaining > 0 {
   407  			return AssertError(fmt.Sprintf("dbRemoveAddrIndexEntries "+
   408  				"not enough entries for address key %x to "+
   409  				"delete %d entries", addrKey, count))
   410  		}
   411  		pendingUpdates[level] = curLevelData
   412  		highestLoadedLevel = level
   413  
   414  		// Delete the entire level as needed.
   415  		numEntries := len(curLevelData) / txEntrySize
   416  		if numRemaining >= numEntries {
   417  			pendingUpdates[level] = nil
   418  			numRemaining -= numEntries
   419  			continue
   420  		}
   421  
   422  		// Remove remaining entries to delete from the level.
   423  		offsetEnd := len(curLevelData) - (numRemaining * txEntrySize)
   424  		pendingUpdates[level] = curLevelData[:offsetEnd]
   425  		break
   426  	}
   427  
   428  	// When all elements in level 0 were not removed there is nothing left
   429  	// to do other than updating the database.
   430  	if len(pendingUpdates[0]) != 0 {
   431  		return applyPending()
   432  	}
   433  
   434  	// At this point there are one or more empty levels before the current
   435  	// level which need to be backfilled and the current level might have
   436  	// had some entries deleted from it as well.  Since all levels after
   437  	// level 0 are required to either be empty, half full, or completely
   438  	// full, the current level must be adjusted accordingly by backfilling
   439  	// each previous levels in a way which satisfies the requirements.  Any
   440  	// entries that are left are assigned to level 0 after the loop as they
   441  	// are guaranteed to fit by the logic in the loop.  In other words, this
   442  	// effectively squashes all remaining entries in the current level into
   443  	// the lowest possible levels while following the level rules.
   444  	//
   445  	// Note that the level after the current level might also have entries
   446  	// and gaps are not allowed, so this also keeps track of the lowest
   447  	// empty level so the code below knows how far to backfill in case it is
   448  	// required.
   449  	lowestEmptyLevel := uint8(255)
   450  	curLevelData := pendingUpdates[highestLoadedLevel]
   451  	curLevelMaxEntries := maxEntriesForLevel(highestLoadedLevel)
   452  	for level := highestLoadedLevel; level > 0; level-- {
   453  		// When there are not enough entries left in the current level
   454  		// for the number that would be required to reach it, clear the
   455  		// the current level which effectively moves them all up to the
   456  		// previous level on the next iteration.  Otherwise, there are
   457  		// are sufficient entries, so update the current level to
   458  		// contain as many entries as possible while still leaving
   459  		// enough remaining entries required to reach the level.
   460  		numEntries := len(curLevelData) / txEntrySize
   461  		prevLevelMaxEntries := curLevelMaxEntries / 2
   462  		minPrevRequired := minEntriesToReachLevel(level - 1)
   463  		if numEntries < prevLevelMaxEntries+minPrevRequired {
   464  			lowestEmptyLevel = level
   465  			pendingUpdates[level] = nil
   466  		} else {
   467  			// This level can only be completely full or half full,
   468  			// so choose the appropriate offset to ensure enough
   469  			// entries remain to reach the level.
   470  			var offset int
   471  			if numEntries-curLevelMaxEntries >= minPrevRequired {
   472  				offset = curLevelMaxEntries * txEntrySize
   473  			} else {
   474  				offset = prevLevelMaxEntries * txEntrySize
   475  			}
   476  			pendingUpdates[level] = curLevelData[:offset]
   477  			curLevelData = curLevelData[offset:]
   478  		}
   479  
   480  		curLevelMaxEntries = prevLevelMaxEntries
   481  	}
   482  	pendingUpdates[0] = curLevelData
   483  	if len(curLevelData) == 0 {
   484  		lowestEmptyLevel = 0
   485  	}
   486  
   487  	// When the highest loaded level is empty, it's possible the level after
   488  	// it still has data and thus that data needs to be backfilled as well.
   489  	for len(pendingUpdates[highestLoadedLevel]) == 0 {
   490  		// When the next level is empty too, the is no data left to
   491  		// continue backfilling, so there is nothing left to do.
   492  		// Otherwise, populate the pending updates map with the newly
   493  		// loaded data and update the highest loaded level accordingly.
   494  		level := highestLoadedLevel + 1
   495  		curLevelKey := keyForLevel(addrKey, level)
   496  		levelData := bucket.Get(curLevelKey[:])
   497  		if len(levelData) == 0 {
   498  			break
   499  		}
   500  		pendingUpdates[level] = levelData
   501  		highestLoadedLevel = level
   502  
   503  		// At this point the highest level is not empty, but it might
   504  		// be half full.  When that is the case, move it up a level to
   505  		// simplify the code below which backfills all lower levels that
   506  		// are still empty.  This also means the current level will be
   507  		// empty, so the loop will perform another another iteration to
   508  		// potentially backfill this level with data from the next one.
   509  		curLevelMaxEntries := maxEntriesForLevel(level)
   510  		if len(levelData)/txEntrySize != curLevelMaxEntries {
   511  			pendingUpdates[level] = nil
   512  			pendingUpdates[level-1] = levelData
   513  			level--
   514  			curLevelMaxEntries /= 2
   515  		}
   516  
   517  		// Backfill all lower levels that are still empty by iteratively
   518  		// halfing the data until the lowest empty level is filled.
   519  		for level > lowestEmptyLevel {
   520  			offset := (curLevelMaxEntries / 2) * txEntrySize
   521  			pendingUpdates[level] = levelData[:offset]
   522  			levelData = levelData[offset:]
   523  			pendingUpdates[level-1] = levelData
   524  			level--
   525  			curLevelMaxEntries /= 2
   526  		}
   527  
   528  		// The lowest possible empty level is now the highest loaded
   529  		// level.
   530  		lowestEmptyLevel = highestLoadedLevel
   531  	}
   532  
   533  	// Apply the pending updates.
   534  	return applyPending()
   535  }
   536  
   537  // addrToKey converts known address types to an addrindex key.  An error is
   538  // returned for unsupported types.
   539  func addrToKey(addr palcutil.Address) ([addrKeySize]byte, error) {
   540  	switch addr := addr.(type) {
   541  	case *palcutil.AddressPubKeyHash:
   542  		var result [addrKeySize]byte
   543  		result[0] = addrKeyTypePubKeyHash
   544  		copy(result[1:], addr.Hash160()[:])
   545  		return result, nil
   546  
   547  	case *palcutil.AddressScriptHash:
   548  		var result [addrKeySize]byte
   549  		result[0] = addrKeyTypeScriptHash
   550  		copy(result[1:], addr.Hash160()[:])
   551  		return result, nil
   552  
   553  	case *palcutil.AddressPubKey:
   554  		var result [addrKeySize]byte
   555  		result[0] = addrKeyTypePubKeyHash
   556  		copy(result[1:], addr.AddressPubKeyHash().Hash160()[:])
   557  		return result, nil
   558  
   559  	case *palcutil.AddressWitnessScriptHash:
   560  		var result [addrKeySize]byte
   561  		result[0] = addrKeyTypeWitnessScriptHash
   562  
   563  		// P2WSH outputs utilize a 32-byte data push created by hashing
   564  		// the script with sha256 instead of hash160. In order to keep
   565  		// all address entries within the database uniform and compact,
   566  		// we use a hash160 here to reduce the size of the salient data
   567  		// push to 20-bytes.
   568  		copy(result[1:], palcutil.Hash160(addr.ScriptAddress()))
   569  		return result, nil
   570  
   571  	case *palcutil.AddressWitnessPubKeyHash:
   572  		var result [addrKeySize]byte
   573  		result[0] = addrKeyTypeWitnessPubKeyHash
   574  		copy(result[1:], addr.Hash160()[:])
   575  		return result, nil
   576  	}
   577  
   578  	return [addrKeySize]byte{}, errUnsupportedAddressType
   579  }
   580  
   581  // AddrIndex implements a transaction by address index.  That is to say, it
   582  // supports querying all transactions that reference a given address because
   583  // they are either crediting or debiting the address.  The returned transactions
   584  // are ordered according to their order of appearance in the blockchain.  In
   585  // other words, first by block height and then by offset inside the block.
   586  //
   587  // In addition, support is provided for a memory-only index of unconfirmed
   588  // transactions such as those which are kept in the memory pool before inclusion
   589  // in a block.
   590  type AddrIndex struct {
   591  	// The following fields are set when the instance is created and can't
   592  	// be changed afterwards, so there is no need to protect them with a
   593  	// separate mutex.
   594  	db          database.DB
   595  	chainParams *chaincfg.Params
   596  
   597  	// The following fields are used to quickly link transactions and
   598  	// addresses that have not been included into a block yet when an
   599  	// address index is being maintained.  The are protected by the
   600  	// unconfirmedLock field.
   601  	//
   602  	// The txnsByAddr field is used to keep an index of all transactions
   603  	// which either create an output to a given address or spend from a
   604  	// previous output to it keyed by the address.
   605  	//
   606  	// The addrsByTx field is essentially the reverse and is used to
   607  	// keep an index of all addresses which a given transaction involves.
   608  	// This allows fairly efficient updates when transactions are removed
   609  	// once they are included into a block.
   610  	unconfirmedLock sync.RWMutex
   611  	txnsByAddr      map[[addrKeySize]byte]map[chainhash.Hash]*palcutil.Tx
   612  	addrsByTx       map[chainhash.Hash]map[[addrKeySize]byte]struct{}
   613  }
   614  
   615  // Ensure the AddrIndex type implements the Indexer interface.
   616  var _ Indexer = (*AddrIndex)(nil)
   617  
   618  // Ensure the AddrIndex type implements the NeedsInputser interface.
   619  var _ NeedsInputser = (*AddrIndex)(nil)
   620  
   621  // NeedsInputs signals that the index requires the referenced inputs in order
   622  // to properly create the index.
   623  //
   624  // This implements the NeedsInputser interface.
   625  func (idx *AddrIndex) NeedsInputs() bool {
   626  	return true
   627  }
   628  
   629  // Init is only provided to satisfy the Indexer interface as there is nothing to
   630  // initialize for this index.
   631  //
   632  // This is part of the Indexer interface.
   633  func (idx *AddrIndex) Init() error {
   634  	// Nothing to do.
   635  	return nil
   636  }
   637  
   638  // Key returns the database key to use for the index as a byte slice.
   639  //
   640  // This is part of the Indexer interface.
   641  func (idx *AddrIndex) Key() []byte {
   642  	return addrIndexKey
   643  }
   644  
   645  // Name returns the human-readable name of the index.
   646  //
   647  // This is part of the Indexer interface.
   648  func (idx *AddrIndex) Name() string {
   649  	return addrIndexName
   650  }
   651  
   652  // Create is invoked when the indexer manager determines the index needs
   653  // to be created for the first time.  It creates the bucket for the address
   654  // index.
   655  //
   656  // This is part of the Indexer interface.
   657  func (idx *AddrIndex) Create(dbTx database.Tx) error {
   658  	_, err := dbTx.Metadata().CreateBucket(addrIndexKey)
   659  	return err
   660  }
   661  
   662  // writeIndexData represents the address index data to be written for one block.
   663  // It consists of the address mapped to an ordered list of the transactions
   664  // that involve the address in block.  It is ordered so the transactions can be
   665  // stored in the order they appear in the block.
   666  type writeIndexData map[[addrKeySize]byte][]int
   667  
   668  // indexPkScript extracts all standard addresses from the passed public key
   669  // script and maps each of them to the associated transaction using the passed
   670  // map.
   671  func (idx *AddrIndex) indexPkScript(data writeIndexData, pkScript []byte, txIdx int) {
   672  	// Nothing to index if the script is non-standard or otherwise doesn't
   673  	// contain any addresses.
   674  	_, addrs, _, err := txscript.ExtractPkScriptAddrs(pkScript,
   675  		idx.chainParams)
   676  	if err != nil || len(addrs) == 0 {
   677  		return
   678  	}
   679  
   680  	for _, addr := range addrs {
   681  		addrKey, err := addrToKey(addr)
   682  		if err != nil {
   683  			// Ignore unsupported address types.
   684  			continue
   685  		}
   686  
   687  		// Avoid inserting the transaction more than once.  Since the
   688  		// transactions are indexed serially any duplicates will be
   689  		// indexed in a row, so checking the most recent entry for the
   690  		// address is enough to detect duplicates.
   691  		indexedTxns := data[addrKey]
   692  		numTxns := len(indexedTxns)
   693  		if numTxns > 0 && indexedTxns[numTxns-1] == txIdx {
   694  			continue
   695  		}
   696  		indexedTxns = append(indexedTxns, txIdx)
   697  		data[addrKey] = indexedTxns
   698  	}
   699  }
   700  
   701  // indexBlock extract all of the standard addresses from all of the transactions
   702  // in the passed block and maps each of them to the associated transaction using
   703  // the passed map.
   704  func (idx *AddrIndex) indexBlock(data writeIndexData, block *palcutil.Block,
   705  	stxos []blockchain.SpentTxOut) {
   706  
   707  	stxoIndex := 0
   708  	for txIdx, tx := range block.Transactions() {
   709  		// Coinbases do not reference any inputs.  Since the block is
   710  		// required to have already gone through full validation, it has
   711  		// already been proven on the first transaction in the block is
   712  		// a coinbase.
   713  		if txIdx != 0 {
   714  			for range tx.MsgTx().TxIn {
   715  				// We'll access the slice of all the
   716  				// transactions spent in this block properly
   717  				// ordered to fetch the previous input script.
   718  				pkScript := stxos[stxoIndex].PkScript
   719  				idx.indexPkScript(data, pkScript, txIdx)
   720  
   721  				// With an input indexed, we'll advance the
   722  				// stxo coutner.
   723  				stxoIndex++
   724  			}
   725  		}
   726  
   727  		for _, txOut := range tx.MsgTx().TxOut {
   728  			idx.indexPkScript(data, txOut.PkScript, txIdx)
   729  		}
   730  	}
   731  }
   732  
   733  // ConnectBlock is invoked by the index manager when a new block has been
   734  // connected to the main chain.  This indexer adds a mapping for each address
   735  // the transactions in the block involve.
   736  //
   737  // This is part of the Indexer interface.
   738  func (idx *AddrIndex) ConnectBlock(dbTx database.Tx, block *palcutil.Block,
   739  	stxos []blockchain.SpentTxOut) error {
   740  
   741  	// The offset and length of the transactions within the serialized
   742  	// block.
   743  	txLocs, err := block.TxLoc()
   744  	if err != nil {
   745  		return err
   746  	}
   747  
   748  	// Get the internal block ID associated with the block.
   749  	blockID, err := dbFetchBlockIDByHash(dbTx, block.Hash())
   750  	if err != nil {
   751  		return err
   752  	}
   753  
   754  	// Build all of the address to transaction mappings in a local map.
   755  	addrsToTxns := make(writeIndexData)
   756  	idx.indexBlock(addrsToTxns, block, stxos)
   757  
   758  	// Add all of the index entries for each address.
   759  	addrIdxBucket := dbTx.Metadata().Bucket(addrIndexKey)
   760  	for addrKey, txIdxs := range addrsToTxns {
   761  		for _, txIdx := range txIdxs {
   762  			err := dbPutAddrIndexEntry(addrIdxBucket, addrKey,
   763  				blockID, txLocs[txIdx])
   764  			if err != nil {
   765  				return err
   766  			}
   767  		}
   768  	}
   769  
   770  	return nil
   771  }
   772  
   773  // DisconnectBlock is invoked by the index manager when a block has been
   774  // disconnected from the main chain.  This indexer removes the address mappings
   775  // each transaction in the block involve.
   776  //
   777  // This is part of the Indexer interface.
   778  func (idx *AddrIndex) DisconnectBlock(dbTx database.Tx, block *palcutil.Block,
   779  	stxos []blockchain.SpentTxOut) error {
   780  
   781  	// Build all of the address to transaction mappings in a local map.
   782  	addrsToTxns := make(writeIndexData)
   783  	idx.indexBlock(addrsToTxns, block, stxos)
   784  
   785  	// Remove all of the index entries for each address.
   786  	bucket := dbTx.Metadata().Bucket(addrIndexKey)
   787  	for addrKey, txIdxs := range addrsToTxns {
   788  		err := dbRemoveAddrIndexEntries(bucket, addrKey, len(txIdxs))
   789  		if err != nil {
   790  			return err
   791  		}
   792  	}
   793  
   794  	return nil
   795  }
   796  
   797  // TxRegionsForAddress returns a slice of block regions which identify each
   798  // transaction that involves the passed address according to the specified
   799  // number to skip, number requested, and whether or not the results should be
   800  // reversed.  It also returns the number actually skipped since it could be less
   801  // in the case where there are not enough entries.
   802  //
   803  // NOTE: These results only include transactions confirmed in blocks.  See the
   804  // UnconfirmedTxnsForAddress method for obtaining unconfirmed transactions
   805  // that involve a given address.
   806  //
   807  // This function is safe for concurrent access.
   808  func (idx *AddrIndex) TxRegionsForAddress(dbTx database.Tx, addr palcutil.Address,
   809  	numToSkip, numRequested uint32, reverse bool) ([]database.BlockRegion, uint32, error) {
   810  
   811  	addrKey, err := addrToKey(addr)
   812  	if err != nil {
   813  		return nil, 0, err
   814  	}
   815  
   816  	var regions []database.BlockRegion
   817  	var skipped uint32
   818  	err = idx.db.View(func(dbTx database.Tx) error {
   819  		// Create closure to lookup the block hash given the ID using
   820  		// the database transaction.
   821  		fetchBlockHash := func(id []byte) (*chainhash.Hash, error) {
   822  			// Deserialize and populate the result.
   823  			return dbFetchBlockHashBySerializedID(dbTx, id)
   824  		}
   825  
   826  		var err error
   827  		addrIdxBucket := dbTx.Metadata().Bucket(addrIndexKey)
   828  		regions, skipped, err = dbFetchAddrIndexEntries(addrIdxBucket,
   829  			addrKey, numToSkip, numRequested, reverse,
   830  			fetchBlockHash)
   831  		return err
   832  	})
   833  
   834  	return regions, skipped, err
   835  }
   836  
   837  // indexUnconfirmedAddresses modifies the unconfirmed (memory-only) address
   838  // index to include mappings for the addresses encoded by the passed public key
   839  // script to the transaction.
   840  //
   841  // This function is safe for concurrent access.
   842  func (idx *AddrIndex) indexUnconfirmedAddresses(pkScript []byte, tx *palcutil.Tx) {
   843  	// The error is ignored here since the only reason it can fail is if the
   844  	// script fails to parse and it was already validated before being
   845  	// admitted to the mempool.
   846  	_, addresses, _, _ := txscript.ExtractPkScriptAddrs(pkScript,
   847  		idx.chainParams)
   848  	for _, addr := range addresses {
   849  		// Ignore unsupported address types.
   850  		addrKey, err := addrToKey(addr)
   851  		if err != nil {
   852  			continue
   853  		}
   854  
   855  		// Add a mapping from the address to the transaction.
   856  		idx.unconfirmedLock.Lock()
   857  		addrIndexEntry := idx.txnsByAddr[addrKey]
   858  		if addrIndexEntry == nil {
   859  			addrIndexEntry = make(map[chainhash.Hash]*palcutil.Tx)
   860  			idx.txnsByAddr[addrKey] = addrIndexEntry
   861  		}
   862  		addrIndexEntry[*tx.Hash()] = tx
   863  
   864  		// Add a mapping from the transaction to the address.
   865  		addrsByTxEntry := idx.addrsByTx[*tx.Hash()]
   866  		if addrsByTxEntry == nil {
   867  			addrsByTxEntry = make(map[[addrKeySize]byte]struct{})
   868  			idx.addrsByTx[*tx.Hash()] = addrsByTxEntry
   869  		}
   870  		addrsByTxEntry[addrKey] = struct{}{}
   871  		idx.unconfirmedLock.Unlock()
   872  	}
   873  }
   874  
   875  // AddUnconfirmedTx adds all addresses related to the transaction to the
   876  // unconfirmed (memory-only) address index.
   877  //
   878  // NOTE: This transaction MUST have already been validated by the memory pool
   879  // before calling this function with it and have all of the inputs available in
   880  // the provided utxo view.  Failure to do so could result in some or all
   881  // addresses not being indexed.
   882  //
   883  // This function is safe for concurrent access.
   884  func (idx *AddrIndex) AddUnconfirmedTx(tx *palcutil.Tx, utxoView *blockchain.UtxoViewpoint) {
   885  	// Index addresses of all referenced previous transaction outputs.
   886  	//
   887  	// The existence checks are elided since this is only called after the
   888  	// transaction has already been validated and thus all inputs are
   889  	// already known to exist.
   890  	for _, txIn := range tx.MsgTx().TxIn {
   891  		entry := utxoView.LookupEntry(txIn.PreviousOutPoint)
   892  		if entry == nil {
   893  			// Ignore missing entries.  This should never happen
   894  			// in practice since the function comments specifically
   895  			// call out all inputs must be available.
   896  			continue
   897  		}
   898  		idx.indexUnconfirmedAddresses(entry.PkScript(), tx)
   899  	}
   900  
   901  	// Index addresses of all created outputs.
   902  	for _, txOut := range tx.MsgTx().TxOut {
   903  		idx.indexUnconfirmedAddresses(txOut.PkScript, tx)
   904  	}
   905  }
   906  
   907  // RemoveUnconfirmedTx removes the passed transaction from the unconfirmed
   908  // (memory-only) address index.
   909  //
   910  // This function is safe for concurrent access.
   911  func (idx *AddrIndex) RemoveUnconfirmedTx(hash *chainhash.Hash) {
   912  	idx.unconfirmedLock.Lock()
   913  	defer idx.unconfirmedLock.Unlock()
   914  
   915  	// Remove all address references to the transaction from the address
   916  	// index and remove the entry for the address altogether if it no longer
   917  	// references any transactions.
   918  	for addrKey := range idx.addrsByTx[*hash] {
   919  		delete(idx.txnsByAddr[addrKey], *hash)
   920  		if len(idx.txnsByAddr[addrKey]) == 0 {
   921  			delete(idx.txnsByAddr, addrKey)
   922  		}
   923  	}
   924  
   925  	// Remove the entry from the transaction to address lookup map as well.
   926  	delete(idx.addrsByTx, *hash)
   927  }
   928  
   929  // UnconfirmedTxnsForAddress returns all transactions currently in the
   930  // unconfirmed (memory-only) address index that involve the passed address.
   931  // Unsupported address types are ignored and will result in no results.
   932  //
   933  // This function is safe for concurrent access.
   934  func (idx *AddrIndex) UnconfirmedTxnsForAddress(addr palcutil.Address) []*palcutil.Tx {
   935  	// Ignore unsupported address types.
   936  	addrKey, err := addrToKey(addr)
   937  	if err != nil {
   938  		return nil
   939  	}
   940  
   941  	// Protect concurrent access.
   942  	idx.unconfirmedLock.RLock()
   943  	defer idx.unconfirmedLock.RUnlock()
   944  
   945  	// Return a new slice with the results if there are any.  This ensures
   946  	// safe concurrency.
   947  	if txns, exists := idx.txnsByAddr[addrKey]; exists {
   948  		addressTxns := make([]*palcutil.Tx, 0, len(txns))
   949  		for _, tx := range txns {
   950  			addressTxns = append(addressTxns, tx)
   951  		}
   952  		return addressTxns
   953  	}
   954  
   955  	return nil
   956  }
   957  
   958  // NewAddrIndex returns a new instance of an indexer that is used to create a
   959  // mapping of all addresses in the blockchain to the respective transactions
   960  // that involve them.
   961  //
   962  // It implements the Indexer interface which plugs into the IndexManager that in
   963  // turn is used by the blockchain package.  This allows the index to be
   964  // seamlessly maintained along with the chain.
   965  func NewAddrIndex(db database.DB, chainParams *chaincfg.Params) *AddrIndex {
   966  	return &AddrIndex{
   967  		db:          db,
   968  		chainParams: chainParams,
   969  		txnsByAddr:  make(map[[addrKeySize]byte]map[chainhash.Hash]*palcutil.Tx),
   970  		addrsByTx:   make(map[chainhash.Hash]map[[addrKeySize]byte]struct{}),
   971  	}
   972  }
   973  
   974  // DropAddrIndex drops the address index from the provided database if it
   975  // exists.
   976  func DropAddrIndex(db database.DB, interrupt <-chan struct{}) error {
   977  	return dropIndex(db, addrIndexKey, addrIndexName, interrupt)
   978  }