feat: implement collectible ownership status

This commit is contained in:
Dario Gabriel Lipicar 2023-09-14 18:52:49 -03:00 committed by dlipicar
parent e502ba82ce
commit e337ab4f13
2 changed files with 72 additions and 8 deletions

View File

@ -3,6 +3,7 @@ package collectibles
import (
"context"
"errors"
"sync/atomic"
"time"
"github.com/ethereum/go-ethereum/common"
@ -27,16 +28,19 @@ type periodicRefreshOwnedCollectiblesCommand struct {
walletFeed *event.Feed
group *async.Group
state atomic.Value
}
func newPeriodicRefreshOwnedCollectiblesCommand(manager *Manager, ownershipDB *OwnershipDB, walletFeed *event.Feed, chainID walletCommon.ChainID, account common.Address) *periodicRefreshOwnedCollectiblesCommand {
return &periodicRefreshOwnedCollectiblesCommand{
ret := &periodicRefreshOwnedCollectiblesCommand{
manager: manager,
ownershipDB: ownershipDB,
walletFeed: walletFeed,
chainID: chainID,
account: account,
}
ret.state.Store(OwnershipStateIdle)
return ret
}
func (c *periodicRefreshOwnedCollectiblesCommand) Command() async.Command {
@ -50,6 +54,10 @@ func (c *periodicRefreshOwnedCollectiblesCommand) Run(ctx context.Context) (err
return c.loadOwnedCollectibles(ctx)
}
func (c *periodicRefreshOwnedCollectiblesCommand) GetState() OwnershipState {
return c.state.Load().(OwnershipState)
}
func (c *periodicRefreshOwnedCollectiblesCommand) Stop() {
if c.group != nil {
c.group.Stop()
@ -60,8 +68,17 @@ func (c *periodicRefreshOwnedCollectiblesCommand) Stop() {
func (c *periodicRefreshOwnedCollectiblesCommand) loadOwnedCollectibles(ctx context.Context) error {
c.group = async.NewGroup(ctx)
command := newLoadOwnedCollectiblesCommand(c.manager, c.ownershipDB, c.walletFeed, c.chainID, c.account)
c.state.Store(OwnershipStateUpdating)
defer func() {
if command.err != nil {
c.state.Store(OwnershipStateError)
} else {
c.state.Store(OwnershipStateIdle)
}
}()
c.group.Add(command.Command())
select {

View File

@ -84,12 +84,29 @@ const (
ErrorCodeFailed
)
type OwnershipState = int
const (
OwnershipStateIdle OwnershipState = iota + 1
OwnershipStateUpdating
OwnershipStateError
)
type OwnershipStatus struct {
State OwnershipState `json:"state"`
Timestamp int64 `json:"timestamp"`
}
type OwnershipStatusPerChainID = map[walletCommon.ChainID]OwnershipStatus
type OwnershipStatusPerAddressAndChainID = map[common.Address]OwnershipStatusPerChainID
type FilterOwnedCollectiblesResponse struct {
Collectibles []CollectibleHeader `json:"collectibles"`
Offset int `json:"offset"`
// Used to indicate that there might be more collectibles that were not returned
// based on a simple heuristic
HasMore bool `json:"hasMore"`
OwnershipStatus OwnershipStatusPerAddressAndChainID `json:"ownershipStatus"`
ErrorCode ErrorCode `json:"errorCode"`
}
@ -101,6 +118,7 @@ type GetCollectiblesDetailsResponse struct {
type filterOwnedCollectiblesTaskReturnType struct {
collectibles []CollectibleHeader
hasMore bool
ownershipStatus OwnershipStatusPerAddressAndChainID
}
// FilterOwnedCollectiblesResponse allows only one filter task to run at a time
@ -116,10 +134,15 @@ func (s *Service) FilterOwnedCollectiblesAsync(requestID int32, chainIDs []walle
if err != nil {
return nil, err
}
ownershipStatus, err := s.GetOwnershipStatus(chainIDs, addresses)
if err != nil {
return nil, err
}
return filterOwnedCollectiblesTaskReturnType{
collectibles: fullCollectiblesDataToHeaders(data),
hasMore: hasMore,
ownershipStatus: ownershipStatus,
}, err
}, func(result interface{}, taskType async.TaskType, err error) {
res := FilterOwnedCollectiblesResponse{
@ -133,6 +156,7 @@ func (s *Service) FilterOwnedCollectiblesAsync(requestID int32, chainIDs []walle
res.Collectibles = fnRet.collectibles
res.Offset = offset
res.HasMore = fnRet.hasMore
res.OwnershipStatus = fnRet.ownershipStatus
res.ErrorCode = ErrorCodeSuccess
}
@ -355,3 +379,26 @@ func (s *Service) GetOwnedCollectibles(chainIDs []walletCommon.ChainID, owners [
func (s *Service) GetOwnedCollectible(chainID walletCommon.ChainID, owner common.Address, contractAddress common.Address, tokenID *big.Int) (*thirdparty.CollectibleUniqueID, error) {
return s.ownershipDB.GetOwnedCollectible(chainID, owner, contractAddress, tokenID)
}
func (s *Service) GetOwnershipStatus(chainIDs []walletCommon.ChainID, owners []common.Address) (OwnershipStatusPerAddressAndChainID, error) {
ret := make(OwnershipStatusPerAddressAndChainID)
for _, address := range owners {
ret[address] = make(OwnershipStatusPerChainID)
for _, chainID := range chainIDs {
timestamp, err := s.ownershipDB.GetOwnershipUpdateTimestamp(address, chainID)
if err != nil {
return nil, err
}
state := OwnershipStateIdle
if s.commands[address] != nil && s.commands[address][chainID] != nil {
state = s.commands[address][chainID].GetState()
}
ret[address][chainID] = OwnershipStatus{
State: state,
Timestamp: timestamp,
}
}
}
return ret, nil
}