Compare commits

...

5 Commits

14 changed files with 66 additions and 265 deletions

View File

@ -1,6 +1,6 @@
FROM golang:1.23.0-bookworm AS build
FROM golang:1.23.3-bookworm AS build
ENV CGO_ENABLED=1
ENV CGO_ENABLED=0
ARG BUILDPLATFORM
ARG TARGETPLATFORM

View File

@ -1,7 +1,7 @@
BIN := eth-tracker
BOOTSTRAP_BIN := eth-tracker-cache-bootstrap
DB_FILE := tracker_db
BUILD_CONF := CGO_ENABLED=1 GOOS=linux GOARCH=amd64
BUILD_CONF := CGO_ENABLED=0 GOOS=linux GOARCH=amd64
BUILD_COMMIT := $(shell git rev-parse --short HEAD 2> /dev/null)
DEBUG := DEV=true

View File

@ -6,6 +6,9 @@ A fast and lightweight tracker designed to monitor EVM blockchains for live and
historical transaction events, including reverted transactions. It filters these
events and publishes them to NATS for further processing.
On a warmed up archive RPC node (HTTP) with the default config, it can process
in excess of 10k blocks/min utilizing not more than 50 MB of RAM.
It applies deduplication at the NATS level, making it safe to run in a
distributed fashion.
@ -36,8 +39,7 @@ The cache will auto-update based on any additions/removals from all indexes.
- Git
- Docker
- NATS server
- Redis server (Optional)
- Access to a Celo RPC node
- Access to an RPC node, archive preffered
See [docker-compose.yaml](dev/docker-compose.yaml) for an example on how to run
and deploy a single instance.
@ -55,7 +57,7 @@ docker buildx build --build-arg BUILD=$(git rev-parse --short HEAD) --tag eth-tr
docker images
```
### 2. Run NATS and Redis
### 2. Run NATS
For an example, see `dev/docker-compose.yaml`.

View File

@ -74,7 +74,7 @@ func main() {
cacheOpts := cache.CacheOpts{
Chain: chain,
Registries: []string{ko.MustString("bootstrap.ge_registry")},
Registries: ko.MustStrings("bootstrap.ge_registry"),
Watchlist: ko.Strings("bootstrap.watchlist"),
Blacklist: ko.Strings("bootstrap.blacklist"),
CacheType: ko.MustString("core.cache_type"),

View File

@ -25,7 +25,7 @@ func bootstrapEventRouter(cacheProvider cache.Cache, pubCB router.Callback) *rou
router.RegisterLogRoute(w3.H("0xab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8"), handler.HandleTokenMintLog())
router.RegisterLogRoute(w3.H("0x894e56e1dac400b4475c83d8af0f0aa44de17c62764bd82f6e768a504e242461"), handler.HandleCustodialRegistrationLog())
router.RegisterLogRoute(w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), handler.HandleTokenTransferLog(handlerContainer))
router.RegisterLogRoute(w3.H("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"), handler.HandleTokenApproveLog())
router.RegisterLogRoute(w3.H("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"), handler.HandleTokenApproveLog(handlerContainer))
router.RegisterInputDataRoute("63e4bff4", handler.HandleFaucetGiveInputData())
router.RegisterInputDataRoute("de82efb4", handler.HandleFaucetGiveInputData())
@ -42,7 +42,7 @@ func bootstrapEventRouter(cacheProvider cache.Cache, pubCB router.Callback) *rou
router.RegisterInputDataRoute("4420e486", handler.HandleCustodialRegistrationInputData())
router.RegisterInputDataRoute("a9059cbb", handler.HandleTokenTransferInputData(handlerContainer))
router.RegisterInputDataRoute("23b872dd", handler.HandleTokenTransferInputData(handlerContainer))
router.RegisterInputDataRoute("095ea7b3", handler.HandleTokenApproveInputData())
router.RegisterInputDataRoute("095ea7b3", handler.HandleTokenApproveInputData(handlerContainer))
return router
}

View File

@ -27,7 +27,7 @@ start_block = 0
[bootstrap]
# This will bootstrap the cache on which addresses to track
ge_registry = "0x0f8E97ef2d6A42CF62549D4924FCBdcE83A1C6A5"
ge_registry = ["0x0f8E97ef2d6A42CF62549D4924FCBdcE83A1C6A5"]
watchlist = [""]
blacklist = [""]

8
go.mod
View File

@ -1,8 +1,6 @@
module github.com/grassrootseconomics/eth-tracker
go 1.23.0
replace github.com/ethereum/go-ethereum => github.com/celo-org/op-geth v1.101408.1-0.20241003173630-fd593f27afa2
go 1.23.3
require (
github.com/VictoriaMetrics/metrics v1.35.1
@ -25,7 +23,6 @@ require (
)
require (
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
@ -35,7 +32,6 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240821192748-42bd03ba8313 // indirect
github.com/ethereum/c-kzg-4844 v1.0.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
@ -52,6 +48,7 @@ require (
github.com/nats-io/nuid v1.0.1 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/supranational/blst v0.3.11 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
@ -60,7 +57,6 @@ require (
github.com/valyala/histogram v1.2.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.17.0 // indirect

18
go.sum
View File

@ -1,7 +1,5 @@
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e h1:ZIWapoIRN1VqT8GR8jAwb1Ie9GyehWjVcGh32Y2MznE=
github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
@ -20,8 +18,6 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurT
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/celo-org/op-geth v1.101408.1-0.20241003173630-fd593f27afa2 h1:uNjQB6rkdWDza/dfkvBW35MAVnfXaNmE67BFr3rVR7g=
github.com/celo-org/op-geth v1.101408.1-0.20241003173630-fd593f27afa2/go.mod h1:Mk8AhvlqFbjI9oW2ymThSSoqc6kiEH0/tCmHGMEu6ac=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I=
@ -30,8 +26,8 @@ github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/e
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA=
github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU=
github.com/cockroachdb/pebble v1.1.1 h1:XnKU22oiCLy2Xn8vp1re67cXg4SAasg/WDt1NtcRFaw=
github.com/cockroachdb/pebble v1.1.1/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU=
github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
@ -54,10 +50,10 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240821192748-42bd03ba8313 h1:SVSFg8ccdRBJxOdRS1pK8oIHvMufiPAQz1gkQsEPnZc=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240821192748-42bd03ba8313/go.mod h1:XaVXL9jg8BcyOeugECgIUGa9Y3DjYJj71RHmb5qon6M=
github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA=
github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
github.com/ethereum/go-ethereum v1.14.8 h1:NgOWvXS+lauK+zFukEvi85UmmsS/OkV0N23UZ1VTIig=
github.com/ethereum/go-ethereum v1.14.8/go.mod h1:TJhyuDq0JDppAkFXgqjwpdlQApywnu/m10kFPxh8vvs=
github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 h1:KrE8I4reeVvf7C1tm8elRjj4BdscTYzz/WAbYyf/JI4=
github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0/go.mod h1:D9AJLVXSyZQXJQVk8oh1EwjISE+sJTn2duYIZC0dy3w=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
@ -217,8 +213,6 @@ golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=

View File

@ -1,121 +0,0 @@
package chain
// import (
// "context"
// "math/big"
// "net/http"
// "time"
// "github.com/ethereum/go-ethereum/common"
// "github.com/ethereum/go-ethereum/core/types"
// "github.com/ethereum/go-ethereum/rpc"
// "github.com/grassrootseconomics/ethutils"
// "github.com/lmittmann/w3"
// "github.com/lmittmann/w3/module/eth"
// "github.com/lmittmann/w3/w3types"
// )
// type (
// CeloRPCOpts struct {
// RPCEndpoint string
// ChainID int64
// }
// CeloRPC struct {
// provider *ethutils.Provider
// }
// )
// func NewRPCFetcher(o CeloRPCOpts) (Chain, error) {
// customRPCClient, err := lowTimeoutRPCClient(o.RPCEndpoint)
// if err != nil {
// return nil, err
// }
// chainProvider := ethutils.NewProvider(
// o.RPCEndpoint,
// o.ChainID,
// ethutils.WithClient(customRPCClient),
// )
// return &CeloRPC{
// provider: chainProvider,
// }, nil
// }
// func lowTimeoutRPCClient(rpcEndpoint string) (*w3.Client, error) {
// httpClient := &http.Client{
// Timeout: 10 * time.Second,
// }
// rpcClient, err := rpc.DialHTTPWithClient(
// rpcEndpoint,
// httpClient,
// )
// if err != nil {
// return nil, err
// }
// return w3.NewClient(rpcClient), nil
// }
// func (c *CeloRPC) GetBlocks(ctx context.Context, blockNumbers []uint64) ([]types.Block, error) {
// blocksCount := len(blockNumbers)
// calls := make([]w3types.RPCCaller, blocksCount)
// blocks := make([]types.Block, blocksCount)
// for i, v := range blockNumbers {
// calls[i] = eth.BlockByNumber(new(big.Int).SetUint64(v)).Returns(&blocks[i])
// }
// if err := c.provider.Client.CallCtx(ctx, calls...); err != nil {
// return nil, err
// }
// return blocks, nil
// }
// func (c *CeloRPC) GetBlock(ctx context.Context, blockNumber uint64) (*types.Block, error) {
// var block types.Block
// blockCall := eth.BlockByNumber(new(big.Int).SetUint64(blockNumber)).Returns(&block)
// if err := c.provider.Client.CallCtx(ctx, blockCall); err != nil {
// return nil, err
// }
// return &block, nil
// }
// func (c *CeloRPC) GetLatestBlock(ctx context.Context) (uint64, error) {
// var latestBlock big.Int
// latestBlockCall := eth.BlockNumber().Returns(&latestBlock)
// if err := c.provider.Client.CallCtx(ctx, latestBlockCall); err != nil {
// return 0, err
// }
// return latestBlock.Uint64(), nil
// }
// func (c *CeloRPC) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, error) {
// var transaction types.Transaction
// if err := c.provider.Client.CallCtx(ctx, eth.Tx(txHash).Returns(&transaction)); err != nil {
// return nil, err
// }
// return &transaction, nil
// }
// func (c *CeloRPC) GetReceipts(ctx context.Context, blockNumber *big.Int) (types.Receipts, error) {
// var receipts types.Receipts
// if err := c.provider.Client.CallCtx(ctx, eth.BlockReceipts(blockNumber).Returns(&receipts)); err != nil {
// return nil, err
// }
// return receipts, nil
// }
// func (c *CeloRPC) Provider() *ethutils.Provider {
// return c.provider
// }

View File

@ -1,98 +0,0 @@
package chain
// import (
// "context"
// "testing"
// "time"
// "github.com/stretchr/testify/require"
// )
// const (
// testRPCEndpoint = "https://celo.archive.grassecon.net"
// testChainID = 42220
// )
// func setupCeloRPC() (Chain, error) {
// opts := CeloRPCOpts{
// RPCEndpoint: testRPCEndpoint,
// ChainID: testChainID,
// }
// return NewRPCFetcher(opts)
// }
// func TestRPC_GetBlocks(t *testing.T) {
// rpcFetcher, err := setupCeloRPC()
// require.NoError(t, err)
// blockNumbers := []uint64{
// 19_600_000,
// 23_000_000,
// 27_000_000,
// }
// ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// defer cancel()
// blocks, err := rpcFetcher.GetBlocks(ctx, blockNumbers)
// require.NoError(t, err)
// t.Logf("blocks %+v\n", blocks)
// }
// func TestRPC_GetBlock(t *testing.T) {
// rpcFetcher, err := setupCeloRPC()
// require.NoError(t, err)
// var blockNumber uint64 = 19_900_000
// ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// defer cancel()
// block, err := rpcFetcher.GetBlock(ctx, blockNumber)
// require.NoError(t, err)
// t.Logf("block %+v\n", block)
// }
// func TestRPC_GetLatestBlock(t *testing.T) {
// rpcFetcher, err := setupCeloRPC()
// require.NoError(t, err)
// ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// defer cancel()
// block, err := rpcFetcher.GetLatestBlock(ctx)
// require.NoError(t, err)
// t.Logf("block %+v\n", block)
// }
// func TestRPC_GetTransaction(t *testing.T) {
// rpcFetcher, err := setupCeloRPC()
// require.NoError(t, err)
// var blockNumber uint64 = 19_900_000
// ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// defer cancel()
// block, err := rpcFetcher.GetBlock(ctx, blockNumber)
// require.NoError(t, err)
// require.NotNil(t, block)
// transaction, err := rpcFetcher.GetTransaction(ctx, block.Transactions()[0].Hash())
// require.NoError(t, err)
// t.Logf("transaction %+v\n", transaction)
// }
// func TestRPC_GetReceipts(t *testing.T) {
// rpcFetcher, err := setupCeloRPC()
// require.NoError(t, err)
// var blockNumber uint64 = 19_900_000
// ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// defer cancel()
// block, err := rpcFetcher.GetBlock(ctx, blockNumber)
// require.NoError(t, err)
// require.NotNil(t, block)
// receipts, err := rpcFetcher.GetReceipts(ctx, block.Number())
// require.NoError(t, err)
// t.Logf("receipts %+v\n", receipts)
// }

View File

@ -17,7 +17,7 @@ var (
tokenApproveToSig = w3.MustNewFunc("approve(address, uint256)", "bool")
)
func HandleTokenApproveLog() router.LogHandlerFunc {
func HandleTokenApproveLog(hc *HandlerContainer) router.LogHandlerFunc {
return func(ctx context.Context, lp router.LogPayload, c router.Callback) error {
var (
owner common.Address
@ -29,6 +29,14 @@ func HandleTokenApproveLog() router.LogHandlerFunc {
return err
}
proceed, err := hc.checkWithinNetwork(ctx, lp.Log.Address.Hex(), owner.Hex(), spender.Hex())
if err != nil {
return err
}
if !proceed {
return nil
}
tokenApproveEvent := event.Event{
Index: lp.Log.Index,
Block: lp.Log.BlockNumber,
@ -48,7 +56,7 @@ func HandleTokenApproveLog() router.LogHandlerFunc {
}
}
func HandleTokenApproveInputData() router.InputDataHandlerFunc {
func HandleTokenApproveInputData(hc *HandlerContainer) router.InputDataHandlerFunc {
return func(ctx context.Context, idp router.InputDataPayload, c router.Callback) error {
var (
spender common.Address
@ -59,6 +67,14 @@ func HandleTokenApproveInputData() router.InputDataHandlerFunc {
return err
}
proceed, err := hc.checkWithinNetwork(ctx, idp.ContractAddress, idp.From, spender.Hex())
if err != nil {
return err
}
if !proceed {
return nil
}
tokenApproveEvent := event.Event{
Block: idp.Block,
ContractAddress: idp.ContractAddress,

View File

@ -30,7 +30,7 @@ func HandleTokenTransferLog(hc *HandlerContainer) router.LogHandlerFunc {
return err
}
proceed, err := hc.checkTransferWithinNetwork(ctx, lp.Log.Address.Hex(), from.Hex(), to.Hex())
proceed, err := hc.checkWithinNetwork(ctx, lp.Log.Address.Hex(), from.Hex(), to.Hex())
if err != nil {
return err
}
@ -79,7 +79,7 @@ func HandleTokenTransferInputData(hc *HandlerContainer) router.InputDataHandlerF
return err
}
proceed, err := hc.checkTransferWithinNetwork(ctx, idp.ContractAddress, idp.From, to.Hex())
proceed, err := hc.checkWithinNetwork(ctx, idp.ContractAddress, idp.From, to.Hex())
if err != nil {
return err
}
@ -105,7 +105,7 @@ func HandleTokenTransferInputData(hc *HandlerContainer) router.InputDataHandlerF
return err
}
proceed, err := hc.checkTransferWithinNetwork(ctx, idp.ContractAddress, from.Hex(), to.Hex())
proceed, err := hc.checkWithinNetwork(ctx, idp.ContractAddress, from.Hex(), to.Hex())
if err != nil {
return err
}
@ -125,12 +125,3 @@ func HandleTokenTransferInputData(hc *HandlerContainer) router.InputDataHandlerF
return nil
}
}
func (hc *HandlerContainer) checkTransferWithinNetwork(ctx context.Context, contractAddress string, from string, to string) (bool, error) {
exists, err := hc.cache.ExistsNetwork(ctx, contractAddress, from, to)
if err != nil {
return false, err
}
return exists, nil
}

View File

@ -0,0 +1,12 @@
package handler
import "context"
func (hc *HandlerContainer) checkWithinNetwork(ctx context.Context, contractAddress string, from string, to string) (bool, error) {
exists, err := hc.cache.ExistsNetwork(ctx, contractAddress, from, to)
if err != nil {
return false, err
}
return exists, nil
}

View File

@ -41,13 +41,22 @@ func InitConfig(lo *slog.Logger, confFilePath string) *koanf.Koanf {
os.Exit(1)
}
if err := ko.Load(env.Provider("TRACKER_", ".", func(s string) string {
return strings.ReplaceAll(strings.ToLower(
strings.TrimPrefix(s, "TRACKER_")), "__", ".")
}), nil); err != nil {
err := ko.Load(env.ProviderWithValue("TRACKER_", ".", func(s string, v string) (string, interface{}) {
key := strings.ReplaceAll(strings.ToLower(strings.TrimPrefix(s, "TRACKER_")), "__", ".")
if strings.Contains(v, " ") {
return key, strings.Split(v, " ")
}
return key, v
}), nil)
if err != nil {
lo.Error("could not override config from env vars", "error", err)
os.Exit(1)
}
if os.Getenv("DEBUG") != "" {
ko.Print()
}
return ko
}