Skip to content

Commit

Permalink
use lru cache across blocks for token symbol and decimals
Browse files Browse the repository at this point in the history
  • Loading branch information
marklandgrebe-cb committed Oct 25, 2024
1 parent d3f547d commit 0d7dd7b
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 16 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/coinbase/rosetta-sdk-go v0.8.6
github.com/coinbase/rosetta-sdk-go/types v1.0.0
github.com/ethereum/go-ethereum v1.13.8
github.com/hashicorp/golang-lru v0.5.1
github.com/neilotoole/errgroup v0.1.6
github.com/stretchr/testify v1.8.4
golang.org/x/crypto v0.17.0
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw=
Expand Down
37 changes: 21 additions & 16 deletions services/block_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ import (
"encoding/json"
"errors"
"fmt"
"log"
"math"
"math/big"

goEthereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common/hexutil"
lru "github.com/hashicorp/golang-lru"

client "github.com/coinbase/rosetta-geth-sdk/client"
construction "github.com/coinbase/rosetta-geth-sdk/services/construction"
Expand All @@ -38,23 +40,33 @@ import (
)

const (
// LRUCacheSize determines how many contract currencies we cache
LRUCacheSize = 100

OpenEthereumTrace = iota // == 2
)

// BlockAPIService implements the server.BlockAPIServicer interface.
type BlockAPIService struct {
config *configuration.Configuration
client construction.Client
config *configuration.Configuration
client construction.Client
currencyCache *lru.Cache
}

// NewBlockAPIService creates a new instance of a BlockAPIService.
func NewBlockAPIService(
cfg *configuration.Configuration,
client construction.Client,
) *BlockAPIService {
currencyCache, err := lru.New(LRUCacheSize)
if err != nil {
log.Fatalln(err)
}

return &BlockAPIService{
config: cfg,
client: client,
config: cfg,
client: client,
currencyCache: currencyCache,
}
}

Expand All @@ -67,9 +79,6 @@ func (s *BlockAPIService) populateTransactions(
rosettaCfg := s.client.GetRosettaConfig()
transactions := make([]*RosettaTypes.Transaction, 0)

// Create a shared currency map for all transactions in this block
contractCurrencyMap := make(map[string]*client.ContractCurrency)

if rosettaCfg.SupportRewardTx {
// Compute reward transaction (block + uncle reward)
rewardTx := s.client.BlockRewardTransaction(
Expand All @@ -85,7 +94,7 @@ func (s *BlockAPIService) populateTransactions(
// Bridge tx is already handled in PopulateCrossChainTransactions flow
continue
}
transaction, err := s.PopulateTransaction(ctx, tx, contractCurrencyMap)
transaction, err := s.PopulateTransaction(ctx, tx)
if err != nil {
return nil, fmt.Errorf("cannot parse %s: %w", tx.TxHash, err)
}
Expand All @@ -98,7 +107,6 @@ func (s *BlockAPIService) populateTransactions(
func (s *BlockAPIService) PopulateTransaction(
ctx context.Context,
tx *client.LoadedTransaction,
contractCurrencyMap map[string]*client.ContractCurrency,
) (*RosettaTypes.Transaction, error) {
ops, err := s.client.ParseOps(tx)
if err != nil {
Expand All @@ -124,13 +132,13 @@ func (s *BlockAPIService) PopulateTransaction(
var currency *client.ContractCurrency
var err error

if cachedCurrency, found := contractCurrencyMap[addressStr]; found {
currency = cachedCurrency
if cachedCurrency, found := s.currencyCache.Get(addressStr); found {
currency = cachedCurrency.(*client.ContractCurrency)
} else {
if currency, err = s.client.GetContractCurrency(log.Address, true); err != nil {
return nil, err
}
contractCurrencyMap[addressStr] = currency
s.currencyCache.Add(addressStr, currency)
}

if currency.Symbol == client.UnknownERC20Symbol && !s.config.RosettaCfg.IndexUnknownTokens {
Expand Down Expand Up @@ -476,10 +484,7 @@ func (s *BlockAPIService) BlockTransaction(
loadedTx.FeeBurned = nil
}

// Create a shared currency map for all logs for this transaction
contractCurrencyMap := make(map[string]*client.ContractCurrency)

transaction, err := s.PopulateTransaction(ctx, loadedTx, contractCurrencyMap)
transaction, err := s.PopulateTransaction(ctx, loadedTx)
if err != nil {
return nil, AssetTypes.WrapErr(AssetTypes.ErrInternalError, fmt.Errorf("unable to populate tx: %w", err))
}
Expand Down

0 comments on commit 0d7dd7b

Please sign in to comment.