github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/blockchain/indexers/addrindex.go (about)

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