perf: add contract info cache for spam token/nft transactions (#994)
This commit is contained in:
parent
0c95abe025
commit
8c2a59aa0e
@ -36,6 +36,9 @@ type Worker struct {
|
||||
metrics *common.Metrics
|
||||
}
|
||||
|
||||
// contractInfoCache is a temporary cache of contract information for ethereum token transfers
|
||||
type contractInfoCache = map[string]*bchain.ContractInfo
|
||||
|
||||
// NewWorker creates new api worker
|
||||
func NewWorker(db *db.RocksDB, chain bchain.BlockChain, mempool bchain.Mempool, txCache *db.TxCache, metrics *common.Metrics, is *common.InternalState, fiatRates *fiat.FiatRates) (*Worker, error) {
|
||||
w := &Worker{
|
||||
@ -666,39 +669,49 @@ func (w *Worker) getContractDescriptorInfo(cd bchain.AddressDescriptor, typeFrom
|
||||
}
|
||||
|
||||
func (w *Worker) getEthereumTokensTransfers(transfers bchain.TokenTransfers, addresses map[string]struct{}) []TokenTransfer {
|
||||
sort.Sort(transfers)
|
||||
tokens := make([]TokenTransfer, len(transfers))
|
||||
for i := range transfers {
|
||||
t := transfers[i]
|
||||
typeName := bchain.EthereumTokenTypeMap[t.Type]
|
||||
contractInfo, _, err := w.getContractInfo(t.Contract, typeName)
|
||||
if err != nil {
|
||||
glog.Errorf("getContractInfo error %v, contract %v", err, t.Contract)
|
||||
continue
|
||||
}
|
||||
var value *Amount
|
||||
var values []MultiTokenValue
|
||||
if t.Type == bchain.MultiToken {
|
||||
values = make([]MultiTokenValue, len(t.MultiTokenValues))
|
||||
for j := range values {
|
||||
values[j].Id = (*Amount)(&t.MultiTokenValues[j].Id)
|
||||
values[j].Value = (*Amount)(&t.MultiTokenValues[j].Value)
|
||||
if len(transfers) > 0 {
|
||||
sort.Sort(transfers)
|
||||
contractCache := make(contractInfoCache)
|
||||
for i := range transfers {
|
||||
t := transfers[i]
|
||||
typeName := bchain.EthereumTokenTypeMap[t.Type]
|
||||
var contractInfo *bchain.ContractInfo
|
||||
if info, ok := contractCache[t.Contract]; ok {
|
||||
contractInfo = info
|
||||
} else {
|
||||
info, _, err := w.getContractInfo(t.Contract, typeName)
|
||||
if err != nil {
|
||||
glog.Errorf("getContractInfo error %v, contract %v", err, t.Contract)
|
||||
continue
|
||||
}
|
||||
contractInfo = info
|
||||
contractCache[t.Contract] = info
|
||||
}
|
||||
var value *Amount
|
||||
var values []MultiTokenValue
|
||||
if t.Type == bchain.MultiToken {
|
||||
values = make([]MultiTokenValue, len(t.MultiTokenValues))
|
||||
for j := range values {
|
||||
values[j].Id = (*Amount)(&t.MultiTokenValues[j].Id)
|
||||
values[j].Value = (*Amount)(&t.MultiTokenValues[j].Value)
|
||||
}
|
||||
} else {
|
||||
value = (*Amount)(&t.Value)
|
||||
}
|
||||
aggregateAddress(addresses, t.From)
|
||||
aggregateAddress(addresses, t.To)
|
||||
tokens[i] = TokenTransfer{
|
||||
Type: typeName,
|
||||
Contract: t.Contract,
|
||||
From: t.From,
|
||||
To: t.To,
|
||||
Value: value,
|
||||
MultiTokenValues: values,
|
||||
Decimals: contractInfo.Decimals,
|
||||
Name: contractInfo.Name,
|
||||
Symbol: contractInfo.Symbol,
|
||||
}
|
||||
} else {
|
||||
value = (*Amount)(&t.Value)
|
||||
}
|
||||
aggregateAddress(addresses, t.From)
|
||||
aggregateAddress(addresses, t.To)
|
||||
tokens[i] = TokenTransfer{
|
||||
Type: typeName,
|
||||
Contract: t.Contract,
|
||||
From: t.From,
|
||||
To: t.To,
|
||||
Value: value,
|
||||
MultiTokenValues: values,
|
||||
Decimals: contractInfo.Decimals,
|
||||
Name: contractInfo.Name,
|
||||
Symbol: contractInfo.Symbol,
|
||||
}
|
||||
}
|
||||
return tokens
|
||||
|
||||
Loading…
Reference in New Issue
Block a user