github.com/status-im/status-go@v1.1.0/services/wallet/transfer/sequential_fetch_strategy.go (about) 1 package transfer 2 3 import ( 4 "context" 5 "math/big" 6 "sync" 7 8 "github.com/ethereum/go-ethereum/common" 9 "github.com/ethereum/go-ethereum/event" 10 "github.com/ethereum/go-ethereum/log" 11 "github.com/status-im/status-go/multiaccounts/accounts" 12 "github.com/status-im/status-go/rpc/chain" 13 "github.com/status-im/status-go/services/wallet/async" 14 "github.com/status-im/status-go/services/wallet/balance" 15 "github.com/status-im/status-go/services/wallet/blockchainstate" 16 "github.com/status-im/status-go/services/wallet/token" 17 "github.com/status-im/status-go/services/wallet/walletevent" 18 "github.com/status-im/status-go/transactions" 19 ) 20 21 func NewSequentialFetchStrategy(db *Database, blockDAO *BlockDAO, blockRangesSeqDAO *BlockRangeSequentialDAO, accountsDB *accounts.Database, feed *event.Feed, 22 transactionManager *TransactionManager, pendingTxManager *transactions.PendingTxTracker, 23 tokenManager *token.Manager, 24 chainClients map[uint64]chain.ClientInterface, 25 accounts []common.Address, 26 balanceCacher balance.Cacher, 27 omitHistory bool, 28 blockChainState *blockchainstate.BlockChainState, 29 ) *SequentialFetchStrategy { 30 31 return &SequentialFetchStrategy{ 32 db: db, 33 blockDAO: blockDAO, 34 blockRangesSeqDAO: blockRangesSeqDAO, 35 accountsDB: accountsDB, 36 feed: feed, 37 transactionManager: transactionManager, 38 pendingTxManager: pendingTxManager, 39 tokenManager: tokenManager, 40 chainClients: chainClients, 41 accounts: accounts, 42 balanceCacher: balanceCacher, 43 omitHistory: omitHistory, 44 blockChainState: blockChainState, 45 } 46 } 47 48 type SequentialFetchStrategy struct { 49 db *Database 50 blockDAO *BlockDAO 51 blockRangesSeqDAO *BlockRangeSequentialDAO 52 accountsDB *accounts.Database 53 feed *event.Feed 54 mu sync.Mutex 55 group *async.Group 56 transactionManager *TransactionManager 57 pendingTxManager *transactions.PendingTxTracker 58 tokenManager *token.Manager 59 chainClients map[uint64]chain.ClientInterface 60 accounts []common.Address 61 balanceCacher balance.Cacher 62 omitHistory bool 63 blockChainState *blockchainstate.BlockChainState 64 } 65 66 func (s *SequentialFetchStrategy) newCommand(chainClient chain.ClientInterface, 67 accounts []common.Address) async.Commander { 68 69 return newLoadBlocksAndTransfersCommand(accounts, s.db, s.accountsDB, s.blockDAO, s.blockRangesSeqDAO, chainClient, s.feed, 70 s.transactionManager, s.pendingTxManager, s.tokenManager, s.balanceCacher, s.omitHistory, s.blockChainState) 71 } 72 73 func (s *SequentialFetchStrategy) start() error { 74 s.mu.Lock() 75 defer s.mu.Unlock() 76 77 if s.group != nil { 78 return errAlreadyRunning 79 } 80 s.group = async.NewGroup(context.Background()) 81 82 if s.feed != nil { 83 s.feed.Send(walletevent.Event{ 84 Type: EventFetchingRecentHistory, 85 Accounts: s.accounts, 86 }) 87 } 88 89 for _, chainClient := range s.chainClients { 90 ctl := s.newCommand(chainClient, s.accounts) 91 s.group.Add(ctl.Command()) 92 } 93 94 return nil 95 } 96 97 // Stop stops reactor loop and waits till it exits. 98 func (s *SequentialFetchStrategy) stop() { 99 s.mu.Lock() 100 defer s.mu.Unlock() 101 if s.group == nil { 102 return 103 } 104 s.group.Stop() 105 s.group.Wait() 106 s.group = nil 107 } 108 109 func (s *SequentialFetchStrategy) kind() FetchStrategyType { 110 return SequentialFetchStrategyType 111 } 112 113 func (s *SequentialFetchStrategy) getTransfersByAddress(ctx context.Context, chainID uint64, address common.Address, toBlock *big.Int, 114 limit int64) ([]Transfer, error) { 115 116 log.Debug("[WalletAPI:: GetTransfersByAddress] get transfers for an address", "address", address, 117 "chainID", chainID, "toBlock", toBlock, "limit", limit) 118 119 rst, err := s.db.GetTransfersByAddress(chainID, address, toBlock, limit) 120 if err != nil { 121 log.Error("[WalletAPI:: GetTransfersByAddress] can't fetch transfers", "err", err) 122 return nil, err 123 } 124 125 return rst, nil 126 }