2023-05-08 06:02:00 +00:00
|
|
|
package transfer
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"math/big"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/ethereum/go-ethereum/event"
|
2023-05-19 08:19:48 +00:00
|
|
|
"github.com/ethereum/go-ethereum/log"
|
2023-05-08 06:02:00 +00:00
|
|
|
"github.com/status-im/status-go/rpc/chain"
|
|
|
|
"github.com/status-im/status-go/services/wallet/async"
|
2023-09-04 05:34:09 +00:00
|
|
|
"github.com/status-im/status-go/services/wallet/balance"
|
2023-06-02 20:08:45 +00:00
|
|
|
"github.com/status-im/status-go/services/wallet/token"
|
2023-06-01 13:09:50 +00:00
|
|
|
"github.com/status-im/status-go/services/wallet/walletevent"
|
2023-06-21 14:09:55 +00:00
|
|
|
"github.com/status-im/status-go/transactions"
|
2023-05-08 06:02:00 +00:00
|
|
|
)
|
|
|
|
|
2023-11-28 14:23:03 +00:00
|
|
|
func NewSequentialFetchStrategy(db *Database, blockDAO *BlockDAO, blockRangesSeqDAO *BlockRangeSequentialDAO, feed *event.Feed,
|
2023-08-01 18:50:30 +00:00
|
|
|
transactionManager *TransactionManager, pendingTxManager *transactions.PendingTxTracker,
|
2023-06-02 20:08:45 +00:00
|
|
|
tokenManager *token.Manager,
|
2023-09-20 08:41:23 +00:00
|
|
|
chainClients map[uint64]chain.ClientInterface,
|
2023-09-04 05:34:09 +00:00
|
|
|
accounts []common.Address,
|
|
|
|
balanceCacher balance.Cacher,
|
2023-10-18 10:02:35 +00:00
|
|
|
omitHistory bool,
|
2023-09-04 05:34:09 +00:00
|
|
|
) *SequentialFetchStrategy {
|
2023-05-19 08:19:48 +00:00
|
|
|
|
|
|
|
return &SequentialFetchStrategy{
|
|
|
|
db: db,
|
|
|
|
blockDAO: blockDAO,
|
2023-11-28 14:23:03 +00:00
|
|
|
blockRangesSeqDAO: blockRangesSeqDAO,
|
2023-05-19 08:19:48 +00:00
|
|
|
feed: feed,
|
|
|
|
transactionManager: transactionManager,
|
2023-06-21 14:09:55 +00:00
|
|
|
pendingTxManager: pendingTxManager,
|
2023-06-02 20:08:45 +00:00
|
|
|
tokenManager: tokenManager,
|
2023-05-19 08:19:48 +00:00
|
|
|
chainClients: chainClients,
|
|
|
|
accounts: accounts,
|
2023-09-04 05:34:09 +00:00
|
|
|
balanceCacher: balanceCacher,
|
2023-10-18 10:02:35 +00:00
|
|
|
omitHistory: omitHistory,
|
2023-05-19 08:19:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-08 06:02:00 +00:00
|
|
|
type SequentialFetchStrategy struct {
|
|
|
|
db *Database
|
|
|
|
blockDAO *BlockDAO
|
2023-11-28 14:23:03 +00:00
|
|
|
blockRangesSeqDAO *BlockRangeSequentialDAO
|
2023-05-08 06:02:00 +00:00
|
|
|
feed *event.Feed
|
|
|
|
mu sync.Mutex
|
|
|
|
group *async.Group
|
|
|
|
transactionManager *TransactionManager
|
2023-08-01 18:50:30 +00:00
|
|
|
pendingTxManager *transactions.PendingTxTracker
|
2023-06-02 20:08:45 +00:00
|
|
|
tokenManager *token.Manager
|
2023-09-20 08:41:23 +00:00
|
|
|
chainClients map[uint64]chain.ClientInterface
|
2023-05-08 06:02:00 +00:00
|
|
|
accounts []common.Address
|
2023-09-04 05:34:09 +00:00
|
|
|
balanceCacher balance.Cacher
|
2023-10-18 10:02:35 +00:00
|
|
|
omitHistory bool
|
2023-05-08 06:02:00 +00:00
|
|
|
}
|
|
|
|
|
2023-09-20 08:41:23 +00:00
|
|
|
func (s *SequentialFetchStrategy) newCommand(chainClient chain.ClientInterface,
|
2023-06-14 10:00:56 +00:00
|
|
|
account common.Address) async.Commander {
|
2023-05-08 06:02:00 +00:00
|
|
|
|
2023-11-28 14:23:03 +00:00
|
|
|
return newLoadBlocksAndTransfersCommand(account, s.db, s.blockDAO, s.blockRangesSeqDAO, chainClient, s.feed,
|
2023-10-18 10:02:35 +00:00
|
|
|
s.transactionManager, s.pendingTxManager, s.tokenManager, s.balanceCacher, s.omitHistory)
|
2023-05-08 06:02:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SequentialFetchStrategy) start() error {
|
|
|
|
s.mu.Lock()
|
|
|
|
defer s.mu.Unlock()
|
|
|
|
|
|
|
|
if s.group != nil {
|
|
|
|
return errAlreadyRunning
|
|
|
|
}
|
|
|
|
s.group = async.NewGroup(context.Background())
|
|
|
|
|
2023-06-01 13:09:50 +00:00
|
|
|
if s.feed != nil {
|
|
|
|
s.feed.Send(walletevent.Event{
|
|
|
|
Type: EventFetchingRecentHistory,
|
|
|
|
Accounts: s.accounts,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-05-08 06:02:00 +00:00
|
|
|
for _, chainClient := range s.chainClients {
|
2023-06-14 10:00:56 +00:00
|
|
|
for _, address := range s.accounts {
|
|
|
|
ctl := s.newCommand(chainClient, address)
|
|
|
|
s.group.Add(ctl.Command())
|
|
|
|
}
|
2023-05-08 06:02:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop stops reactor loop and waits till it exits.
|
|
|
|
func (s *SequentialFetchStrategy) stop() {
|
|
|
|
s.mu.Lock()
|
|
|
|
defer s.mu.Unlock()
|
|
|
|
if s.group == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
s.group.Stop()
|
|
|
|
s.group.Wait()
|
|
|
|
s.group = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SequentialFetchStrategy) kind() FetchStrategyType {
|
|
|
|
return SequentialFetchStrategyType
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SequentialFetchStrategy) getTransfersByAddress(ctx context.Context, chainID uint64, address common.Address, toBlock *big.Int,
|
2023-11-15 14:30:56 +00:00
|
|
|
limit int64) ([]Transfer, error) {
|
2023-05-08 06:02:00 +00:00
|
|
|
|
2023-11-15 14:30:56 +00:00
|
|
|
log.Debug("[WalletAPI:: GetTransfersByAddress] get transfers for an address", "address", address,
|
2023-05-19 08:19:48 +00:00
|
|
|
"chainID", chainID, "toBlock", toBlock, "limit", limit)
|
|
|
|
|
|
|
|
rst, err := s.db.GetTransfersByAddress(chainID, address, toBlock, limit)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("[WalletAPI:: GetTransfersByAddress] can't fetch transfers", "err", err)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return rst, nil
|
2023-05-08 06:02:00 +00:00
|
|
|
}
|