[wallet] Reduce number of RPC requests
- Wallet service is not started on foreground event on status-go side anymore, it leaves a client side opportunity to decide whether new blocks should be watched. - `watchNewBlocks` parameter is added to `StartWallet`. - Some requests are removed/moved to the place where they are necessary.
This commit is contained in:
parent
a4195e5b5c
commit
002f9a5597
|
@ -882,26 +882,7 @@ func (b *GethStatusBackend) AppStateChange(state string) {
|
||||||
b.log.Info("App State changed", "new-state", s)
|
b.log.Info("App State changed", "new-state", s)
|
||||||
b.appState = s
|
b.appState = s
|
||||||
|
|
||||||
if s == appStateForeground && !b.forceStopWallet {
|
if s == appStateBackground {
|
||||||
wallet, err := b.statusNode.WalletService()
|
|
||||||
if err != nil {
|
|
||||||
b.log.Error("Retrieving of wallet service failed on app state change to active", "error", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !wallet.IsStarted() {
|
|
||||||
err = wallet.Start(b.statusNode.Server())
|
|
||||||
if err != nil {
|
|
||||||
b.log.Error("Wallet service start failed on app state change to active", "error", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = b.startWallet()
|
|
||||||
if err != nil {
|
|
||||||
b.log.Error("Wallet reactor start failed on app state change to active", "error", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if s == appStateBackground && !b.forceStopWallet {
|
|
||||||
localNotifications, err := b.statusNode.LocalNotificationsService()
|
localNotifications, err := b.statusNode.LocalNotificationsService()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.log.Error("Retrieving of local notifications service failed on app state change", "error", err)
|
b.log.Error("Retrieving of local notifications service failed on app state change", "error", err)
|
||||||
|
@ -947,7 +928,7 @@ func (b *GethStatusBackend) StopWallet() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GethStatusBackend) StartWallet() error {
|
func (b *GethStatusBackend) StartWallet(watchNewBlocks bool) error {
|
||||||
wallet, err := b.statusNode.WalletService()
|
wallet, err := b.statusNode.WalletService()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.log.Error("Retrieving of wallet service failed on StartWallet", "error", err)
|
b.log.Error("Retrieving of wallet service failed on StartWallet", "error", err)
|
||||||
|
@ -960,7 +941,7 @@ func (b *GethStatusBackend) StartWallet() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err = b.startWallet()
|
err = b.startWallet(watchNewBlocks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.log.Error("Wallet reactor start failed on StartWallet", "error", err)
|
b.log.Error("Wallet reactor start failed on StartWallet", "error", err)
|
||||||
return nil
|
return nil
|
||||||
|
@ -1187,7 +1168,7 @@ func (b *GethStatusBackend) injectAccountIntoServices() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GethStatusBackend) startWallet() error {
|
func (b *GethStatusBackend) startWallet(watchNewBlocks bool) error {
|
||||||
if !b.statusNode.Config().WalletConfig.Enabled {
|
if !b.statusNode.Config().WalletConfig.Enabled {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1197,7 +1178,11 @@ func (b *GethStatusBackend) startWallet() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
watchAddresses := b.accountManager.WatchAddresses()
|
accountsDB := accounts.NewDB(b.appDB)
|
||||||
|
watchAddresses, err := accountsDB.GetWalletAddresses()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
mainAccountAddress, err := b.accountManager.MainAccountAddress()
|
mainAccountAddress, err := b.accountManager.MainAccountAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1220,7 +1205,8 @@ func (b *GethStatusBackend) startWallet() error {
|
||||||
return wallet.StartReactor(
|
return wallet.StartReactor(
|
||||||
b.statusNode.RPCClient().Ethclient(),
|
b.statusNode.RPCClient().Ethclient(),
|
||||||
allAddresses,
|
allAddresses,
|
||||||
new(big.Int).SetUint64(b.statusNode.Config().NetworkID))
|
new(big.Int).SetUint64(b.statusNode.Config().NetworkID),
|
||||||
|
watchNewBlocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InjectChatAccount selects the current chat account using chatKeyHex and injects the key into whisper.
|
// InjectChatAccount selects the current chat account using chatKeyHex and injects the key into whisper.
|
||||||
|
|
|
@ -518,8 +518,8 @@ func StopWallet() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartWallet
|
// StartWallet
|
||||||
func StartWallet() string {
|
func StartWallet(watchNewBlocks bool) string {
|
||||||
err := statusBackend.StartWallet()
|
err := statusBackend.StartWallet(watchNewBlocks)
|
||||||
return makeJSONResponse(err)
|
return makeJSONResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,11 +54,12 @@ type Notification struct {
|
||||||
|
|
||||||
// TransactionEvent - structure used to pass messages from wallet to bus
|
// TransactionEvent - structure used to pass messages from wallet to bus
|
||||||
type TransactionEvent struct {
|
type TransactionEvent struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
BlockNumber *big.Int `json:"block-number"`
|
BlockNumber *big.Int `json:"block-number"`
|
||||||
Accounts []common.Address `json:"accounts"`
|
Accounts []common.Address `json:"accounts"`
|
||||||
NewTransactionsPerAccount map[common.Address]int `json:"new-transactions"`
|
NewTransactionsPerAccount map[common.Address]int `json:"new-transactions"`
|
||||||
ERC20 bool `json:"erc20"`
|
ERC20 bool `json:"erc20"`
|
||||||
|
MaxKnownBlocks map[common.Address]*big.Int `json:"max-known-blocks"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageEvent - structure used to pass messages from chat to bus
|
// MessageEvent - structure used to pass messages from chat to bus
|
||||||
|
@ -165,15 +166,17 @@ func (s *Service) transactionsHandler(payload TransactionEvent) {
|
||||||
limit := 20
|
limit := 20
|
||||||
if payload.BlockNumber != nil {
|
if payload.BlockNumber != nil {
|
||||||
for _, address := range payload.Accounts {
|
for _, address := range payload.Accounts {
|
||||||
log.Info("Handled transfer for address", "info", address)
|
if payload.BlockNumber.Cmp(payload.MaxKnownBlocks[address]) == 1 {
|
||||||
transfers, err := s.walletDB.GetTransfersByAddressAndBlock(address, payload.BlockNumber, int64(limit))
|
log.Info("Handled transfer for address", "info", address)
|
||||||
if err != nil {
|
transfers, err := s.walletDB.GetTransfersByAddressAndBlock(address, payload.BlockNumber, int64(limit))
|
||||||
log.Error("Could not fetch transfers", "error", err)
|
if err != nil {
|
||||||
}
|
log.Error("Could not fetch transfers", "error", err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, transaction := range transfers {
|
for _, transaction := range transfers {
|
||||||
n := s.buildTransactionNotification(transaction)
|
n := s.buildTransactionNotification(transaction)
|
||||||
pushMessage(n)
|
pushMessage(n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,6 +218,7 @@ func (s *Service) StartWalletWatcher() {
|
||||||
|
|
||||||
s.walletTransmitter.wg.Add(1)
|
s.walletTransmitter.wg.Add(1)
|
||||||
|
|
||||||
|
maxKnownBlocks := map[common.Address]*big.Int{}
|
||||||
go func() {
|
go func() {
|
||||||
defer s.walletTransmitter.wg.Done()
|
defer s.walletTransmitter.wg.Done()
|
||||||
for {
|
for {
|
||||||
|
@ -230,14 +234,21 @@ func (s *Service) StartWalletWatcher() {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
case event := <-events:
|
case event := <-events:
|
||||||
if event.Type == wallet.EventNewBlock {
|
if event.Type == wallet.EventNewBlock && len(maxKnownBlocks) > 0 {
|
||||||
s.transmitter.publisher.Send(TransactionEvent{
|
s.transmitter.publisher.Send(TransactionEvent{
|
||||||
Type: string(event.Type),
|
Type: string(event.Type),
|
||||||
BlockNumber: event.BlockNumber,
|
BlockNumber: event.BlockNumber,
|
||||||
Accounts: event.Accounts,
|
Accounts: event.Accounts,
|
||||||
NewTransactionsPerAccount: event.NewTransactionsPerAccount,
|
NewTransactionsPerAccount: event.NewTransactionsPerAccount,
|
||||||
ERC20: event.ERC20,
|
ERC20: event.ERC20,
|
||||||
|
MaxKnownBlocks: maxKnownBlocks,
|
||||||
})
|
})
|
||||||
|
} else if event.Type == wallet.EventMaxKnownBlock {
|
||||||
|
for _, address := range event.Accounts {
|
||||||
|
if _, ok := maxKnownBlocks[address]; !ok {
|
||||||
|
maxKnownBlocks[address] = event.BlockNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,12 @@ func TestTransactionNotification(t *testing.T) {
|
||||||
require.NoError(t, walletDb.ProcessBlocks(header.Address, big.NewInt(1), big.NewInt(1), []*wallet.DBHeader{header}))
|
require.NoError(t, walletDb.ProcessBlocks(header.Address, big.NewInt(1), big.NewInt(1), []*wallet.DBHeader{header}))
|
||||||
require.NoError(t, walletDb.ProcessTranfers(transfers, []*wallet.DBHeader{}))
|
require.NoError(t, walletDb.ProcessTranfers(transfers, []*wallet.DBHeader{}))
|
||||||
|
|
||||||
|
feed.Send(wallet.Event{
|
||||||
|
Type: wallet.EventMaxKnownBlock,
|
||||||
|
BlockNumber: big.NewInt(0),
|
||||||
|
Accounts: []common.Address{header.Address},
|
||||||
|
})
|
||||||
|
|
||||||
feed.Send(wallet.Event{
|
feed.Send(wallet.Event{
|
||||||
Type: wallet.EventNewBlock,
|
Type: wallet.EventNewBlock,
|
||||||
BlockNumber: header.Number,
|
BlockNumber: header.Number,
|
||||||
|
|
|
@ -442,14 +442,15 @@ func (c *newBlocksTransfersCommand) getTransfers(parent context.Context, header
|
||||||
// - runs fast indexing for each account separately
|
// - runs fast indexing for each account separately
|
||||||
// - starts listening to new blocks and watches for reorgs
|
// - starts listening to new blocks and watches for reorgs
|
||||||
type controlCommand struct {
|
type controlCommand struct {
|
||||||
accounts []common.Address
|
accounts []common.Address
|
||||||
db *Database
|
db *Database
|
||||||
eth *ETHTransferDownloader
|
eth *ETHTransferDownloader
|
||||||
erc20 *ERC20TransfersDownloader
|
erc20 *ERC20TransfersDownloader
|
||||||
chain *big.Int
|
chain *big.Int
|
||||||
client *ethclient.Client
|
client *ethclient.Client
|
||||||
feed *event.Feed
|
feed *event.Feed
|
||||||
safetyDepth *big.Int
|
safetyDepth *big.Int
|
||||||
|
watchNewBlocks bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// run fast indexing for every accont up to canonical chain head minus safety depth.
|
// run fast indexing for every accont up to canonical chain head minus safety depth.
|
||||||
|
@ -558,7 +559,7 @@ func loadTransfers(ctx context.Context, accounts []common.Address, db *Database,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, block := range blocks {
|
for _, block := range blocks {
|
||||||
erc20 := &transfersCommand{
|
transfers := &transfersCommand{
|
||||||
db: db,
|
db: db,
|
||||||
client: client,
|
client: client,
|
||||||
address: address,
|
address: address,
|
||||||
|
@ -570,8 +571,8 @@ func loadTransfers(ctx context.Context, accounts []common.Address, db *Database,
|
||||||
},
|
},
|
||||||
block: block,
|
block: block,
|
||||||
}
|
}
|
||||||
commands = append(commands, erc20)
|
commands = append(commands, transfers)
|
||||||
group.Add(erc20.Command())
|
group.Add(transfers.Command())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
|
@ -731,12 +732,6 @@ func (c *controlCommand) Run(parent context.Context) error {
|
||||||
if target.Cmp(zero) <= 0 {
|
if target.Cmp(zero) <= 0 {
|
||||||
target = zero
|
target = zero
|
||||||
}
|
}
|
||||||
ctx, cancel = context.WithTimeout(parent, 3*time.Second)
|
|
||||||
head, err = c.client.HeaderByNumber(ctx, target)
|
|
||||||
cancel()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fromByAddress := map[common.Address]*big.Int{}
|
fromByAddress := map[common.Address]*big.Int{}
|
||||||
toByAddress := map[common.Address]*big.Int{}
|
toByAddress := map[common.Address]*big.Int{}
|
||||||
|
@ -748,7 +743,7 @@ func (c *controlCommand) Run(parent context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
fromByAddress[address] = from
|
fromByAddress[address] = from
|
||||||
toByAddress[address] = head.Number
|
toByAddress[address] = target
|
||||||
}
|
}
|
||||||
|
|
||||||
bCache := newBalanceCache()
|
bCache := newBalanceCache()
|
||||||
|
@ -779,30 +774,56 @@ func (c *controlCommand) Run(parent context.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, address := range c.accounts {
|
||||||
|
for _, header := range cmnd.foundHeaders[address] {
|
||||||
|
c.feed.Send(Event{
|
||||||
|
Type: EventNewBlock,
|
||||||
|
BlockNumber: header.Number,
|
||||||
|
Accounts: []common.Address{address},
|
||||||
|
NewTransactionsPerAccount: map[common.Address]int{address: 20},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.feed.Send(Event{
|
c.feed.Send(Event{
|
||||||
Type: EventRecentHistoryReady,
|
Type: EventRecentHistoryReady,
|
||||||
Accounts: c.accounts,
|
Accounts: c.accounts,
|
||||||
BlockNumber: head.Number,
|
BlockNumber: target,
|
||||||
})
|
})
|
||||||
|
|
||||||
log.Info("watching new blocks", "start from", head.Number)
|
if c.watchNewBlocks {
|
||||||
cmd := &newBlocksTransfersCommand{
|
ctx, cancel = context.WithTimeout(parent, 3*time.Second)
|
||||||
db: c.db,
|
head, err = c.client.HeaderByNumber(ctx, target)
|
||||||
chain: c.chain,
|
cancel()
|
||||||
client: c.client,
|
if err != nil {
|
||||||
accounts: c.accounts,
|
return err
|
||||||
eth: c.eth,
|
}
|
||||||
erc20: c.erc20,
|
|
||||||
feed: c.feed,
|
|
||||||
initialFrom: toDBHeader(head),
|
|
||||||
from: toDBHeader(head),
|
|
||||||
lastFetchedBlockTime: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cmd.Command()(parent)
|
log.Info("watching new blocks", "start from", target)
|
||||||
if err != nil {
|
cmd := &newBlocksTransfersCommand{
|
||||||
log.Warn("error on running newBlocksTransfersCommand", "err", err)
|
db: c.db,
|
||||||
return err
|
chain: c.chain,
|
||||||
|
client: c.client,
|
||||||
|
accounts: c.accounts,
|
||||||
|
eth: c.eth,
|
||||||
|
erc20: c.erc20,
|
||||||
|
feed: c.feed,
|
||||||
|
initialFrom: toDBHeader(head),
|
||||||
|
from: toDBHeader(head),
|
||||||
|
lastFetchedBlockTime: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cmd.Command()(parent)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("error on running newBlocksTransfersCommand", "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.feed.Send(Event{
|
||||||
|
Type: EventNewBlock,
|
||||||
|
BlockNumber: target,
|
||||||
|
Accounts: []common.Address{},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("end control command")
|
log.Info("end control command")
|
||||||
|
@ -965,6 +986,7 @@ func (c *findAndCheckBlockRangeCommand) Run(parent context.Context) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
foundHeaders := map[common.Address][]*DBHeader{}
|
foundHeaders := map[common.Address][]*DBHeader{}
|
||||||
|
maxBlockNumber := big.NewInt(0)
|
||||||
for _, address := range c.accounts {
|
for _, address := range c.accounts {
|
||||||
ethHeaders := ethHeadersByAddress[address]
|
ethHeaders := ethHeadersByAddress[address]
|
||||||
erc20Headers := erc20HeadersByAddress[address]
|
erc20Headers := erc20HeadersByAddress[address]
|
||||||
|
@ -972,6 +994,12 @@ func (c *findAndCheckBlockRangeCommand) Run(parent context.Context) (err error)
|
||||||
allHeaders := append(ethHeaders, erc20Headers...)
|
allHeaders := append(ethHeaders, erc20Headers...)
|
||||||
foundHeaders[address] = allHeaders
|
foundHeaders[address] = allHeaders
|
||||||
|
|
||||||
|
for _, header := range allHeaders {
|
||||||
|
if header.Number.Cmp(maxBlockNumber) == 1 {
|
||||||
|
maxBlockNumber = header.Number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log.Debug("saving headers", "len", len(allHeaders), "address")
|
log.Debug("saving headers", "len", len(allHeaders), "address")
|
||||||
err = c.db.ProcessBlocks(address, newFromByAddress[address], c.toByAddress[address], allHeaders)
|
err = c.db.ProcessBlocks(address, newFromByAddress[address], c.toByAddress[address], allHeaders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -979,6 +1007,12 @@ func (c *findAndCheckBlockRangeCommand) Run(parent context.Context) (err error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.feed.Send(Event{
|
||||||
|
Type: EventMaxKnownBlock,
|
||||||
|
BlockNumber: maxBlockNumber,
|
||||||
|
Accounts: c.accounts,
|
||||||
|
})
|
||||||
|
|
||||||
c.foundHeaders = foundHeaders
|
c.foundHeaders = foundHeaders
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -110,12 +110,6 @@ func checkRanges(parent context.Context, client reactorClient, cache BalanceCach
|
||||||
}
|
}
|
||||||
if lb.Cmp(hb) == 0 {
|
if lb.Cmp(hb) == 0 {
|
||||||
log.Debug("balances are equal", "from", from, "to", to)
|
log.Debug("balances are equal", "from", from, "to", to)
|
||||||
// In case if balances are equal but non zero we want to check if
|
|
||||||
// eth_getTransactionCount return different values, because there
|
|
||||||
// still might be transactions
|
|
||||||
if lb.Cmp(zero) != 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := client.NonceAt(ctx, account, from)
|
ln, err := client.NonceAt(ctx, account, from)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -11,7 +11,8 @@ type EventType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// EventNewBlock emitted when new block was added to the same canonical chan.
|
// EventNewBlock emitted when new block was added to the same canonical chan.
|
||||||
EventNewBlock EventType = "newblock"
|
EventNewBlock EventType = "newblock"
|
||||||
|
EventMaxKnownBlock EventType = "maxKnownBlock"
|
||||||
// EventReorg emitted when canonical chain was changed. In this case, BlockNumber will be an earliest added block.
|
// EventReorg emitted when canonical chain was changed. In this case, BlockNumber will be an earliest added block.
|
||||||
EventReorg EventType = "reorg"
|
EventReorg EventType = "reorg"
|
||||||
// EventNewHistory emitted if transfer from older block was added.
|
// EventNewHistory emitted if transfer from older block was added.
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
@ -70,22 +69,14 @@ func (d *IterativeDownloader) Next(parent context.Context) ([]*DBHeader, *big.In
|
||||||
from = d.from
|
from = d.from
|
||||||
}
|
}
|
||||||
log.Info("load erc20 transfers in range", "from", from, "to", to)
|
log.Info("load erc20 transfers in range", "from", from, "to", to)
|
||||||
headres, err := d.downloader.GetHeadersInRange(parent, from, to)
|
headers, err := d.downloader.GetHeadersInRange(parent, from, to)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to get transfer in between two bloks", "from", from, "to", to, "error", err)
|
log.Error("failed to get transfer in between two bloks", "from", from, "to", to, "error", err)
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
// use integers instead of DBHeader
|
|
||||||
ctx, cancel := context.WithTimeout(parent, 5*time.Second)
|
|
||||||
header, err := d.client.HeaderByNumber(ctx, from)
|
|
||||||
cancel()
|
|
||||||
if err != nil {
|
|
||||||
log.Error("failed to get header by number", "from", d.from, "to", to, "error", err)
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.previous, d.to = d.to, header.Number
|
d.previous, d.to = d.to, from
|
||||||
return headres, d.from, to, nil
|
return headers, d.from, to, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Revert reverts last step progress. Should be used if application failed to process transfers.
|
// Revert reverts last step progress. Should be used if application failed to process transfers.
|
||||||
|
|
|
@ -32,7 +32,7 @@ func pollingPeriodByChain(chain *big.Int) time.Duration {
|
||||||
func reorgSafetyDepth(chain *big.Int) *big.Int {
|
func reorgSafetyDepth(chain *big.Int) *big.Int {
|
||||||
switch chain.Int64() {
|
switch chain.Int64() {
|
||||||
case int64(params.MainNetworkID):
|
case int64(params.MainNetworkID):
|
||||||
return big.NewInt(5)
|
return big.NewInt(2)
|
||||||
case int64(params.RopstenNetworkID):
|
case int64(params.RopstenNetworkID):
|
||||||
return big.NewInt(15)
|
return big.NewInt(15)
|
||||||
default:
|
default:
|
||||||
|
@ -63,21 +63,23 @@ type reactorClient interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReactor creates instance of the Reactor.
|
// NewReactor creates instance of the Reactor.
|
||||||
func NewReactor(db *Database, feed *event.Feed, client *ethclient.Client, chain *big.Int) *Reactor {
|
func NewReactor(db *Database, feed *event.Feed, client *ethclient.Client, chain *big.Int, watchNewBlocks bool) *Reactor {
|
||||||
return &Reactor{
|
return &Reactor{
|
||||||
db: db,
|
db: db,
|
||||||
client: client,
|
client: client,
|
||||||
feed: feed,
|
feed: feed,
|
||||||
chain: chain,
|
chain: chain,
|
||||||
|
watchNewBlocks: watchNewBlocks,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reactor listens to new blocks and stores transfers into the database.
|
// Reactor listens to new blocks and stores transfers into the database.
|
||||||
type Reactor struct {
|
type Reactor struct {
|
||||||
client *ethclient.Client
|
client *ethclient.Client
|
||||||
db *Database
|
db *Database
|
||||||
feed *event.Feed
|
feed *event.Feed
|
||||||
chain *big.Int
|
chain *big.Int
|
||||||
|
watchNewBlocks bool
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
group *Group
|
group *Group
|
||||||
|
@ -96,9 +98,10 @@ func (r *Reactor) newControlCommand(accounts []common.Address) *controlCommand {
|
||||||
signer: signer,
|
signer: signer,
|
||||||
db: r.db,
|
db: r.db,
|
||||||
},
|
},
|
||||||
erc20: NewERC20TransfersDownloader(r.client, accounts, signer),
|
erc20: NewERC20TransfersDownloader(r.client, accounts, signer),
|
||||||
feed: r.feed,
|
feed: r.feed,
|
||||||
safetyDepth: reorgSafetyDepth(r.chain),
|
safetyDepth: reorgSafetyDepth(r.chain),
|
||||||
|
watchNewBlocks: r.watchNewBlocks,
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctl
|
return ctl
|
||||||
|
|
|
@ -52,8 +52,8 @@ func (s *Service) GetFeed() *event.Feed {
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartReactor separately because it requires known ethereum address, which will become available only after login.
|
// StartReactor separately because it requires known ethereum address, which will become available only after login.
|
||||||
func (s *Service) StartReactor(client *ethclient.Client, accounts []common.Address, chain *big.Int) error {
|
func (s *Service) StartReactor(client *ethclient.Client, accounts []common.Address, chain *big.Int, watchNewBlocks bool) error {
|
||||||
reactor := NewReactor(s.db, s.feed, client, chain)
|
reactor := NewReactor(s.db, s.feed, client, chain, watchNewBlocks)
|
||||||
err := reactor.Start(accounts)
|
err := reactor.Start(accounts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (s *ReactorChangesSuite) SetupTest() {
|
||||||
s.backend, err = testchain.NewBackend()
|
s.backend, err = testchain.NewBackend()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.feed = &event.Feed{}
|
s.feed = &event.Feed{}
|
||||||
s.reactor = NewReactor(s.db, &event.Feed{}, s.backend.Client, big.NewInt(1337))
|
s.reactor = NewReactor(s.db, &event.Feed{}, s.backend.Client, big.NewInt(1337), true)
|
||||||
account, err := crypto.GenerateKey()
|
account, err := crypto.GenerateKey()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.first = crypto.PubkeyToAddress(account.PublicKey)
|
s.first = crypto.PubkeyToAddress(account.PublicKey)
|
||||||
|
@ -123,13 +123,13 @@ func TestServiceStartStop(t *testing.T) {
|
||||||
account, err := crypto.GenerateKey()
|
account, err := crypto.GenerateKey()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = s.StartReactor(backend.Client, []common.Address{crypto.PubkeyToAddress(account.PublicKey)}, big.NewInt(1337))
|
err = s.StartReactor(backend.Client, []common.Address{crypto.PubkeyToAddress(account.PublicKey)}, big.NewInt(1337), true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.NoError(t, s.Stop())
|
require.NoError(t, s.Stop())
|
||||||
require.NoError(t, s.Start(nil))
|
require.NoError(t, s.Start(nil))
|
||||||
|
|
||||||
err = s.StartReactor(backend.Client, []common.Address{crypto.PubkeyToAddress(account.PublicKey)}, big.NewInt(1337))
|
err = s.StartReactor(backend.Client, []common.Address{crypto.PubkeyToAddress(account.PublicKey)}, big.NewInt(1337), true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, s.Stop())
|
require.NoError(t, s.Stop())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue