mirror of
				https://github.com/grassrootseconomics/eth-tracker.git
				synced 2025-10-31 00:34:13 +01:00 
			
		
		
		
	feat: add cache updaters, blacklist
This commit is contained in:
		
							parent
							
								
									87e91907dd
								
							
						
					
					
						commit
						0f55babf41
					
				| @ -16,3 +16,4 @@ registries = [ | ||||
|     "0xd1FB944748aca327a1ba036B082993D9dd9Bfa0C", | ||||
|     "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" | ||||
| ) | ||||
| 
 | ||||
| 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 { | ||||
| 		registryMap, err := chain.Provider.RegistryMap(ctx, w3.A(registry)) | ||||
| 		if err != nil { | ||||
| 			return nil | ||||
| 			return nil, nil | ||||
| 		} | ||||
| 
 | ||||
| 		for _, v := range registryMap { | ||||
| @ -24,18 +28,20 @@ func bootstrapAllGESmartContracts(ctx context.Context, registries []string, chai | ||||
| 		if registryMap[celoutils.TokenIndex] != common.ZeroAddress { | ||||
| 			tokens, err := chain.GetAllTokensFromTokenIndex(ctx, registryMap[celoutils.TokenIndex]) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 				return nil, err | ||||
| 			} | ||||
| 
 | ||||
| 			for _, token := range tokens { | ||||
| 				cache.Add(token.Hex()) | ||||
| 			} | ||||
| 
 | ||||
| 			watchableIndex[registryMap[celoutils.TokenIndex].Hex()] = true | ||||
| 		} | ||||
| 
 | ||||
| 		if registryMap[celoutils.PoolIndex] != common.ZeroAddress { | ||||
| 			pools, err := chain.GetAllTokensFromTokenIndex(ctx, registryMap[celoutils.PoolIndex]) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 				return nil, err | ||||
| 			} | ||||
| 
 | ||||
| 			for _, pool := range pools { | ||||
| @ -51,21 +57,24 @@ func bootstrapAllGESmartContracts(ctx context.Context, registries []string, chai | ||||
| 					eth.CallFunc(pool, quoterGetter).Returns(&priceQuoter), | ||||
| 				) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 					return nil, err | ||||
| 				} | ||||
| 				cache.Add(priceQuoter.Hex()) | ||||
| 
 | ||||
| 				poolTokens, err := chain.GetAllTokensFromTokenIndex(ctx, poolTokenRegistry) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 					return nil, err | ||||
| 				} | ||||
| 
 | ||||
| 				for _, token := range poolTokens { | ||||
| 					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 { | ||||
| 		Purge() error | ||||
| 		Exists(string) bool | ||||
| 		Add(string) bool | ||||
| 		Add(string) | ||||
| 		Remove(string) | ||||
| 		SetWatchableIndex(WatchableIndex) | ||||
| 		ISWatchAbleIndex(string) bool | ||||
| 		Size() int | ||||
| 	} | ||||
| 
 | ||||
| @ -21,7 +24,10 @@ type ( | ||||
| 		Chain      *chain.Chain | ||||
| 		CacheType  string | ||||
| 		Registries []string | ||||
| 		Blacklist  []string | ||||
| 	} | ||||
| 
 | ||||
| 	WatchableIndex map[string]bool | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| @ -41,14 +47,21 @@ func New(o CacheOpts) (Cache, error) { | ||||
| 		cache = NewMapCache() | ||||
| 	} | ||||
| 
 | ||||
| 	if err := bootstrapAllGESmartContracts( | ||||
| 	watchableIndex, err := bootstrapAllGESmartContracts( | ||||
| 		context.Background(), | ||||
| 		o.Registries, | ||||
| 		o.Chain, | ||||
| 		cache, | ||||
| 	); err != nil { | ||||
| 	) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	cache.SetWatchableIndex(watchableIndex) | ||||
| 
 | ||||
| 	for _, address := range o.Blacklist { | ||||
| 		cache.Remove(address) | ||||
| 	} | ||||
| 
 | ||||
| 	o.Logg.Debug("cache bootstrap complete", "cached_addresses", cache.Size()) | ||||
| 
 | ||||
| 	return cache, nil | ||||
|  | ||||
							
								
								
									
										21
									
								
								internal/cache/map.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								internal/cache/map.go
									
									
									
									
										vendored
									
									
								
							| @ -8,8 +8,9 @@ import ( | ||||
| 
 | ||||
| type ( | ||||
| 	MapCache struct { | ||||
| 		mapCache *xsync.Map | ||||
| 		logg     *slog.Logger | ||||
| 		mapCache       *xsync.Map | ||||
| 		logg           *slog.Logger | ||||
| 		watchableIndex WatchableIndex | ||||
| 	} | ||||
| ) | ||||
| 
 | ||||
| @ -29,11 +30,23 @@ func (c *MapCache) Exists(key string) bool { | ||||
| 	return ok | ||||
| } | ||||
| 
 | ||||
| func (c *MapCache) Add(key string) bool { | ||||
| func (c *MapCache) Add(key string) { | ||||
| 	c.mapCache.Store(key, nil) | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| func (c *MapCache) Remove(key string) { | ||||
| 	c.mapCache.Delete(key) | ||||
| } | ||||
| 
 | ||||
| func (c *MapCache) Size() int { | ||||
| 	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