Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions lib/block_view_nft.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,22 @@ func (bav *UtxoView) GetNFTEntriesForPostHash(nftPostHash *BlockHash) []*NFTEntr
return nftEntries
}

func (bav *UtxoView) GetNFTEntriesForPKID(ownerPKID *PKID) []*NFTEntry {
func (bav *UtxoView) GetNFTEntriesForPKID(
ownerPKID *PKID,
limit int,
lastKeyBytes []byte,
isForSale *bool,
isPending *bool,
) ([]*NFTEntry, []byte) {
var dbNFTEntries []*NFTEntry
var lastSeenKey []byte
if bav.Postgres != nil {
nfts := bav.Postgres.GetNFTsForPKID(ownerPKID)
for _, nft := range nfts {
dbNFTEntries = append(dbNFTEntries, nft.NewNFTEntry())
}
} else {
dbNFTEntries = DBGetNFTEntriesForPKID(bav.Handle, ownerPKID)
dbNFTEntries, lastSeenKey = DBGetNFTEntriesForPKID(bav.Handle, ownerPKID, limit, lastKeyBytes, isForSale, isPending)
}

// Make sure all of the DB entries are loaded in the view.
Expand All @@ -118,11 +125,11 @@ func (bav *UtxoView) GetNFTEntriesForPKID(ownerPKID *PKID) []*NFTEntry {
// Loop over the view and build the final set of NFTEntries to return.
nftEntries := []*NFTEntry{}
for _, nftEntry := range bav.NFTKeyToNFTEntry {
if !nftEntry.isDeleted && reflect.DeepEqual(nftEntry.OwnerPKID, ownerPKID) {
if !nftEntry.isDeleted && nftEntry.OwnerPKID.Eq(ownerPKID) {
nftEntries = append(nftEntries, nftEntry)
}
}
return nftEntries
return nftEntries, lastSeenKey
}

func (bav *UtxoView) GetNFTBidEntriesForPKID(bidderPKID *PKID) (_nftBidEntries []*NFTBidEntry) {
Expand Down
73 changes: 65 additions & 8 deletions lib/db_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8754,18 +8754,75 @@ func DBGetNFTEntryByNFTOwnershipDetails(db *badger.DB, snap *Snapshot, ownerPKID
}

// DBGetNFTEntriesForPKID gets NFT Entries *from the DB*. Does not include mempool txns.
func DBGetNFTEntriesForPKID(handle *badger.DB, ownerPKID *PKID) (_nftEntries []*NFTEntry) {
func DBGetNFTEntriesForPKID(
handle *badger.DB,
ownerPKID *PKID,
limit int,
lastKeyBytes []byte,
isForSale *bool,
isPending *bool,
) (
_nftEntries []*NFTEntry,
_lastKeyBytes []byte,
) {
var nftEntries []*NFTEntry
prefix := append([]byte{}, Prefixes.PrefixPKIDIsForSaleBidAmountNanosPostHashSerialNumberToNFTEntry...)
keyPrefix := append(prefix, ownerPKID[:]...)
_, entryByteStringsFound := _enumerateKeysForPrefix(handle, keyPrefix, false, false)
for _, byteString := range entryByteStringsFound {
currentEntry := &NFTEntry{}
rr := bytes.NewReader(byteString)
DecodeFromBytes(currentEntry, rr)
nftEntries = append(nftEntries, currentEntry)
if isForSale != nil {
keyPrefix = append(keyPrefix, BoolToByte(*isForSale))
}
return nftEntries
lastSeenKey := keyPrefix
haveSeenLastSeenKey := true
if len(lastKeyBytes) > 0 {
lastSeenKey = lastKeyBytes
if limit > 0 {
limit += 1
}
}

opts := badger.DefaultIteratorOptions
opts.Prefix = keyPrefix
var lastSeenKeyBytes []byte
dbErr := handle.View(func(txn *badger.Txn) error {
nodeIterator := txn.NewIterator(opts)
defer nodeIterator.Close()
for nodeIterator.Seek(lastSeenKey); nodeIterator.ValidForPrefix(keyPrefix); nodeIterator.Next() {
// Break if at or beyond limit.
if limit > 0 && len(nftEntries) >= limit {
break
}
key := nodeIterator.Item().Key()
// Skip if key is before the last seen key. The caller
// needs to filter out the lastSeenKey in the view as
// we return any key >= the lastSeenKey.
if !haveSeenLastSeenKey {
if !bytes.Equal(key, lastSeenKey) {
continue
}
haveSeenLastSeenKey = true
}

val, err := nodeIterator.Item().ValueCopy(nil)
if err != nil {
return err
}
currentEntry := &NFTEntry{}
rr := bytes.NewReader(val)
DecodeFromBytes(currentEntry, rr)
// If isPending is specified, filter by it.
if isPending != nil && currentEntry.IsPending != *isPending {
continue
}
nftEntries = append(nftEntries, currentEntry)
lastSeenKeyBytes = append([]byte{}, key...)
}
return nil
})
if dbErr != nil {
glog.Errorf("DBGetNFTEntriesForPKID: Problem reading NFTEntry, error: (%v)", dbErr)
}

return nftEntries, lastSeenKeyBytes
}

// =======================================================================================
Expand Down