Skip to content

Commit

Permalink
[wallet] Detect non archival RPC node
Browse files Browse the repository at this point in the history
  • Loading branch information
rasom committed Jan 25, 2021
1 parent 2427b3c commit d8bccaf
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 19 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.68.7
0.68.8
10 changes: 9 additions & 1 deletion services/wallet/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ func (api *API) GetTransfersByAddress(ctx context.Context, address common.Addres

from, err := findFirstRange(ctx, address, block, api.s.client)
if err != nil {
return nil, err
if nonArchivalNodeError(err) {
api.s.feed.Send(Event{
Type: EventNonArchivalNodeDetected,
})
from = big.NewInt(0).Sub(block, big.NewInt(100))
} else {
log.Error("first range error", "error", err)
return nil, err
}
}
fromByAddress := map[common.Address]*big.Int{address: from}
toByAddress := map[common.Address]*big.Int{address: block}
Expand Down
69 changes: 52 additions & 17 deletions services/wallet/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"math/big"
"strings"
"time"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -24,6 +25,7 @@ type ethHistoricalCommand struct {
balanceCache *balanceCache
feed *event.Feed
foundHeaders []*DBHeader
error error
noLimit bool

from, to, resultingFrom *big.Int
Expand All @@ -43,7 +45,8 @@ func (c *ethHistoricalCommand) Run(ctx context.Context) (err error) {
from, headers, err := findBlocksWithEthTransfers(ctx, c.client, c.balanceCache, c.eth, c.address, c.from, c.to, c.noLimit)

if err != nil {
return err
c.error = err
return nil
}

c.foundHeaders = headers
Expand Down Expand Up @@ -442,16 +445,17 @@ func (c *newBlocksTransfersCommand) getTransfers(parent context.Context, header
// - runs fast indexing for each account separately
// - starts listening to new blocks and watches for reorgs
type controlCommand struct {
accounts []common.Address
db *Database
eth *ETHTransferDownloader
erc20 *ERC20TransfersDownloader
chain *big.Int
client *ethclient.Client
feed *event.Feed
safetyDepth *big.Int
watchNewBlocks bool
errorsCount int
accounts []common.Address
db *Database
eth *ETHTransferDownloader
erc20 *ERC20TransfersDownloader
chain *big.Int
client *ethclient.Client
feed *event.Feed
safetyDepth *big.Int
watchNewBlocks bool
errorsCount int
nonArchivalRPCNode bool
}

// run fast indexing for every accont up to canonical chain head minus safety depth.
Expand Down Expand Up @@ -488,6 +492,9 @@ func (c *findAndCheckBlockRangeCommand) fastIndex(ctx context.Context, bCache *b
resultingFromByAddress := map[common.Address]*big.Int{}
headers := map[common.Address][]*DBHeader{}
for _, command := range commands {
if command.error != nil {
return nil, nil, command.error
}
resultingFromByAddress[command.address] = command.resultingFrom
headers[command.address] = command.foundHeaders
}
Expand Down Expand Up @@ -730,12 +737,16 @@ func (c *controlCommand) Run(parent context.Context) error {
return err
}

fromMap, err := findFirstRanges(parent, accountsWithoutHistory, head.Number, c.client)
if err != nil {
if c.NewError(err) {
return nil
fromMap := map[common.Address]*big.Int{}

if !c.nonArchivalRPCNode {
fromMap, err = findFirstRanges(parent, accountsWithoutHistory, head.Number, c.client)
if err != nil {
if c.NewError(err) {
return nil
}
return err
}
return err
}

target := new(big.Int).Sub(head.Number, c.safetyDepth)
Expand All @@ -751,6 +762,9 @@ func (c *controlCommand) Run(parent context.Context) error {
if !ok {
from = fromMap[address]
}
if c.nonArchivalRPCNode {
from = big.NewInt(0).Sub(target, big.NewInt(100))
}

fromByAddress[address] = from
toByAddress[address] = target
Expand All @@ -776,6 +790,13 @@ func (c *controlCommand) Run(parent context.Context) error {
return err
}

if cmnd.error != nil {
if c.NewError(cmnd.error) {
return nil
}
return cmnd.error
}

downloader := &ETHTransferDownloader{
client: c.client,
accounts: c.accounts,
Expand Down Expand Up @@ -852,9 +873,21 @@ func (c *controlCommand) Run(parent context.Context) error {
return err
}

func nonArchivalNodeError(err error) bool {
return strings.Contains(err.Error(), "missing trie node") ||
strings.Contains(err.Error(), "project ID does not have access to archive state")
}

func (c *controlCommand) NewError(err error) bool {
c.errorsCount++
log.Error("controlCommand error", "error", err, "counter", c.errorsCount)
if nonArchivalNodeError(err) {
log.Info("Non archival node detected")
c.nonArchivalRPCNode = true
c.feed.Send(Event{
Type: EventNonArchivalNodeDetected,
})
}
if c.errorsCount >= 3 {
c.feed.Send(Event{
Type: EventFetchingHistoryError,
Expand Down Expand Up @@ -994,6 +1027,7 @@ type findAndCheckBlockRangeCommand struct {
toByAddress map[common.Address]*big.Int
foundHeaders map[common.Address][]*DBHeader
noLimit bool
error error
}

func (c *findAndCheckBlockRangeCommand) Command() Command {
Expand All @@ -1007,7 +1041,8 @@ func (c *findAndCheckBlockRangeCommand) Run(parent context.Context) (err error)
log.Debug("start findAndCHeckBlockRangeCommand")
newFromByAddress, ethHeadersByAddress, err := c.fastIndex(parent, c.balanceCache, c.fromByAddress, c.toByAddress)
if err != nil {
return err
c.error = err
return nil
}
if c.noLimit {
newFromByAddress = map[common.Address]*big.Int{}
Expand Down
2 changes: 2 additions & 0 deletions services/wallet/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const (
EventRecentHistoryReady EventType = "recent-history-ready"
// EventRecentHistoryError emitted when fetching of tx history failed
EventFetchingHistoryError EventType = "fetching-history-error"
// EventNonArchivalNodeDetected emitted when a connection to a non archival node is detected
EventNonArchivalNodeDetected EventType = "non-archival-node-detected"
)

// Event is a type for wallet events.
Expand Down

0 comments on commit d8bccaf

Please sign in to comment.