[#4630] Add wallet_fetchOrGetCachedWalletBalances method (#4666)

This commit is contained in:
Roman Volosovskyi 2024-02-02 11:42:56 +01:00 committed by GitHub
parent 9c131edfaa
commit 9b10b29da2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 59 additions and 2 deletions

View File

@ -1 +1 @@
0.172.11 0.172.12

View File

@ -48,7 +48,7 @@ func (m *Messenger) retrieveWalletBalances() error {
defer cancel() defer cancel()
// TODO: publish tokens as a signal // TODO: publish tokens as a signal
_, err = m.walletAPI.GetWalletToken(ctx, ethAccounts) _, err = m.walletAPI.FetchOrGetCachedWalletBalances(ctx, ethAccounts)
if err != nil { if err != nil {
return err return err
} }

View File

@ -80,6 +80,10 @@ func (api *API) GetWalletTokenBalances(ctx context.Context, addresses []common.A
return api.reader.GetWalletTokenBalances(ctx, addresses) return api.reader.GetWalletTokenBalances(ctx, addresses)
} }
func (api *API) FetchOrGetCachedWalletBalances(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) {
return api.reader.FetchOrGetCachedWalletBalances(ctx, addresses)
}
func (api *API) GetCachedWalletTokensWithoutMarketData(ctx context.Context) (map[common.Address][]Token, error) { func (api *API) GetCachedWalletTokensWithoutMarketData(ctx context.Context) (map[common.Address][]Token, error) {
return api.reader.GetCachedWalletTokensWithoutMarketData() return api.reader.GetCachedWalletTokensWithoutMarketData()
} }

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"math" "math"
"math/big" "math/big"
"sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -72,6 +73,8 @@ type Reader struct {
walletEventsWatcher *walletevent.Watcher walletEventsWatcher *walletevent.Watcher
lastWalletTokenUpdateTimestamp atomic.Int64 lastWalletTokenUpdateTimestamp atomic.Int64
reloadDelayTimer *time.Timer reloadDelayTimer *time.Timer
refreshBalanceCache bool
rw sync.RWMutex
} }
type TokenMarketValues struct { type TokenMarketValues struct {
@ -221,6 +224,10 @@ func (r *Reader) startWalletEventsWatcher() {
if event.At > timecheck { if event.At > timecheck {
r.triggerDelayedWalletReload() r.triggerDelayedWalletReload()
} }
if transfer.IsTransferDetectionEvent(event.Type) {
r.invalidateBalanceCache()
}
} }
r.walletEventsWatcher = walletevent.NewWatcher(r.walletFeed, walletEventCb) r.walletEventsWatcher = walletevent.NewWatcher(r.walletFeed, walletEventCb)
@ -235,6 +242,41 @@ func (r *Reader) stopWalletEventsWatcher() {
} }
} }
func (r *Reader) isBalanceCacheValid() bool {
r.rw.RLock()
defer r.rw.RUnlock()
return !r.refreshBalanceCache
}
func (r *Reader) balanceRefreshed() {
r.rw.Lock()
defer r.rw.Unlock()
r.refreshBalanceCache = false
}
func (r *Reader) invalidateBalanceCache() {
r.rw.Lock()
defer r.rw.Unlock()
r.refreshBalanceCache = true
}
func (r *Reader) FetchOrGetCachedWalletBalances(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) {
if !r.isBalanceCacheValid() {
balances, err := r.GetWalletTokenBalances(ctx, addresses)
if err != nil {
return nil, err
}
r.balanceRefreshed()
return balances, nil
}
return r.persistence.GetTokens()
}
func (r *Reader) GetWalletTokenBalances(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) { func (r *Reader) GetWalletTokenBalances(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) {
areTestNetworksEnabled, err := r.accountsDB.GetTestNetworksEnabled() areTestNetworksEnabled, err := r.accountsDB.GetTestNetworksEnabled()
if err != nil { if err != nil {

View File

@ -641,3 +641,14 @@ func subTransactionListToTransactionsByTxHash(subTransactions []Transfer) map[co
return rst return rst
} }
func IsTransferDetectionEvent(ev walletevent.EventType) bool {
if ev == EventInternalETHTransferDetected ||
ev == EventInternalERC20TransferDetected ||
ev == EventInternalERC721TransferDetected ||
ev == EventInternalERC1155TransferDetected {
return true
}
return false
}