fix: handle collectibles owned by multiple accounts

This commit is contained in:
Dario Gabriel Lipicar 2024-03-06 12:55:35 -03:00 committed by dlipicar
parent 55e8fd4554
commit 4bf6f27b26
4 changed files with 34 additions and 10 deletions

View File

@ -60,7 +60,7 @@ func filterOwnedCollectibles(ctx context.Context, db *sql.DB, chainIDs []wcommon
return nil, errors.New("no chainIDs provided") return nil, errors.New("no chainIDs provided")
} }
q := sq.Select("ownership.chain_id,ownership.contract_address,ownership.token_id") q := sq.Select("ownership.chain_id,ownership.contract_address,ownership.token_id").Distinct()
q = q.From("collectibles_ownership_cache ownership"). q = q.From("collectibles_ownership_cache ownership").
LeftJoin(`collectible_data_cache data ON LeftJoin(`collectible_data_cache data ON
ownership.chain_id = data.chain_id AND ownership.chain_id = data.chain_id AND

View File

@ -51,11 +51,23 @@ func TestFilterOwnedCollectibles(t *testing.T) {
var err error var err error
for i := 0; i < nData; i++ { var commonID thirdparty.CollectibleUniqueID
dataPerID[data[i].ID.HashKey()] = data[i]
communityDataPerID[data[i].ID.HashKey()] = communityData[i]
chainID := data[i].ID.ContractID.ChainID for i := 0; i < nData; i++ {
iData := data[i]
iCommunityData := communityData[i]
if i == 1 {
// Insert a duplicate ID to represent 2 owners having the same ERC1155 collectible
iData = data[0]
iCommunityData = communityData[0]
commonID = iData.ID
}
dataPerID[iData.ID.HashKey()] = iData
communityDataPerID[iData.ID.HashKey()] = iCommunityData
chainID := iData.ID.ContractID.ChainID
ownerAddress := ownerAddresses[i%len(ownerAddresses)] ownerAddress := ownerAddresses[i%len(ownerAddresses)]
if _, ok := balancesPerChainIDAndOwner[chainID]; !ok { if _, ok := balancesPerChainIDAndOwner[chainID]; !ok {
@ -65,13 +77,13 @@ func TestFilterOwnedCollectibles(t *testing.T) {
balancesPerChainIDAndOwner[chainID][ownerAddress] = make(thirdparty.TokenBalancesPerContractAddress) balancesPerChainIDAndOwner[chainID][ownerAddress] = make(thirdparty.TokenBalancesPerContractAddress)
} }
contractAddress := data[i].ID.ContractID.Address contractAddress := iData.ID.ContractID.Address
if _, ok := balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress]; !ok { if _, ok := balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress]; !ok {
balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress] = make([]thirdparty.TokenBalance, 0, len(data)) balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress] = make([]thirdparty.TokenBalance, 0, len(data))
} }
tokenBalance := thirdparty.TokenBalance{ tokenBalance := thirdparty.TokenBalance{
TokenID: data[i].ID.TokenID, TokenID: iData.ID.TokenID,
Balance: &bigint.BigInt{Int: big.NewInt(int64(i % 10))}, Balance: &bigint.BigInt{Int: big.NewInt(int64(i % 10))},
} }
balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress] = append(balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress], tokenBalance) balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress] = append(balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress], tokenBalance)
@ -214,4 +226,16 @@ func TestFilterOwnedCollectibles(t *testing.T) {
filterIDs, err = filterOwnedCollectibles(ctx, db, filterChains, filterAddresses, filter, 0, nData) filterIDs, err = filterOwnedCollectibles(ctx, db, filterChains, filterAddresses, filter, 0, nData)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, expectedIDs, filterIDs) require.Equal(t, expectedIDs, filterIDs)
// Test collectible ID owned by both accounts 0 and 1
filterChains = []w_common.ChainID{commonID.ContractID.ChainID}
filterAddresses = []common.Address{ownerAddresses[0], ownerAddresses[1]}
filter = allFilter()
filter.CollectibleIDs = append(filter.CollectibleIDs, commonID)
expectedIDs = filter.CollectibleIDs
filterIDs, err = filterOwnedCollectibles(ctx, db, filterChains, filterAddresses, filter, 0, nData)
require.NoError(t, err)
require.Equal(t, expectedIDs, filterIDs)
} }

View File

@ -397,7 +397,7 @@ func (o *OwnershipDB) Update(chainID w_common.ChainID, ownerAddress common.Addre
} }
func (o *OwnershipDB) GetOwnedCollectibles(chainIDs []w_common.ChainID, ownerAddresses []common.Address, offset int, limit int) ([]thirdparty.CollectibleUniqueID, error) { func (o *OwnershipDB) GetOwnedCollectibles(chainIDs []w_common.ChainID, ownerAddresses []common.Address, offset int, limit int) ([]thirdparty.CollectibleUniqueID, error) {
query, args, err := sqlx.In(fmt.Sprintf(`SELECT %s query, args, err := sqlx.In(fmt.Sprintf(`SELECT DISTINCT %s
FROM collectibles_ownership_cache FROM collectibles_ownership_cache
WHERE chain_id IN (?) AND owner_address IN (?) WHERE chain_id IN (?) AND owner_address IN (?)
LIMIT ? OFFSET ?`, selectOwnershipColumns), chainIDs, ownerAddresses, limit, offset) LIMIT ? OFFSET ?`, selectOwnershipColumns), chainIDs, ownerAddresses, limit, offset)

View File

@ -115,8 +115,8 @@ func TestUpdateOwnership(t *testing.T) {
allChains := []w_common.ChainID{chainID0, chainID1, chainID2} allChains := []w_common.ChainID{chainID0, chainID1, chainID2}
allOwnerAddresses := []common.Address{ownerAddress1, ownerAddress2, ownerAddress3} allOwnerAddresses := []common.Address{ownerAddress1, ownerAddress2, ownerAddress3}
allCollectibles := append(ownedList1, ownedList2...) allCollectibles := append(ownedList1[1:], ownedList2...)
allCollectibles = append(allCollectibles, ownedList3...) allCollectibles = append(allCollectibles, ownedList3[:len(ownedList3)-1]...) // the last element of ownerdList3 is a duplicate of the first element of ownedList2
randomAddress := common.HexToAddress("0xFFFF") randomAddress := common.HexToAddress("0xFFFF")