fix(wallet): balance history used a wrong db for accessing accounts.
Balance history was not checked for all chains if no history on some chain. Removed `SetInitialRange` from wallet API as internal implementation. This method was called on adding a brand new Status account to initialize blocks_range table to avoid transfers history checks.
This commit is contained in:
parent
fbcda780ec
commit
c24c3966e2
|
@ -132,30 +132,6 @@ Returns avaiable transfers in a given range.
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
### wallet_setInitialBlocksRange
|
|
||||||
|
|
||||||
Sets `zero block - latest block` range as scanned for an account. It is used when a new multiaccount is generated to avoid scanning transfers history.
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"jsonrpc":"2.0","id":7,"method":"wallet_setInitialBlocksRange","params":[]}
|
|
||||||
```
|
|
||||||
|
|
||||||
### setInitialBlocksRangeForChainIDs
|
|
||||||
|
|
||||||
Sets `zero block - latest block` range as scanned for an account. It is used when a new multiaccount is generated to avoid scanning transfers history.
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `chainIDs`: `[]INT` - array of ethereum chain ID to be initialized
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"jsonrpc":"2.0","id":7,"method":"wallet_setInitialBlocksRangeForChainIDs","params":[[1, 2]]}
|
|
||||||
```
|
|
||||||
|
|
||||||
### wallet_watchTransaction
|
### wallet_watchTransaction
|
||||||
|
|
||||||
Starts watching for transaction confirmation/rejection. If transaction was not confirmed/rejected in 10 minutes the call is timed out with error.
|
Starts watching for transaction confirmation/rejection. If transaction was not confirmed/rejected in 10 minutes the call is timed out with error.
|
||||||
|
@ -616,7 +592,7 @@ Emitted when history scanning is started.
|
||||||
|
|
||||||
Emitted when history scanning is ended.
|
Emitted when history scanning is ended.
|
||||||
|
|
||||||
4. `fetching-history-error`
|
4. `fetching-history-error`
|
||||||
|
|
||||||
Emitted when when history can't be fetched because some error. Error's decritption can be found in `message` field.
|
Emitted when when history can't be fetched because some error. Error's decritption can be found in `message` field.
|
||||||
|
|
||||||
|
@ -630,12 +606,11 @@ Emitted when the application is connected to a non-archival node.
|
||||||
|
|
||||||
When a new multiaccount is created corresponding address will not contain any transaction. Thus no point in checking history, it will be empty.
|
When a new multiaccount is created corresponding address will not contain any transaction. Thus no point in checking history, it will be empty.
|
||||||
|
|
||||||
1. Call `wallet_setInitialRange`
|
1. Call `wallet_checkRecentHistory`
|
||||||
2. Call `wallet_checkRecentHistory`
|
2. On `recent-history-ready` request transactions via `wallet_getTransfersByAddress`
|
||||||
3. On `recent-history-ready` request transactions via `wallet_getTransfersByAddress`
|
3. Repeat `wallet_checkRecentHistory` in N minutes (currently 20 minutes in `status-mobile` for upstream RPC node. If a custom node is used interval can be arbitrary)
|
||||||
4. Repeat `wallet_checkRecentHistory` in N minutes (currently 20 minutes in `status-mobile` for upstream RPC node. If a custom node is used interval can be arbitrary)
|
|
||||||
|
|
||||||
### Logging into application
|
### Logging into application
|
||||||
1. Call `wallet_checkRecentHistory`
|
1. Call `wallet_checkRecentHistory`
|
||||||
2. On `recent-history-ready` request transactions via `wallet_getTransfersByAddress`
|
2. On `recent-history-ready` request transactions via `wallet_getTransfersByAddress`
|
||||||
3. Repeat `wallet_checkRecentHistory` in N minutes (currently 20 minutes in `status-mobile` for upstream RPC node. If a custom node is used interval can be arbitrary)
|
3. Repeat `wallet_checkRecentHistory` in N minutes (currently 20 minutes in `status-mobile` for upstream RPC node. If a custom node is used interval can be arbitrary)
|
||||||
|
|
|
@ -66,15 +66,6 @@ type DerivedAddress struct {
|
||||||
AlreadyCreated bool `json:"alreadyCreated"`
|
AlreadyCreated bool `json:"alreadyCreated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetInitialBlocksRange sets initial blocks range
|
|
||||||
func (api *API) SetInitialBlocksRange(ctx context.Context) error {
|
|
||||||
return api.s.transferController.SetInitialBlocksRange([]uint64{api.s.rpcClient.UpstreamChainID})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) SetInitialBlocksRangeForChainIDs(ctx context.Context, chainIDs []uint64) error {
|
|
||||||
return api.s.transferController.SetInitialBlocksRange(chainIDs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) CheckRecentHistory(ctx context.Context, addresses []common.Address) error {
|
func (api *API) CheckRecentHistory(ctx context.Context, addresses []common.Address) error {
|
||||||
return api.s.transferController.CheckRecentHistory([]uint64{api.s.rpcClient.UpstreamChainID}, addresses)
|
return api.s.transferController.CheckRecentHistory([]uint64{api.s.rpcClient.UpstreamChainID}, addresses)
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ const (
|
||||||
type Service struct {
|
type Service struct {
|
||||||
balance *Balance
|
balance *Balance
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
|
accountsDB *accounts.Database
|
||||||
eventFeed *event.Feed
|
eventFeed *event.Feed
|
||||||
rpcClient *statusrpc.Client
|
rpcClient *statusrpc.Client
|
||||||
networkManager *network.Manager
|
networkManager *network.Manager
|
||||||
|
@ -56,10 +57,11 @@ type Service struct {
|
||||||
|
|
||||||
type chainIdentity uint64
|
type chainIdentity uint64
|
||||||
|
|
||||||
func NewService(db *sql.DB, eventFeed *event.Feed, rpcClient *statusrpc.Client, tokenManager *token.Manager, marketManager *market.Manager) *Service {
|
func NewService(db *sql.DB, accountsDB *accounts.Database, eventFeed *event.Feed, rpcClient *statusrpc.Client, tokenManager *token.Manager, marketManager *market.Manager) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
balance: NewBalance(NewBalanceDB(db)),
|
balance: NewBalance(NewBalanceDB(db)),
|
||||||
db: db,
|
db: db,
|
||||||
|
accountsDB: accountsDB,
|
||||||
eventFeed: eventFeed,
|
eventFeed: eventFeed,
|
||||||
rpcClient: rpcClient,
|
rpcClient: rpcClient,
|
||||||
networkManager: rpcClient.NetworkManager,
|
networkManager: rpcClient.NetworkManager,
|
||||||
|
@ -222,8 +224,6 @@ func (s *Service) GetBalanceHistory(ctx context.Context, chainIDs []uint64, addr
|
||||||
}
|
}
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
allData[chainIdentity(chainID)] = data
|
allData[chainIdentity(chainID)] = data
|
||||||
} else {
|
|
||||||
return make([]*ValuePoint, 0), nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,17 +476,13 @@ func sortTimeAsc(data map[chainIdentity][]*DataPoint, pos map[chainIdentity]int)
|
||||||
//
|
//
|
||||||
// expects ctx to have cancellation support and processing to be cancelled by the caller
|
// expects ctx to have cancellation support and processing to be cancelled by the caller
|
||||||
func (s *Service) updateBalanceHistory(ctx context.Context) error {
|
func (s *Service) updateBalanceHistory(ctx context.Context) error {
|
||||||
accountsDB, err := accounts.NewDB(s.db)
|
|
||||||
|
addresses, err := s.accountsDB.GetWalletAddresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
addresses, err := accountsDB.GetWalletAddresses()
|
areTestNetworksEnabled, err := s.accountsDB.GetTestNetworksEnabled()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
areTestNetworksEnabled, err := accountsDB.GetTestNetworksEnabled()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ func setupDummyServiceNoDependencies(t *testing.T) (service *Service, closeFn fu
|
||||||
rpcClient, err := statusRPC.NewClient(client, 1, upstreamConfig, nil, db)
|
rpcClient, err := statusRPC.NewClient(client, 1, upstreamConfig, nil, db)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return NewService(db, nil, rpcClient, nil, market.NewManager(cryptoCompare, cryptoCompare, &event.Feed{})), func() {
|
return NewService(db, nil, nil, rpcClient, nil, market.NewManager(cryptoCompare, cryptoCompare, &event.Feed{})), func() {
|
||||||
require.NoError(t, db.Close())
|
require.NoError(t, db.Close())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ func NewService(
|
||||||
coingecko := coingecko.NewClient()
|
coingecko := coingecko.NewClient()
|
||||||
marketManager := market.NewManager(cryptoCompare, coingecko, feed)
|
marketManager := market.NewManager(cryptoCompare, coingecko, feed)
|
||||||
reader := NewReader(rpcClient, tokenManager, marketManager, accountsDB, NewPersistence(db), feed)
|
reader := NewReader(rpcClient, tokenManager, marketManager, accountsDB, NewPersistence(db), feed)
|
||||||
history := history.NewService(db, feed, rpcClient, tokenManager, marketManager)
|
history := history.NewService(db, accountsDB, feed, rpcClient, tokenManager, marketManager)
|
||||||
currency := currency.NewService(db, feed, tokenManager, marketManager)
|
currency := currency.NewService(db, feed, tokenManager, marketManager)
|
||||||
activity := activity.NewService(db, tokenManager, feed, accountsDB)
|
activity := activity.NewService(db, tokenManager, feed, accountsDB)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/status-im/status-go/multiaccounts/accounts"
|
|
||||||
"github.com/status-im/status-go/services/wallet/bigint"
|
"github.com/status-im/status-go/services/wallet/bigint"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,23 +59,6 @@ func (b *BlockDAO) mergeBlocksRanges(chainIDs []uint64, accounts []common.Addres
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlockDAO) setInitialBlocksRange(chainID uint64, from *big.Int, to *big.Int) error {
|
|
||||||
accountsDB, err := accounts.NewDB(b.db)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
watchAddress, err := accountsDB.GetWalletAddress()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = b.insertRange(chainID, common.Address(watchAddress), from, to, big.NewInt(0), 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BlockDAO) mergeRanges(chainID uint64, account common.Address) (err error) {
|
func (b *BlockDAO) mergeRanges(chainID uint64, account common.Address) (err error) {
|
||||||
var (
|
var (
|
||||||
tx *sql.Tx
|
tx *sql.Tx
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
@ -66,32 +65,6 @@ func (c *Controller) Stop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) SetInitialBlocksRange(chainIDs []uint64) error {
|
|
||||||
chainClients, err := c.rpcClient.EthClients(chainIDs)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for chainID, chainClient := range chainClients {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
toHeader, err := chainClient.HeaderByNumber(ctx, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
from := big.NewInt(0)
|
|
||||||
|
|
||||||
err = c.blockDAO.setInitialBlocksRange(chainID, from, toHeader.Number)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Controller) CheckRecentHistory(chainIDs []uint64, accounts []common.Address) error {
|
func (c *Controller) CheckRecentHistory(chainIDs []uint64, accounts []common.Address) error {
|
||||||
if len(accounts) == 0 {
|
if len(accounts) == 0 {
|
||||||
log.Info("no accounts provided")
|
log.Info("no accounts provided")
|
||||||
|
|
|
@ -57,6 +57,30 @@ type HistoryFetcher interface {
|
||||||
limit int64, fetchMore bool) ([]Transfer, error)
|
limit int64, fetchMore bool) ([]Transfer, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewOnDemandFetchStrategy(
|
||||||
|
db *Database,
|
||||||
|
blockDAO *BlockDAO,
|
||||||
|
feed *event.Feed,
|
||||||
|
transactionManager *TransactionManager,
|
||||||
|
pendingTxManager *transactions.PendingTxTracker,
|
||||||
|
tokenManager *token.Manager,
|
||||||
|
chainClients map[uint64]*chain.ClientWithFallback,
|
||||||
|
accounts []common.Address,
|
||||||
|
) *OnDemandFetchStrategy {
|
||||||
|
strategy := &OnDemandFetchStrategy{
|
||||||
|
db: db,
|
||||||
|
blockDAO: blockDAO,
|
||||||
|
feed: feed,
|
||||||
|
transactionManager: transactionManager,
|
||||||
|
pendingTxManager: pendingTxManager,
|
||||||
|
tokenManager: tokenManager,
|
||||||
|
chainClients: chainClients,
|
||||||
|
accounts: accounts,
|
||||||
|
}
|
||||||
|
|
||||||
|
return strategy
|
||||||
|
}
|
||||||
|
|
||||||
type OnDemandFetchStrategy struct {
|
type OnDemandFetchStrategy struct {
|
||||||
db *Database
|
db *Database
|
||||||
blockDAO *BlockDAO
|
blockDAO *BlockDAO
|
||||||
|
@ -294,16 +318,7 @@ func (r *Reactor) createFetchStrategy(chainClients map[uint64]*chain.ClientWithF
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &OnDemandFetchStrategy{
|
return NewOnDemandFetchStrategy(r.db, r.blockDAO, r.feed, r.transactionManager, r.pendingTxManager, r.tokenManager, chainClients, accounts)
|
||||||
db: r.db,
|
|
||||||
feed: r.feed,
|
|
||||||
blockDAO: r.blockDAO,
|
|
||||||
transactionManager: r.transactionManager,
|
|
||||||
pendingTxManager: r.pendingTxManager,
|
|
||||||
tokenManager: r.tokenManager,
|
|
||||||
chainClients: chainClients,
|
|
||||||
accounts: accounts,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Reactor) getTransfersByAddress(ctx context.Context, chainID uint64, address common.Address, toBlock *big.Int,
|
func (r *Reactor) getTransfersByAddress(ctx context.Context, chainID uint64, address common.Address, toBlock *big.Int,
|
||||||
|
|
Loading…
Reference in New Issue