Skip to content

Commit 11be7d3

Browse files
authored
enforce limit on get nfts for user (#1463)
* enforce limit on get nfts for user * formatting and use PKID.Eq instead of reflect deepequals * filter for sale and pending in db * remove commented out code * gofmt
1 parent 63f113d commit 11be7d3

2 files changed

Lines changed: 76 additions & 12 deletions

File tree

lib/block_view_nft.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,22 @@ func (bav *UtxoView) GetNFTEntriesForPostHash(nftPostHash *BlockHash) []*NFTEntr
9494
return nftEntries
9595
}
9696

97-
func (bav *UtxoView) GetNFTEntriesForPKID(ownerPKID *PKID) []*NFTEntry {
97+
func (bav *UtxoView) GetNFTEntriesForPKID(
98+
ownerPKID *PKID,
99+
limit int,
100+
lastKeyBytes []byte,
101+
isForSale *bool,
102+
isPending *bool,
103+
) ([]*NFTEntry, []byte) {
98104
var dbNFTEntries []*NFTEntry
105+
var lastSeenKey []byte
99106
if bav.Postgres != nil {
100107
nfts := bav.Postgres.GetNFTsForPKID(ownerPKID)
101108
for _, nft := range nfts {
102109
dbNFTEntries = append(dbNFTEntries, nft.NewNFTEntry())
103110
}
104111
} else {
105-
dbNFTEntries = DBGetNFTEntriesForPKID(bav.Handle, ownerPKID)
112+
dbNFTEntries, lastSeenKey = DBGetNFTEntriesForPKID(bav.Handle, ownerPKID, limit, lastKeyBytes, isForSale, isPending)
106113
}
107114

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

128135
func (bav *UtxoView) GetNFTBidEntriesForPKID(bidderPKID *PKID) (_nftBidEntries []*NFTBidEntry) {

lib/db_utils.go

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8754,18 +8754,75 @@ func DBGetNFTEntryByNFTOwnershipDetails(db *badger.DB, snap *Snapshot, ownerPKID
87548754
}
87558755

87568756
// DBGetNFTEntriesForPKID gets NFT Entries *from the DB*. Does not include mempool txns.
8757-
func DBGetNFTEntriesForPKID(handle *badger.DB, ownerPKID *PKID) (_nftEntries []*NFTEntry) {
8757+
func DBGetNFTEntriesForPKID(
8758+
handle *badger.DB,
8759+
ownerPKID *PKID,
8760+
limit int,
8761+
lastKeyBytes []byte,
8762+
isForSale *bool,
8763+
isPending *bool,
8764+
) (
8765+
_nftEntries []*NFTEntry,
8766+
_lastKeyBytes []byte,
8767+
) {
87588768
var nftEntries []*NFTEntry
87598769
prefix := append([]byte{}, Prefixes.PrefixPKIDIsForSaleBidAmountNanosPostHashSerialNumberToNFTEntry...)
87608770
keyPrefix := append(prefix, ownerPKID[:]...)
8761-
_, entryByteStringsFound := _enumerateKeysForPrefix(handle, keyPrefix, false, false)
8762-
for _, byteString := range entryByteStringsFound {
8763-
currentEntry := &NFTEntry{}
8764-
rr := bytes.NewReader(byteString)
8765-
DecodeFromBytes(currentEntry, rr)
8766-
nftEntries = append(nftEntries, currentEntry)
8771+
if isForSale != nil {
8772+
keyPrefix = append(keyPrefix, BoolToByte(*isForSale))
87678773
}
8768-
return nftEntries
8774+
lastSeenKey := keyPrefix
8775+
haveSeenLastSeenKey := true
8776+
if len(lastKeyBytes) > 0 {
8777+
lastSeenKey = lastKeyBytes
8778+
if limit > 0 {
8779+
limit += 1
8780+
}
8781+
}
8782+
8783+
opts := badger.DefaultIteratorOptions
8784+
opts.Prefix = keyPrefix
8785+
var lastSeenKeyBytes []byte
8786+
dbErr := handle.View(func(txn *badger.Txn) error {
8787+
nodeIterator := txn.NewIterator(opts)
8788+
defer nodeIterator.Close()
8789+
for nodeIterator.Seek(lastSeenKey); nodeIterator.ValidForPrefix(keyPrefix); nodeIterator.Next() {
8790+
// Break if at or beyond limit.
8791+
if limit > 0 && len(nftEntries) >= limit {
8792+
break
8793+
}
8794+
key := nodeIterator.Item().Key()
8795+
// Skip if key is before the last seen key. The caller
8796+
// needs to filter out the lastSeenKey in the view as
8797+
// we return any key >= the lastSeenKey.
8798+
if !haveSeenLastSeenKey {
8799+
if !bytes.Equal(key, lastSeenKey) {
8800+
continue
8801+
}
8802+
haveSeenLastSeenKey = true
8803+
}
8804+
8805+
val, err := nodeIterator.Item().ValueCopy(nil)
8806+
if err != nil {
8807+
return err
8808+
}
8809+
currentEntry := &NFTEntry{}
8810+
rr := bytes.NewReader(val)
8811+
DecodeFromBytes(currentEntry, rr)
8812+
// If isPending is specified, filter by it.
8813+
if isPending != nil && currentEntry.IsPending != *isPending {
8814+
continue
8815+
}
8816+
nftEntries = append(nftEntries, currentEntry)
8817+
lastSeenKeyBytes = append([]byte{}, key...)
8818+
}
8819+
return nil
8820+
})
8821+
if dbErr != nil {
8822+
glog.Errorf("DBGetNFTEntriesForPKID: Problem reading NFTEntry, error: (%v)", dbErr)
8823+
}
8824+
8825+
return nftEntries, lastSeenKeyBytes
87698826
}
87708827

87718828
// =======================================================================================

0 commit comments

Comments
 (0)