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 }