| 597 | } |
| 598 | |
| 599 | int CBlockTreeDB::ReadHeightIndex(int low, int high, int minconf, |
| 600 | std::vector<std::vector<uint256>> &blocksOfHashes, |
| 601 | std::set<dev::h160> const &addresses) { |
| 602 | |
| 603 | if ((high < low && high > -1) || (high == 0 && low == 0) || (high < -1 || low < 0)) { |
| 604 | return -1; |
| 605 | } |
| 606 | |
| 607 | boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator()); |
| 608 | |
| 609 | CDataStream ssKeySet(SER_DISK, CLIENT_VERSION); |
| 610 | ssKeySet << std::make_pair(DB_HEIGHTINDEX, CHeightTxIndexIteratorKey(low)); |
| 611 | pcursor->Seek(ssKeySet.str()); |
| 612 | |
| 613 | int curheight = 0; |
| 614 | |
| 615 | for (size_t count = 0; pcursor->Valid(); pcursor->Next()) { |
| 616 | leveldb::Slice slKey = pcursor->key(); |
| 617 | CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION); |
| 618 | char chType; |
| 619 | ssKey >> chType; |
| 620 | if (chType == DB_HEIGHTINDEX) { |
| 621 | CHeightTxIndexKey heightTxIndex; |
| 622 | ssKey >> heightTxIndex; |
| 623 | |
| 624 | int nextHeight = heightTxIndex.height; |
| 625 | |
| 626 | if (high > -1 && nextHeight > high) { |
| 627 | break; |
| 628 | } |
| 629 | |
| 630 | if (minconf > 0) { |
| 631 | int conf = chainActive.Height() - nextHeight; |
| 632 | if (conf < minconf) { |
| 633 | break; |
| 634 | } |
| 635 | } |
| 636 | |
| 637 | curheight = nextHeight; |
| 638 | |
| 639 | auto address = heightTxIndex.address; |
| 640 | if (!addresses.empty() && addresses.find(address) == addresses.end()) { |
| 641 | continue; |
| 642 | } |
| 643 | |
| 644 | leveldb::Slice slValue = pcursor->value(); |
| 645 | CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION); |
| 646 | std::vector<uint256> hashesTx; |
| 647 | ssValue >> hashesTx; |
| 648 | |
| 649 | count += hashesTx.size(); |
| 650 | |
| 651 | blocksOfHashes.push_back(hashesTx); |
| 652 | |
| 653 | } else { |
| 654 | break; |
| 655 | } |
| 656 | |