mirror of
https://github.com/grassrootseconomics/eth-tracker.git
synced 2025-05-01 12:11:01 +02:00
feat: add cache updaters, blacklist
This commit is contained in:
parent
87e91907dd
commit
0f55babf41
@ -16,3 +16,4 @@ registries = [
|
|||||||
"0xd1FB944748aca327a1ba036B082993D9dd9Bfa0C",
|
"0xd1FB944748aca327a1ba036B082993D9dd9Bfa0C",
|
||||||
"0x0cc9f4fff962def35bb34a53691180b13e653030",
|
"0x0cc9f4fff962def35bb34a53691180b13e653030",
|
||||||
]
|
]
|
||||||
|
blacklist = ["0x765DE816845861e75A25fCA122bb6898B8B1282a"]
|
||||||
|
23
internal/cache/bootstrap.go
vendored
23
internal/cache/bootstrap.go
vendored
@ -10,11 +10,15 @@ import (
|
|||||||
"github.com/grassrootseconomics/w3-celo/module/eth"
|
"github.com/grassrootseconomics/w3-celo/module/eth"
|
||||||
)
|
)
|
||||||
|
|
||||||
func bootstrapAllGESmartContracts(ctx context.Context, registries []string, chain *chain.Chain, cache Cache) error {
|
func bootstrapAllGESmartContracts(ctx context.Context, registries []string, chain *chain.Chain, cache Cache) (WatchableIndex, error) {
|
||||||
|
var (
|
||||||
|
watchableIndex = make(WatchableIndex)
|
||||||
|
)
|
||||||
|
|
||||||
for _, registry := range registries {
|
for _, registry := range registries {
|
||||||
registryMap, err := chain.Provider.RegistryMap(ctx, w3.A(registry))
|
registryMap, err := chain.Provider.RegistryMap(ctx, w3.A(registry))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range registryMap {
|
for _, v := range registryMap {
|
||||||
@ -24,18 +28,20 @@ func bootstrapAllGESmartContracts(ctx context.Context, registries []string, chai
|
|||||||
if registryMap[celoutils.TokenIndex] != common.ZeroAddress {
|
if registryMap[celoutils.TokenIndex] != common.ZeroAddress {
|
||||||
tokens, err := chain.GetAllTokensFromTokenIndex(ctx, registryMap[celoutils.TokenIndex])
|
tokens, err := chain.GetAllTokensFromTokenIndex(ctx, registryMap[celoutils.TokenIndex])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, token := range tokens {
|
for _, token := range tokens {
|
||||||
cache.Add(token.Hex())
|
cache.Add(token.Hex())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchableIndex[registryMap[celoutils.TokenIndex].Hex()] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if registryMap[celoutils.PoolIndex] != common.ZeroAddress {
|
if registryMap[celoutils.PoolIndex] != common.ZeroAddress {
|
||||||
pools, err := chain.GetAllTokensFromTokenIndex(ctx, registryMap[celoutils.PoolIndex])
|
pools, err := chain.GetAllTokensFromTokenIndex(ctx, registryMap[celoutils.PoolIndex])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pool := range pools {
|
for _, pool := range pools {
|
||||||
@ -51,21 +57,24 @@ func bootstrapAllGESmartContracts(ctx context.Context, registries []string, chai
|
|||||||
eth.CallFunc(pool, quoterGetter).Returns(&priceQuoter),
|
eth.CallFunc(pool, quoterGetter).Returns(&priceQuoter),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
cache.Add(priceQuoter.Hex())
|
cache.Add(priceQuoter.Hex())
|
||||||
|
|
||||||
poolTokens, err := chain.GetAllTokensFromTokenIndex(ctx, poolTokenRegistry)
|
poolTokens, err := chain.GetAllTokensFromTokenIndex(ctx, poolTokenRegistry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, token := range poolTokens {
|
for _, token := range poolTokens {
|
||||||
cache.Add(token.Hex())
|
cache.Add(token.Hex())
|
||||||
}
|
}
|
||||||
|
watchableIndex[poolTokenRegistry.Hex()] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchableIndex[registryMap[celoutils.PoolIndex].Hex()] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return watchableIndex, nil
|
||||||
}
|
}
|
||||||
|
19
internal/cache/cache.go
vendored
19
internal/cache/cache.go
vendored
@ -12,7 +12,10 @@ type (
|
|||||||
Cache interface {
|
Cache interface {
|
||||||
Purge() error
|
Purge() error
|
||||||
Exists(string) bool
|
Exists(string) bool
|
||||||
Add(string) bool
|
Add(string)
|
||||||
|
Remove(string)
|
||||||
|
SetWatchableIndex(WatchableIndex)
|
||||||
|
ISWatchAbleIndex(string) bool
|
||||||
Size() int
|
Size() int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +24,10 @@ type (
|
|||||||
Chain *chain.Chain
|
Chain *chain.Chain
|
||||||
CacheType string
|
CacheType string
|
||||||
Registries []string
|
Registries []string
|
||||||
|
Blacklist []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WatchableIndex map[string]bool
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -41,14 +47,21 @@ func New(o CacheOpts) (Cache, error) {
|
|||||||
cache = NewMapCache()
|
cache = NewMapCache()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bootstrapAllGESmartContracts(
|
watchableIndex, err := bootstrapAllGESmartContracts(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
o.Registries,
|
o.Registries,
|
||||||
o.Chain,
|
o.Chain,
|
||||||
cache,
|
cache,
|
||||||
); err != nil {
|
)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
cache.SetWatchableIndex(watchableIndex)
|
||||||
|
|
||||||
|
for _, address := range o.Blacklist {
|
||||||
|
cache.Remove(address)
|
||||||
|
}
|
||||||
|
|
||||||
o.Logg.Debug("cache bootstrap complete", "cached_addresses", cache.Size())
|
o.Logg.Debug("cache bootstrap complete", "cached_addresses", cache.Size())
|
||||||
|
|
||||||
return cache, nil
|
return cache, nil
|
||||||
|
21
internal/cache/map.go
vendored
21
internal/cache/map.go
vendored
@ -8,8 +8,9 @@ import (
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
MapCache struct {
|
MapCache struct {
|
||||||
mapCache *xsync.Map
|
mapCache *xsync.Map
|
||||||
logg *slog.Logger
|
logg *slog.Logger
|
||||||
|
watchableIndex WatchableIndex
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,11 +30,23 @@ func (c *MapCache) Exists(key string) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MapCache) Add(key string) bool {
|
func (c *MapCache) Add(key string) {
|
||||||
c.mapCache.Store(key, nil)
|
c.mapCache.Store(key, nil)
|
||||||
return true
|
}
|
||||||
|
|
||||||
|
func (c *MapCache) Remove(key string) {
|
||||||
|
c.mapCache.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MapCache) Size() int {
|
func (c *MapCache) Size() int {
|
||||||
return c.mapCache.Size()
|
return c.mapCache.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *MapCache) SetWatchableIndex(watchableIndex WatchableIndex) {
|
||||||
|
c.watchableIndex = watchableIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *MapCache) ISWatchAbleIndex(key string) bool {
|
||||||
|
_, ok := c.watchableIndex[key]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
114
internal/handler/index_add.go
Normal file
114
internal/handler/index_add.go
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/celo-org/celo-blockchain/common"
|
||||||
|
"github.com/grassrootseconomics/celo-tracker/internal/cache"
|
||||||
|
"github.com/grassrootseconomics/celo-tracker/internal/emitter"
|
||||||
|
"github.com/grassrootseconomics/w3-celo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
IndexAddHandler struct {
|
||||||
|
topicHash common.Hash
|
||||||
|
event *w3.Event
|
||||||
|
cache cache.Cache
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
indexAddTopicHash = w3.H("0xa226db3f664042183ee0281230bba26cbf7b5057e50aee7f25a175ff45ce4d7f")
|
||||||
|
indexAddEvent = w3.MustNewEvent("AddressAdded(address _token)")
|
||||||
|
indexAddSig = w3.MustNewFunc("add(address)", "bool")
|
||||||
|
indexRegisterSig = w3.MustNewFunc("register(address)", "bool")
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *IndexAddHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error {
|
||||||
|
if msg.Log.Topics[0] == indexAddTopicHash {
|
||||||
|
var (
|
||||||
|
address common.Address
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := indexAddEvent.DecodeArgs(msg.Log, &address); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
indexAddEvent := Event{
|
||||||
|
Block: msg.Log.BlockNumber,
|
||||||
|
ContractAddress: msg.Log.Address.Hex(),
|
||||||
|
Success: true,
|
||||||
|
Timestamp: msg.BlockTime,
|
||||||
|
TxHash: msg.Log.TxHash.Hex(),
|
||||||
|
TxType: "INDEX_ADD",
|
||||||
|
Payload: map[string]any{
|
||||||
|
"address": address.Hex(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.cache.ISWatchAbleIndex(address.Hex()) {
|
||||||
|
h.cache.Add(address.Hex())
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter.Emit(ctx, indexAddEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *IndexAddHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error {
|
||||||
|
if len(msg.InputData) < 8 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch msg.InputData[:8] {
|
||||||
|
case "0a3b0a4f":
|
||||||
|
var (
|
||||||
|
address common.Address
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := indexAddSig.DecodeArgs(w3.B(msg.InputData), &address); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
indexAddEvent := Event{
|
||||||
|
Block: msg.Block,
|
||||||
|
ContractAddress: msg.ContractAddress,
|
||||||
|
Success: false,
|
||||||
|
Timestamp: msg.Timestamp,
|
||||||
|
TxHash: msg.TxHash,
|
||||||
|
TxType: "INDEX_ADD",
|
||||||
|
Payload: map[string]any{
|
||||||
|
"revertReason": msg.RevertReason,
|
||||||
|
"address": address.Hex(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter.Emit(ctx, indexAddEvent)
|
||||||
|
case "4420e486":
|
||||||
|
var (
|
||||||
|
address common.Address
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := indexRegisterSig.DecodeArgs(w3.B(msg.InputData), &address); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
indexAddEvent := Event{
|
||||||
|
Block: msg.Block,
|
||||||
|
ContractAddress: msg.ContractAddress,
|
||||||
|
Success: false,
|
||||||
|
Timestamp: msg.Timestamp,
|
||||||
|
TxHash: msg.TxHash,
|
||||||
|
TxType: "INDEX_ADD",
|
||||||
|
Payload: map[string]any{
|
||||||
|
"revertReason": msg.RevertReason,
|
||||||
|
"address": address.Hex(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter.Emit(ctx, indexAddEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
90
internal/handler/index_remove.go
Normal file
90
internal/handler/index_remove.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/celo-org/celo-blockchain/common"
|
||||||
|
"github.com/grassrootseconomics/celo-tracker/internal/cache"
|
||||||
|
"github.com/grassrootseconomics/celo-tracker/internal/emitter"
|
||||||
|
"github.com/grassrootseconomics/w3-celo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
IndexRemoveHandler struct {
|
||||||
|
topicHash common.Hash
|
||||||
|
event *w3.Event
|
||||||
|
cache cache.Cache
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
indexRemoveTopicHash = w3.H("0x24a12366c02e13fe4a9e03d86a8952e85bb74a456c16e4a18b6d8295700b74bb")
|
||||||
|
indexRemoveEvent = w3.MustNewEvent("AddressRemoved(address _token)")
|
||||||
|
indexRemoveSig = w3.MustNewFunc("remove(address)", "bool")
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *IndexRemoveHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error {
|
||||||
|
if msg.Log.Topics[0] == indexRemoveTopicHash {
|
||||||
|
var (
|
||||||
|
address common.Address
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := indexRemoveEvent.DecodeArgs(msg.Log, &address); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
indexRemoveEvent := Event{
|
||||||
|
Block: msg.Log.BlockNumber,
|
||||||
|
ContractAddress: msg.Log.Address.Hex(),
|
||||||
|
Success: true,
|
||||||
|
Timestamp: msg.BlockTime,
|
||||||
|
TxHash: msg.Log.TxHash.Hex(),
|
||||||
|
TxType: "INDEX_REMOVE",
|
||||||
|
Payload: map[string]any{
|
||||||
|
"address": address.Hex(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.cache.ISWatchAbleIndex(address.Hex()) {
|
||||||
|
h.cache.Remove(address.Hex())
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter.Emit(ctx, indexRemoveEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *IndexRemoveHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error {
|
||||||
|
if len(msg.InputData) < 8 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch msg.InputData[:8] {
|
||||||
|
case "29092d0e":
|
||||||
|
var (
|
||||||
|
address common.Address
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := indexRemoveSig.DecodeArgs(w3.B(msg.InputData), &address); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
indexRemoveEvent := Event{
|
||||||
|
Block: msg.Block,
|
||||||
|
ContractAddress: msg.ContractAddress,
|
||||||
|
Success: false,
|
||||||
|
Timestamp: msg.Timestamp,
|
||||||
|
TxHash: msg.TxHash,
|
||||||
|
TxType: "INDEX_REMOVE",
|
||||||
|
Payload: map[string]any{
|
||||||
|
"revertReason": msg.RevertReason,
|
||||||
|
"address": address.Hex(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter.Emit(ctx, indexRemoveEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
89
internal/handler/quoter_price.go
Normal file
89
internal/handler/quoter_price.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/celo-org/celo-blockchain/common"
|
||||||
|
"github.com/grassrootseconomics/celo-tracker/internal/emitter"
|
||||||
|
"github.com/grassrootseconomics/w3-celo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
QuoterPriceHandler struct {
|
||||||
|
topicHash common.Hash
|
||||||
|
event *w3.Event
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
quoterPriceTopicHash = w3.H("0xdb9ce1a76955721ca61ac50cd1b87f9ab8620325c8619a62192c2dc7871d56b1")
|
||||||
|
quoterPriceEvent = w3.MustNewEvent("PriceIndexUpdated(address _tokenAddress, uint256 _exchangeRate)")
|
||||||
|
quoterPriceToSig = w3.MustNewFunc("setPriceIndexValue(address, uint256)", "uint256")
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *QuoterPriceHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error {
|
||||||
|
if msg.Log.Topics[0] == quoterPriceTopicHash {
|
||||||
|
var (
|
||||||
|
token common.Address
|
||||||
|
exchangeRate big.Int
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := quoterPriceEvent.DecodeArgs(msg.Log, &token, &exchangeRate); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
quoterPriceEvent := Event{
|
||||||
|
Block: msg.Log.BlockNumber,
|
||||||
|
ContractAddress: msg.Log.Address.Hex(),
|
||||||
|
Success: true,
|
||||||
|
Timestamp: msg.BlockTime,
|
||||||
|
TxHash: msg.Log.TxHash.Hex(),
|
||||||
|
TxType: "QUOTER_PRICE_INDEX_UPDATED",
|
||||||
|
Payload: map[string]any{
|
||||||
|
"token": token.Hex(),
|
||||||
|
"exchangeRate": exchangeRate.String(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter.Emit(ctx, quoterPriceEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *QuoterPriceHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error {
|
||||||
|
if len(msg.InputData) < 8 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch msg.InputData[:8] {
|
||||||
|
case "ebc59dff":
|
||||||
|
var (
|
||||||
|
token common.Address
|
||||||
|
exchangeRate big.Int
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := quoterPriceToSig.DecodeArgs(w3.B(msg.InputData), &token, &exchangeRate); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
quoterPriceEvent := Event{
|
||||||
|
Block: msg.Block,
|
||||||
|
ContractAddress: msg.ContractAddress,
|
||||||
|
Success: false,
|
||||||
|
Timestamp: msg.Timestamp,
|
||||||
|
TxHash: msg.TxHash,
|
||||||
|
TxType: "QUOTER_PRICE_INDEX_UPDATED",
|
||||||
|
Payload: map[string]any{
|
||||||
|
"revertReason": msg.RevertReason,
|
||||||
|
"token": token.Hex(),
|
||||||
|
"exchangeRate": exchangeRate.String(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return emitter.Emit(ctx, quoterPriceEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user