From 190f40e69e7e44d4cc5bdfa97084de0d61173bc4 Mon Sep 17 00:00:00 2001 From: Tangui Clairet <181825613+Tangui-Bitfly@users.noreply.github.com> Date: Tue, 1 Oct 2024 14:53:35 +0200 Subject: [PATCH 01/40] fix(internal transaction): recursively revert traces --- cache/tiered_cache.go | 16 +- db/bigtable.go | 36 +++-- db/bigtable_eth1.go | 15 +- db/bigtable_init.go | 4 +- db/db.go | 10 +- db/utils.go | 16 ++ eth1data/eth1data_test.go | 223 ++++++++++++++++++++++++++ types/config.go | 324 +++++++++++++++++++------------------- 8 files changed, 465 insertions(+), 179 deletions(-) create mode 100644 db/utils.go create mode 100644 eth1data/eth1data_test.go diff --git a/cache/tiered_cache.go b/cache/tiered_cache.go index 815fa361b0..2bec69e849 100644 --- a/cache/tiered_cache.go +++ b/cache/tiered_cache.go @@ -13,6 +13,8 @@ import ( "github.com/sirupsen/logrus" ) +var _ TieredCacher = (*tieredCache)(nil) + // Tiered cache is a cache implementation combining a type tieredCache struct { localGoCache *freecache.Cache @@ -31,7 +33,19 @@ type RemoteCache interface { GetBool(ctx context.Context, key string) (bool, error) } -var TieredCache *tieredCache +type TieredCacher interface { + Set(key string, value interface{}, expiration time.Duration) error + SetString(key string, value string, expiration time.Duration) error + SetUint64(key string, value uint64, expiration time.Duration) error + SetBool(key string, value bool, expiration time.Duration) error + + GetStringWithLocalTimeout(key string, localExpiration time.Duration) (string, error) + GetUint64WithLocalTimeout(key string, localExpiration time.Duration) (uint64, error) + GetBoolWithLocalTimeout(key string, localExpiration time.Duration) (bool, error) + GetWithLocalTimeout(key string, localExpiration time.Duration, returnValue interface{}) (interface{}, error) +} + +var TieredCache TieredCacher func MustInitTieredCache(redisAddress string) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) diff --git a/db/bigtable.go b/db/bigtable.go index 8098835f4a..2f65274245 100644 --- a/db/bigtable.go +++ b/db/bigtable.go @@ -67,7 +67,7 @@ type Bigtable struct { tableMachineMetrics *gcp_bigtable.Table - redisCache *redis.Client + redisCache RedisClient LastAttestationCache map[uint64]uint64 LastAttestationCacheMux *sync.Mutex @@ -79,10 +79,30 @@ type Bigtable struct { machineMetricsQueuedWritesChan chan (types.BulkMutation) } +type RedisClient interface { + SCard(ctx context.Context, key string) *redis.IntCmd + SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.BoolCmd + Pipeline() redis.Pipeliner + Get(ctx context.Context, key string) *redis.StringCmd + Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd +} + func InitBigtable(project, instance, chainId, redisAddress string) (*Bigtable, error) { + rdc := redis.NewClient(&redis.Options{ + Addr: redisAddress, + ReadTimeout: time.Second * 20, + }) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() + if err := rdc.Ping(ctx).Err(); err != nil { + return nil, err + } - if utils.Config.Bigtable.Emulator { + return InitBigtableWithCache(ctx, project, instance, chainId, rdc) +} +func InitBigtableWithCache(ctx context.Context, project, instance, chainId string, rdc RedisClient) (*Bigtable, error) { + if utils.Config.Bigtable.Emulator { if utils.Config.Bigtable.EmulatorHost == "" { utils.Config.Bigtable.EmulatorHost = "127.0.0.1" } @@ -93,26 +113,14 @@ func InitBigtable(project, instance, chainId, redisAddress string) (*Bigtable, e logger.Fatalf("unable to set bigtable emulator environment variable: %v", err) } } - ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) - defer cancel() poolSize := 50 btClient, err := gcp_bigtable.NewClient(ctx, project, instance, option.WithGRPCConnectionPool(poolSize)) - // btClient, err := gcp_bigtable.NewClient(context.Background(), project, instance) if err != nil { return nil, err } - rdc := redis.NewClient(&redis.Options{ - Addr: redisAddress, - ReadTimeout: time.Second * 20, - }) - - if err := rdc.Ping(ctx).Err(); err != nil { - return nil, err - } - bt := &Bigtable{ client: btClient, tableData: btClient.Open("data"), diff --git a/db/bigtable_eth1.go b/db/bigtable_eth1.go index a33906d310..45bd991ae4 100644 --- a/db/bigtable_eth1.go +++ b/db/bigtable_eth1.go @@ -11,6 +11,7 @@ import ( "log" "math/big" "sort" + "strconv" "strings" "sync" "time" @@ -24,8 +25,6 @@ import ( "github.com/gobitfly/eth2-beaconchain-explorer/types" "github.com/gobitfly/eth2-beaconchain-explorer/utils" - "strconv" - gcp_bigtable "cloud.google.com/go/bigtable" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/types/known/timestamppb" @@ -2869,7 +2868,17 @@ func (bigtable *Bigtable) GetInternalTransfersForTransaction(transaction []byte, } data := make([]types.ITransaction, 0, len(parityTrace)-1) + var revertSource []int64 for i := 1; i < len(parityTrace); i++ { + var reverted bool + if parityTrace[i].Error != "" { + reverted = true + revertSource = parityTrace[i].TraceAddress + } + if isSubset(parityTrace[i].TraceAddress, revertSource) { + reverted = true + } + from, to, value, tx_type := parityTrace[i].ConvertFields() if tx_type == "suicide" { // erigon's "suicide" might be misleading for users @@ -2896,7 +2905,7 @@ func (bigtable *Bigtable) GetInternalTransfersForTransaction(transaction []byte, From: utils.FormatAddress(from, nil, fromName, false, from_contractInteraction != types.CONTRACT_NONE, true), To: utils.FormatAddress(to, nil, toName, false, to_contractInteraction != types.CONTRACT_NONE, true), Amount: utils.FormatElCurrency(value, currency, 8, true, false, false, true), - TracePath: utils.FormatTracePath(tx_type, parityTrace[i].TraceAddress, parityTrace[i].Error == "", bigtable.GetMethodLabel(input, from_contractInteraction)), + TracePath: utils.FormatTracePath(tx_type, parityTrace[i].TraceAddress, !reverted, bigtable.GetMethodLabel(input, from_contractInteraction)), Advanced: tx_type == "delegatecall" || string(value) == "\x00", } diff --git a/db/bigtable_init.go b/db/bigtable_init.go index fa15ab03c9..3b390848fc 100644 --- a/db/bigtable_init.go +++ b/db/bigtable_init.go @@ -10,6 +10,8 @@ import ( gcp_bigtable "cloud.google.com/go/bigtable" ) +var TableAlreadyExistErr = fmt.Errorf("aborting bigtable schema init as tables are already present") + func InitBigtableSchema() error { tables := make(map[string]map[string]gcp_bigtable.GCPolicy) @@ -62,7 +64,7 @@ func InitBigtableSchema() error { } if len(existingTables) > 0 { - return fmt.Errorf("aborting bigtable schema init as tables are already present") + return TableAlreadyExistErr } for name, definition := range tables { diff --git a/db/db.go b/db/db.go index 9ca297c989..6f6216903d 100644 --- a/db/db.go +++ b/db/db.go @@ -37,9 +37,17 @@ var EmbedMigrations embed.FS var DBPGX *pgxpool.Conn +type SQLReaderDb interface { + Close() error + Get(dest interface{}, query string, args ...interface{}) error + Select(dest interface{}, query string, args ...interface{}) error + Query(query string, args ...any) (*sql.Rows, error) + Preparex(query string) (*sqlx.Stmt, error) +} + // DB is a pointer to the explorer-database var WriterDb *sqlx.DB -var ReaderDb *sqlx.DB +var ReaderDb SQLReaderDb var logger = logrus.StandardLogger().WithField("module", "db") diff --git a/db/utils.go b/db/utils.go new file mode 100644 index 0000000000..165ee09bcf --- /dev/null +++ b/db/utils.go @@ -0,0 +1,16 @@ +package db + +func isSubset[E comparable](big []E, short []E) bool { + if len(short) == 0 { + return false + } + if len(big) < len(short) { + return false + } + for i := 0; i < len(short); i++ { + if big[i] != short[i] { + return false + } + } + return true +} diff --git a/eth1data/eth1data_test.go b/eth1data/eth1data_test.go new file mode 100644 index 0000000000..45a5c47051 --- /dev/null +++ b/eth1data/eth1data_test.go @@ -0,0 +1,223 @@ +package eth1data + +import ( + "context" + "database/sql" + "errors" + "fmt" + "os" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/go-redis/redis/v8" + "github.com/jmoiron/sqlx" + "golang.org/x/exp/slices" + + "github.com/gobitfly/eth2-beaconchain-explorer/cache" + "github.com/gobitfly/eth2-beaconchain-explorer/db" + "github.com/gobitfly/eth2-beaconchain-explorer/price" + "github.com/gobitfly/eth2-beaconchain-explorer/rpc" + "github.com/gobitfly/eth2-beaconchain-explorer/types" + "github.com/gobitfly/eth2-beaconchain-explorer/utils" +) + +func TestGetEth1Transaction(t *testing.T) { + node, exists := os.LookupEnv("ERIGON_NODE") + if !exists { + t.Skip() + } + + erigon, err := rpc.NewErigonClient(node) + if err != nil { + t.Fatal(err) + } + rpc.CurrentErigonClient = erigon + + utils.Config = &types.Config{ + Chain: types.Chain{ + ClConfig: types.ClChainConfig{ + DepositChainID: 1, + }, + }, + Bigtable: types.Bigtable{ + Project: "test", + Instance: "instanceTest", + Emulator: true, + EmulatorPort: 8086, + EmulatorHost: "127.0.0.1", + }, + Frontend: types.Frontend{ + ElCurrencyDivisor: 1e18, + }, + } + cache.TieredCache = &noCache{} + db.ReaderDb = noSQLReaderDb{} + + price.Init(1, node, "ETH", "ETH") + + bt, err := db.InitBigtableWithCache(context.Background(), "test", "instanceTest", "1", noRedis{}) + if err != nil { + t.Fatal(err) + } + if err := db.InitBigtableSchema(); err != nil { + if !errors.Is(err, db.TableAlreadyExistErr) { + t.Fatal(err) + } + } + + tests := []struct { + name string + block int64 + txHash string + revertIndexes []int + }{ + { + name: "no revert", + block: 20870689, + txHash: "0x45ae8f94592cd0fb20cd6b50c8def1b5d478c1968806f129dda881d3eb7b968e", + }, + { + name: "recursive revert", + block: 20183291, + txHash: "0xf7d385f000250c073dfef9a36327c5d30a4c77a0c50588ce3eded29f6829a4cd", + revertIndexes: []int{0, 1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + block, _, err := erigon.GetBlock(tt.block, "parity/geth") + if err != nil { + t.Fatal(err) + } + + if err := bt.SaveBlock(block); err != nil { + t.Fatal(err) + } + + res, err := GetEth1Transaction(common.HexToHash(tt.txHash), "ETH") + if err != nil { + t.Fatal(err) + } + + for i, internal := range res.InternalTxns { + if !slices.Contains(tt.revertIndexes, i) { + if strings.Contains(string(internal.TracePath), "Transaction failed") { + t.Errorf("internal transaction should not be flagged as failed") + } + continue + } + if !strings.Contains(string(internal.TracePath), "Transaction failed") { + t.Errorf("internal transaction should be flagged as failed") + } + } + }) + } +} + +type noRedis struct { +} + +func (n noRedis) SCard(ctx context.Context, key string) *redis.IntCmd { + return redis.NewIntCmd(ctx) +} + +func (n noRedis) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.BoolCmd { + return redis.NewBoolCmd(ctx) +} + +func (n noRedis) Pipeline() redis.Pipeliner { + //TODO implement me + panic("implement me") +} + +func (n noRedis) Get(ctx context.Context, key string) *redis.StringCmd { + cmd := redis.NewStringCmd(ctx) + cmd.SetErr(redis.Nil) + return cmd +} + +func (n noRedis) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd { + return redis.NewStatusCmd(ctx) +} + +type noCache struct { +} + +func (n noCache) Set(key string, value interface{}, expiration time.Duration) error { + return nil +} + +func (n noCache) SetString(key string, value string, expiration time.Duration) error { + return nil + +} + +func (n noCache) SetUint64(key string, value uint64, expiration time.Duration) error { + return nil + +} + +func (n noCache) SetBool(key string, value bool, expiration time.Duration) error { + return nil + +} + +func (n noCache) Get(ctx context.Context, key string, returnValue any) (any, error) { + return nil, fmt.Errorf("no cache") +} + +func (n noCache) GetString(ctx context.Context, key string) (string, error) { + return "", fmt.Errorf("no cache") +} + +func (n noCache) GetUint64(ctx context.Context, key string) (uint64, error) { + return 0, fmt.Errorf("no cache") +} + +func (n noCache) GetBool(ctx context.Context, key string) (bool, error) { + return false, fmt.Errorf("no cache") +} + +func (n noCache) GetStringWithLocalTimeout(key string, localExpiration time.Duration) (string, error) { + return "", fmt.Errorf("no cache") +} + +func (n noCache) GetUint64WithLocalTimeout(key string, localExpiration time.Duration) (uint64, error) { + return 0, fmt.Errorf("no cache") +} + +func (n noCache) GetBoolWithLocalTimeout(key string, localExpiration time.Duration) (bool, error) { + return false, fmt.Errorf("no cache") +} + +func (n noCache) GetWithLocalTimeout(key string, localExpiration time.Duration, returnValue interface{}) (interface{}, error) { + return nil, fmt.Errorf("no cache") +} + +type noSQLReaderDb struct { +} + +func (n noSQLReaderDb) Close() error { + //TODO implement me + panic("implement me") +} + +func (n noSQLReaderDb) Get(dest interface{}, query string, args ...interface{}) error { + return nil +} + +func (n noSQLReaderDb) Select(dest interface{}, query string, args ...interface{}) error { + return nil +} + +func (n noSQLReaderDb) Query(query string, args ...any) (*sql.Rows, error) { + //TODO implement me + panic("implement me") +} + +func (n noSQLReaderDb) Preparex(query string) (*sqlx.Stmt, error) { + //TODO implement me + panic("implement me") +} diff --git a/types/config.go b/types/config.go index 3ebef26a61..a59b160d45 100644 --- a/types/config.go +++ b/types/config.go @@ -29,14 +29,7 @@ type Config struct { MaxIdleConns int `yaml:"maxIdleConns" envconfig:"WRITER_DB_MAX_IDLE_CONNS"` SSL bool `yaml:"ssl" envconfig:"WRITER_DB_SSL"` } `yaml:"writerDatabase"` - Bigtable struct { - Project string `yaml:"project" envconfig:"BIGTABLE_PROJECT"` - Instance string `yaml:"instance" envconfig:"BIGTABLE_INSTANCE"` - Emulator bool `yaml:"emulator" envconfig:"BIGTABLE_EMULATOR"` - EmulatorPort int `yaml:"emulatorPort" envconfig:"BIGTABLE_EMULATOR_PORT"` - EmulatorHost string `yaml:"emulatorHost" envconfig:"BIGTABLE_EMULATOR_HOST"` - V2SchemaCutOffEpoch uint64 `yaml:"v2SchemaCutOffEpoch" envconfig:"BIGTABLE_V2_SCHEMA_CUTT_OFF_EPOCH"` - } `yaml:"bigtable"` + Bigtable `yaml:"bigtable"` BlobIndexer struct { S3 struct { Endpoint string `yaml:"endpoint" envconfig:"BLOB_INDEXER_S3_ENDPOINT"` @@ -45,18 +38,7 @@ type Config struct { AccessKeySecret string `yaml:"accessKeySecret" envconfig:"BLOB_INDEXER_S3_ACCESS_KEY_SECRET"` } `yaml:"s3"` } `yaml:"blobIndexer"` - Chain struct { - Name string `yaml:"name" envconfig:"CHAIN_NAME"` - Id uint64 `yaml:"id" envconfig:"CHAIN_ID"` - GenesisTimestamp uint64 `yaml:"genesisTimestamp" envconfig:"CHAIN_GENESIS_TIMESTAMP"` - GenesisValidatorsRoot string `yaml:"genesisValidatorsRoot" envconfig:"CHAIN_GENESIS_VALIDATORS_ROOT"` - DomainBLSToExecutionChange string `yaml:"domainBLSToExecutionChange" envconfig:"CHAIN_DOMAIN_BLS_TO_EXECUTION_CHANGE"` - DomainVoluntaryExit string `yaml:"domainVoluntaryExit" envconfig:"CHAIN_DOMAIN_VOLUNTARY_EXIT"` - ClConfigPath string `yaml:"clConfigPath" envconfig:"CHAIN_CL_CONFIG_PATH"` - ElConfigPath string `yaml:"elConfigPath" envconfig:"CHAIN_EL_CONFIG_PATH"` - ClConfig ClChainConfig - ElConfig *params.ChainConfig - } `yaml:"chain"` + Chain `yaml:"chain"` Eth1ErigonEndpoint string `yaml:"eth1ErigonEndpoint" envconfig:"ETH1_ERIGON_ENDPOINT"` Eth1GethEndpoint string `yaml:"eth1GethEndpoint" envconfig:"ETH1_GETH_ENDPOINT"` EtherscanAPIKey string `yaml:"etherscanApiKey" envconfig:"ETHERSCAN_API_KEY"` @@ -81,145 +63,8 @@ type Config struct { ValidRegistrarContracts []string `yaml:"validRegistrarContracts" envconfig:"ENS_VALID_REGISTRAR_CONTRACTS"` } `yaml:"ensTransformer"` } `yaml:"indexer"` - Frontend struct { - Debug bool `yaml:"debug" envconfig:"FRONTEND_DEBUG"` - BeaconchainETHPoolBridgeSecret string `yaml:"beaconchainETHPoolBridgeSecret" envconfig:"FRONTEND_BEACONCHAIN_ETHPOOL_BRIDGE_SECRET"` - Kong string `yaml:"kong" envconfig:"FRONTEND_KONG"` - OnlyAPI bool `yaml:"onlyAPI" envconfig:"FRONTEND_ONLY_API"` - CsrfAuthKey string `yaml:"csrfAuthKey" envconfig:"FRONTEND_CSRF_AUTHKEY"` - CsrfInsecure bool `yaml:"csrfInsecure" envconfig:"FRONTEND_CSRF_INSECURE"` - DisableCharts bool `yaml:"disableCharts" envconfig:"disableCharts"` - RecaptchaSiteKey string `yaml:"recaptchaSiteKey" envconfig:"FRONTEND_RECAPTCHA_SITEKEY"` - RecaptchaSecretKey string `yaml:"recaptchaSecretKey" envconfig:"FRONTEND_RECAPTCHA_SECRETKEY"` - Enabled bool `yaml:"enabled" envconfig:"FRONTEND_ENABLED"` - BlobProviderUrl string `yaml:"blobProviderUrl" envconfig:"FRONTEND_BLOB_PROVIDER_URL"` - SiteBrand string `yaml:"siteBrand" envconfig:"FRONTEND_SITE_BRAND"` - Keywords string `yaml:"keywords" envconfig:"FRONTEND_KEYWORDS"` - // Imprint is deprdecated place imprint file into the legal directory - Imprint string `yaml:"imprint" envconfig:"FRONTEND_IMPRINT"` - Legal struct { - TermsOfServiceUrl string `yaml:"termsOfServiceUrl" envconfig:"FRONTEND_LEGAL_TERMS_OF_SERVICE_URL"` - PrivacyPolicyUrl string `yaml:"privacyPolicyUrl" envconfig:"FRONTEND_LEGAL_PRIVACY_POLICY_URL"` - ImprintTemplate string `yaml:"imprintTemplate" envconfig:"FRONTEND_LEGAL_IMPRINT_TEMPLATE"` - } `yaml:"legal"` - SiteDomain string `yaml:"siteDomain" envconfig:"FRONTEND_SITE_DOMAIN"` - SiteName string `yaml:"siteName" envconfig:"FRONTEND_SITE_NAME"` - SiteTitle string `yaml:"siteTitle" envconfig:"FRONTEND_SITE_TITLE"` - SiteSubtitle string `yaml:"siteSubtitle" envconfig:"FRONTEND_SITE_SUBTITLE"` - Server struct { - Port string `yaml:"port" envconfig:"FRONTEND_SERVER_PORT"` - Host string `yaml:"host" envconfig:"FRONTEND_SERVER_HOST"` - } `yaml:"server"` - ReaderDatabase struct { - Username string `yaml:"user" envconfig:"FRONTEND_READER_DB_USERNAME"` - Password string `yaml:"password" envconfig:"FRONTEND_READER_DB_PASSWORD"` - Name string `yaml:"name" envconfig:"FRONTEND_READER_DB_NAME"` - Host string `yaml:"host" envconfig:"FRONTEND_READER_DB_HOST"` - Port string `yaml:"port" envconfig:"FRONTEND_READER_DB_PORT"` - MaxOpenConns int `yaml:"maxOpenConns" envconfig:"FRONTEND_READER_DB_MAX_OPEN_CONNS"` - MaxIdleConns int `yaml:"maxIdleConns" envconfig:"FRONTEND_READER_DB_MAX_IDLE_CONNS"` - SSL bool `yaml:"ssl" envconfig:"FRONTEND_READER_DB_SSL"` - } `yaml:"readerDatabase"` - WriterDatabase struct { - Username string `yaml:"user" envconfig:"FRONTEND_WRITER_DB_USERNAME"` - Password string `yaml:"password" envconfig:"FRONTEND_WRITER_DB_PASSWORD"` - Name string `yaml:"name" envconfig:"FRONTEND_WRITER_DB_NAME"` - Host string `yaml:"host" envconfig:"FRONTEND_WRITER_DB_HOST"` - Port string `yaml:"port" envconfig:"FRONTEND_WRITER_DB_PORT"` - MaxOpenConns int `yaml:"maxOpenConns" envconfig:"FRONTEND_WRITER_DB_MAX_OPEN_CONNS"` - MaxIdleConns int `yaml:"maxIdleConns" envconfig:"FRONTEND_WRITER_DB_MAX_IDLE_CONNS"` - SSL bool `yaml:"ssl" envconfig:"FRONTEND_WRITER_DB_SSL"` - } `yaml:"writerDatabase"` - OldProductsDeadlineUnix int64 `yaml:"oldProductsDeadline" envconfig:"FRONTEND_OLD_PRODUCTS_DEADLINE_UNIX"` - Stripe struct { - Webhook string `yaml:"webhook" envconfig:"FRONTEND_STRIPE_WEBHOOK"` - SecretKey string `yaml:"secretKey" envconfig:"FRONTEND_STRIPE_SECRET_KEY"` - PublicKey string `yaml:"publicKey" envconfig:"FRONTEND_STRIPE_PUBLIC_KEY"` - - Sapphire string `yaml:"sapphire" envconfig:"FRONTEND_STRIPE_SAPPHIRE"` - Emerald string `yaml:"emerald" envconfig:"FRONTEND_STRIPE_EMERALD"` - Diamond string `yaml:"diamond" envconfig:"FRONTEND_STRIPE_DIAMOND"` - Whale string `yaml:"whale" envconfig:"FRONTEND_STRIPE_WHALE"` - Goldfish string `yaml:"goldfish" envconfig:"FRONTEND_STRIPE_GOLDFISH"` - Plankton string `yaml:"plankton" envconfig:"FRONTEND_STRIPE_PLANKTON"` - - Iron string `yaml:"iron" envconfig:"FRONTEND_STRIPE_IRON"` - IronYearly string `yaml:"ironYearly" envconfig:"FRONTEND_STRIPE_IRON_YEARLY"` - Silver string `yaml:"silver" envconfig:"FRONTEND_STRIPE_SILVER"` - SilverYearly string `yaml:"silverYearly" envconfig:"FRONTEND_STRIPE_SILVER_YEARLY"` - Gold string `yaml:"gold" envconfig:"FRONTEND_STRIPE_GOLD"` - GoldYearly string `yaml:"goldYearly" envconfig:"FRONTEND_STRIPE_GOLD_YEARLY"` - - Guppy string `yaml:"guppy" envconfig:"FRONTEND_STRIPE_GUPPY"` - GuppyYearly string `yaml:"guppyYearly" envconfig:"FRONTEND_STRIPE_GUPPY_YEARLY"` - Dolphin string `yaml:"dolphin" envconfig:"FRONTEND_STRIPE_DOLPHIN"` - DolphinYearly string `yaml:"dolphinYearly" envconfig:"FRONTEND_STRIPE_DOLPHIN_YEARLY"` - Orca string `yaml:"orca" envconfig:"FRONTEND_STRIPE_ORCA"` - OrcaYearly string `yaml:"orcaYearly" envconfig:"FRONTEND_STRIPE_ORCA_YEARLY"` - - VdbAddon1k string `yaml:"vdbAddon1k" envconfig:"FRONTEND_STRIPE_VDB_ADDON_1K"` - VdbAddon1kYearly string `yaml:"vdbAddon1kYearly" envconfig:"FRONTEND_STRIPE_VDB_ADDON_1K_YEARLY"` - VdbAddon10k string `yaml:"vdbAddon10k" envconfig:"FRONTEND_STRIPE_VDB_ADDON_10K"` - VdbAddon10kYearly string `yaml:"vdbAddon10kYearly" envconfig:"FRONTEND_STRIPE_VDB_ADDON_10K_YEARLY"` - } - RatelimitUpdateInterval time.Duration `yaml:"ratelimitUpdateInterval" envconfig:"FRONTEND_RATELIMIT_UPDATE_INTERVAL"` - SessionSameSiteNone bool `yaml:"sessionSameSiteNone" envconfig:"FRONTEND_SESSION_SAMESITE_NONE"` - SessionSecret string `yaml:"sessionSecret" envconfig:"FRONTEND_SESSION_SECRET"` - SessionCookieDomain string `yaml:"sessionCookieDomain" envconfig:"FRONTEND_SESSION_COOKIE_DOMAIN"` - SessionCookieDeriveDomainFromRequest bool `yaml:"sessionCookieDeriveDomainFromRequest" envconfig:"FRONTEND_SESSION_COOKIE_DERIVE_DOMAIN_FROM_REQUEST"` - JwtSigningSecret string `yaml:"jwtSigningSecret" envconfig:"FRONTEND_JWT_SECRET"` - JwtIssuer string `yaml:"jwtIssuer" envconfig:"FRONTEND_JWT_ISSUER"` - JwtValidityInMinutes int `yaml:"jwtValidityInMinutes" envconfig:"FRONTEND_JWT_VALIDITY_INMINUTES"` - MaxMailsPerEmailPerDay int `yaml:"maxMailsPerEmailPerDay" envconfig:"FRONTEND_MAX_MAIL_PER_EMAIL_PER_DAY"` - Mail struct { - SMTP struct { - Server string `yaml:"server" envconfig:"FRONTEND_MAIL_SMTP_SERVER"` - Host string `yaml:"host" envconfig:"FRONTEND_MAIL_SMTP_HOST"` - User string `yaml:"user" envconfig:"FRONTEND_MAIL_SMTP_USER"` - Password string `yaml:"password" envconfig:"FRONTEND_MAIL_SMTP_PASSWORD"` - } `yaml:"smtp"` - Mailgun struct { - Domain string `yaml:"domain" envconfig:"FRONTEND_MAIL_MAILGUN_DOMAIN"` - PrivateKey string `yaml:"privateKey" envconfig:"FRONTEND_MAIL_MAILGUN_PRIVATE_KEY"` - Sender string `yaml:"sender" envconfig:"FRONTEND_MAIL_MAILGUN_SENDER"` - } `yaml:"mailgun"` - Contact struct { - SupportEmail string `yaml:"supportEmail" envconfig:"FRONTEND_MAIL_CONTACT_SUPPORT_EMAIL"` - InquiryEmail string `yaml:"inquiryEmail" envconfig:"FRONTEND_MAIL_CONTACT_INQUIRY_EMAIL"` - } `yaml:"contact"` - } `yaml:"mail"` - GATag string `yaml:"gatag" envconfig:"GATAG"` - VerifyAppSubs bool `yaml:"verifyAppSubscriptions" envconfig:"FRONTEND_VERIFY_APP_SUBSCRIPTIONS"` - Apple struct { - LegacyAppSubsAppleSecret string `yaml:"appSubsAppleSecret" envconfig:"FRONTEND_APP_SUBS_APPLE_SECRET"` - KeyID string `yaml:"keyID" envconfig:"FRONTEND_APPLE_APP_KEY_ID"` - IssueID string `yaml:"issueID" envconfig:"FRONTEND_APPLE_ISSUE_ID"` - Certificate string `yaml:"certificate" envconfig:"FRONTEND_APPLE_CERTIFICATE"` - } `yaml:"apple"` - AppSubsGoogleJSONPath string `yaml:"appSubsGoogleJsonPath" envconfig:"FRONTEND_APP_SUBS_GOOGLE_JSON_PATH"` - DisableStatsInserts bool `yaml:"disableStatsInserts" envconfig:"FRONTEND_DISABLE_STATS_INSERTS"` - ShowDonors struct { - Enabled bool `yaml:"enabled" envconfig:"FRONTEND_SHOW_DONORS_ENABLED"` - URL string `yaml:"gitcoinURL" envconfig:"FRONTEND_GITCOIN_URL"` - } `yaml:"showDonors"` - Countdown struct { - Enabled bool `yaml:"enabled" envconfig:"FRONTEND_COUNTDOWN_ENABLED"` - Title template.HTML `yaml:"title" envconfig:"FRONTEND_COUNTDOWN_TITLE"` - Timestamp uint64 `yaml:"timestamp" envconfig:"FRONTEND_COUNTDOWN_TIMESTAMP"` - Info string `yaml:"info" envconfig:"FRONTEND_COUNTDOWN_INFO"` - } `yaml:"countdown"` - HttpReadTimeout time.Duration `yaml:"httpReadTimeout" envconfig:"FRONTEND_HTTP_READ_TIMEOUT"` - HttpWriteTimeout time.Duration `yaml:"httpWriteTimeout" envconfig:"FRONTEND_HTTP_WRITE_TIMEOUT"` - HttpIdleTimeout time.Duration `yaml:"httpIdleTimeout" envconfig:"FRONTEND_HTTP_IDLE_TIMEOUT"` - ClCurrency string `yaml:"clCurrency" envconfig:"FRONTEND_CL_CURRENCY"` - ClCurrencyDivisor int64 `yaml:"clCurrencyDivisor" envconfig:"FRONTEND_CL_CURRENCY_DIVISOR"` - ClCurrencyDecimals int64 `yaml:"clCurrencyDecimals" envconfig:"FRONTEND_CL_CURRENCY_DECIMALS"` - ElCurrency string `yaml:"elCurrency" envconfig:"FRONTEND_EL_CURRENCY"` - ElCurrencyDivisor int64 `yaml:"elCurrencyDivisor" envconfig:"FRONTEND_EL_CURRENCY_DIVISOR"` - ElCurrencyDecimals int64 `yaml:"elCurrencyDecimals" envconfig:"FRONTEND_EL_CURRENCY_DECIMALS"` - MainCurrency string `yaml:"mainCurrency" envconfig:"FRONTEND_MAIN_CURRENCY"` - } `yaml:"frontend"` - Metrics struct { + Frontend `yaml:"frontend"` + Metrics struct { Enabled bool `yaml:"enabled" envconfig:"METRICS_ENABLED"` Address string `yaml:"address" envconfig:"METRICS_ADDRESS"` Pprof bool `yaml:"pprof" envconfig:"METRICS_PPROF"` @@ -264,6 +109,167 @@ type Config struct { GithubApiHost string `yaml:"githubApiHost" envconfig:"GITHUB_API_HOST"` } +type Chain struct { + Name string `yaml:"name" envconfig:"CHAIN_NAME"` + Id uint64 `yaml:"id" envconfig:"CHAIN_ID"` + GenesisTimestamp uint64 `yaml:"genesisTimestamp" envconfig:"CHAIN_GENESIS_TIMESTAMP"` + GenesisValidatorsRoot string `yaml:"genesisValidatorsRoot" envconfig:"CHAIN_GENESIS_VALIDATORS_ROOT"` + DomainBLSToExecutionChange string `yaml:"domainBLSToExecutionChange" envconfig:"CHAIN_DOMAIN_BLS_TO_EXECUTION_CHANGE"` + DomainVoluntaryExit string `yaml:"domainVoluntaryExit" envconfig:"CHAIN_DOMAIN_VOLUNTARY_EXIT"` + ClConfigPath string `yaml:"clConfigPath" envconfig:"CHAIN_CL_CONFIG_PATH"` + ElConfigPath string `yaml:"elConfigPath" envconfig:"CHAIN_EL_CONFIG_PATH"` + ClConfig ClChainConfig + ElConfig *params.ChainConfig +} + +type Bigtable struct { + Project string `yaml:"project" envconfig:"BIGTABLE_PROJECT"` + Instance string `yaml:"instance" envconfig:"BIGTABLE_INSTANCE"` + Emulator bool `yaml:"emulator" envconfig:"BIGTABLE_EMULATOR"` + EmulatorPort int `yaml:"emulatorPort" envconfig:"BIGTABLE_EMULATOR_PORT"` + EmulatorHost string `yaml:"emulatorHost" envconfig:"BIGTABLE_EMULATOR_HOST"` + V2SchemaCutOffEpoch uint64 `yaml:"v2SchemaCutOffEpoch" envconfig:"BIGTABLE_V2_SCHEMA_CUTT_OFF_EPOCH"` +} + +type Frontend struct { + Debug bool `yaml:"debug" envconfig:"FRONTEND_DEBUG"` + BeaconchainETHPoolBridgeSecret string `yaml:"beaconchainETHPoolBridgeSecret" envconfig:"FRONTEND_BEACONCHAIN_ETHPOOL_BRIDGE_SECRET"` + Kong string `yaml:"kong" envconfig:"FRONTEND_KONG"` + OnlyAPI bool `yaml:"onlyAPI" envconfig:"FRONTEND_ONLY_API"` + CsrfAuthKey string `yaml:"csrfAuthKey" envconfig:"FRONTEND_CSRF_AUTHKEY"` + CsrfInsecure bool `yaml:"csrfInsecure" envconfig:"FRONTEND_CSRF_INSECURE"` + DisableCharts bool `yaml:"disableCharts" envconfig:"disableCharts"` + RecaptchaSiteKey string `yaml:"recaptchaSiteKey" envconfig:"FRONTEND_RECAPTCHA_SITEKEY"` + RecaptchaSecretKey string `yaml:"recaptchaSecretKey" envconfig:"FRONTEND_RECAPTCHA_SECRETKEY"` + Enabled bool `yaml:"enabled" envconfig:"FRONTEND_ENABLED"` + BlobProviderUrl string `yaml:"blobProviderUrl" envconfig:"FRONTEND_BLOB_PROVIDER_URL"` + SiteBrand string `yaml:"siteBrand" envconfig:"FRONTEND_SITE_BRAND"` + Keywords string `yaml:"keywords" envconfig:"FRONTEND_KEYWORDS"` + // Imprint is deprdecated place imprint file into the legal directory + Imprint string `yaml:"imprint" envconfig:"FRONTEND_IMPRINT"` + Legal struct { + TermsOfServiceUrl string `yaml:"termsOfServiceUrl" envconfig:"FRONTEND_LEGAL_TERMS_OF_SERVICE_URL"` + PrivacyPolicyUrl string `yaml:"privacyPolicyUrl" envconfig:"FRONTEND_LEGAL_PRIVACY_POLICY_URL"` + ImprintTemplate string `yaml:"imprintTemplate" envconfig:"FRONTEND_LEGAL_IMPRINT_TEMPLATE"` + } `yaml:"legal"` + SiteDomain string `yaml:"siteDomain" envconfig:"FRONTEND_SITE_DOMAIN"` + SiteName string `yaml:"siteName" envconfig:"FRONTEND_SITE_NAME"` + SiteTitle string `yaml:"siteTitle" envconfig:"FRONTEND_SITE_TITLE"` + SiteSubtitle string `yaml:"siteSubtitle" envconfig:"FRONTEND_SITE_SUBTITLE"` + Server struct { + Port string `yaml:"port" envconfig:"FRONTEND_SERVER_PORT"` + Host string `yaml:"host" envconfig:"FRONTEND_SERVER_HOST"` + } `yaml:"server"` + ReaderDatabase struct { + Username string `yaml:"user" envconfig:"FRONTEND_READER_DB_USERNAME"` + Password string `yaml:"password" envconfig:"FRONTEND_READER_DB_PASSWORD"` + Name string `yaml:"name" envconfig:"FRONTEND_READER_DB_NAME"` + Host string `yaml:"host" envconfig:"FRONTEND_READER_DB_HOST"` + Port string `yaml:"port" envconfig:"FRONTEND_READER_DB_PORT"` + MaxOpenConns int `yaml:"maxOpenConns" envconfig:"FRONTEND_READER_DB_MAX_OPEN_CONNS"` + MaxIdleConns int `yaml:"maxIdleConns" envconfig:"FRONTEND_READER_DB_MAX_IDLE_CONNS"` + SSL bool `yaml:"ssl" envconfig:"FRONTEND_READER_DB_SSL"` + } `yaml:"readerDatabase"` + WriterDatabase struct { + Username string `yaml:"user" envconfig:"FRONTEND_WRITER_DB_USERNAME"` + Password string `yaml:"password" envconfig:"FRONTEND_WRITER_DB_PASSWORD"` + Name string `yaml:"name" envconfig:"FRONTEND_WRITER_DB_NAME"` + Host string `yaml:"host" envconfig:"FRONTEND_WRITER_DB_HOST"` + Port string `yaml:"port" envconfig:"FRONTEND_WRITER_DB_PORT"` + MaxOpenConns int `yaml:"maxOpenConns" envconfig:"FRONTEND_WRITER_DB_MAX_OPEN_CONNS"` + MaxIdleConns int `yaml:"maxIdleConns" envconfig:"FRONTEND_WRITER_DB_MAX_IDLE_CONNS"` + SSL bool `yaml:"ssl" envconfig:"FRONTEND_WRITER_DB_SSL"` + } `yaml:"writerDatabase"` + OldProductsDeadlineUnix int64 `yaml:"oldProductsDeadline" envconfig:"FRONTEND_OLD_PRODUCTS_DEADLINE_UNIX"` + Stripe struct { + Webhook string `yaml:"webhook" envconfig:"FRONTEND_STRIPE_WEBHOOK"` + SecretKey string `yaml:"secretKey" envconfig:"FRONTEND_STRIPE_SECRET_KEY"` + PublicKey string `yaml:"publicKey" envconfig:"FRONTEND_STRIPE_PUBLIC_KEY"` + + Sapphire string `yaml:"sapphire" envconfig:"FRONTEND_STRIPE_SAPPHIRE"` + Emerald string `yaml:"emerald" envconfig:"FRONTEND_STRIPE_EMERALD"` + Diamond string `yaml:"diamond" envconfig:"FRONTEND_STRIPE_DIAMOND"` + Whale string `yaml:"whale" envconfig:"FRONTEND_STRIPE_WHALE"` + Goldfish string `yaml:"goldfish" envconfig:"FRONTEND_STRIPE_GOLDFISH"` + Plankton string `yaml:"plankton" envconfig:"FRONTEND_STRIPE_PLANKTON"` + + Iron string `yaml:"iron" envconfig:"FRONTEND_STRIPE_IRON"` + IronYearly string `yaml:"ironYearly" envconfig:"FRONTEND_STRIPE_IRON_YEARLY"` + Silver string `yaml:"silver" envconfig:"FRONTEND_STRIPE_SILVER"` + SilverYearly string `yaml:"silverYearly" envconfig:"FRONTEND_STRIPE_SILVER_YEARLY"` + Gold string `yaml:"gold" envconfig:"FRONTEND_STRIPE_GOLD"` + GoldYearly string `yaml:"goldYearly" envconfig:"FRONTEND_STRIPE_GOLD_YEARLY"` + + Guppy string `yaml:"guppy" envconfig:"FRONTEND_STRIPE_GUPPY"` + GuppyYearly string `yaml:"guppyYearly" envconfig:"FRONTEND_STRIPE_GUPPY_YEARLY"` + Dolphin string `yaml:"dolphin" envconfig:"FRONTEND_STRIPE_DOLPHIN"` + DolphinYearly string `yaml:"dolphinYearly" envconfig:"FRONTEND_STRIPE_DOLPHIN_YEARLY"` + Orca string `yaml:"orca" envconfig:"FRONTEND_STRIPE_ORCA"` + OrcaYearly string `yaml:"orcaYearly" envconfig:"FRONTEND_STRIPE_ORCA_YEARLY"` + + VdbAddon1k string `yaml:"vdbAddon1k" envconfig:"FRONTEND_STRIPE_VDB_ADDON_1K"` + VdbAddon1kYearly string `yaml:"vdbAddon1kYearly" envconfig:"FRONTEND_STRIPE_VDB_ADDON_1K_YEARLY"` + VdbAddon10k string `yaml:"vdbAddon10k" envconfig:"FRONTEND_STRIPE_VDB_ADDON_10K"` + VdbAddon10kYearly string `yaml:"vdbAddon10kYearly" envconfig:"FRONTEND_STRIPE_VDB_ADDON_10K_YEARLY"` + } + RatelimitUpdateInterval time.Duration `yaml:"ratelimitUpdateInterval" envconfig:"FRONTEND_RATELIMIT_UPDATE_INTERVAL"` + SessionSameSiteNone bool `yaml:"sessionSameSiteNone" envconfig:"FRONTEND_SESSION_SAMESITE_NONE"` + SessionSecret string `yaml:"sessionSecret" envconfig:"FRONTEND_SESSION_SECRET"` + SessionCookieDomain string `yaml:"sessionCookieDomain" envconfig:"FRONTEND_SESSION_COOKIE_DOMAIN"` + SessionCookieDeriveDomainFromRequest bool `yaml:"sessionCookieDeriveDomainFromRequest" envconfig:"FRONTEND_SESSION_COOKIE_DERIVE_DOMAIN_FROM_REQUEST"` + JwtSigningSecret string `yaml:"jwtSigningSecret" envconfig:"FRONTEND_JWT_SECRET"` + JwtIssuer string `yaml:"jwtIssuer" envconfig:"FRONTEND_JWT_ISSUER"` + JwtValidityInMinutes int `yaml:"jwtValidityInMinutes" envconfig:"FRONTEND_JWT_VALIDITY_INMINUTES"` + MaxMailsPerEmailPerDay int `yaml:"maxMailsPerEmailPerDay" envconfig:"FRONTEND_MAX_MAIL_PER_EMAIL_PER_DAY"` + Mail struct { + SMTP struct { + Server string `yaml:"server" envconfig:"FRONTEND_MAIL_SMTP_SERVER"` + Host string `yaml:"host" envconfig:"FRONTEND_MAIL_SMTP_HOST"` + User string `yaml:"user" envconfig:"FRONTEND_MAIL_SMTP_USER"` + Password string `yaml:"password" envconfig:"FRONTEND_MAIL_SMTP_PASSWORD"` + } `yaml:"smtp"` + Mailgun struct { + Domain string `yaml:"domain" envconfig:"FRONTEND_MAIL_MAILGUN_DOMAIN"` + PrivateKey string `yaml:"privateKey" envconfig:"FRONTEND_MAIL_MAILGUN_PRIVATE_KEY"` + Sender string `yaml:"sender" envconfig:"FRONTEND_MAIL_MAILGUN_SENDER"` + } `yaml:"mailgun"` + Contact struct { + SupportEmail string `yaml:"supportEmail" envconfig:"FRONTEND_MAIL_CONTACT_SUPPORT_EMAIL"` + InquiryEmail string `yaml:"inquiryEmail" envconfig:"FRONTEND_MAIL_CONTACT_INQUIRY_EMAIL"` + } `yaml:"contact"` + } `yaml:"mail"` + GATag string `yaml:"gatag" envconfig:"GATAG"` + VerifyAppSubs bool `yaml:"verifyAppSubscriptions" envconfig:"FRONTEND_VERIFY_APP_SUBSCRIPTIONS"` + Apple struct { + LegacyAppSubsAppleSecret string `yaml:"appSubsAppleSecret" envconfig:"FRONTEND_APP_SUBS_APPLE_SECRET"` + KeyID string `yaml:"keyID" envconfig:"FRONTEND_APPLE_APP_KEY_ID"` + IssueID string `yaml:"issueID" envconfig:"FRONTEND_APPLE_ISSUE_ID"` + Certificate string `yaml:"certificate" envconfig:"FRONTEND_APPLE_CERTIFICATE"` + } `yaml:"apple"` + AppSubsGoogleJSONPath string `yaml:"appSubsGoogleJsonPath" envconfig:"FRONTEND_APP_SUBS_GOOGLE_JSON_PATH"` + DisableStatsInserts bool `yaml:"disableStatsInserts" envconfig:"FRONTEND_DISABLE_STATS_INSERTS"` + ShowDonors struct { + Enabled bool `yaml:"enabled" envconfig:"FRONTEND_SHOW_DONORS_ENABLED"` + URL string `yaml:"gitcoinURL" envconfig:"FRONTEND_GITCOIN_URL"` + } `yaml:"showDonors"` + Countdown struct { + Enabled bool `yaml:"enabled" envconfig:"FRONTEND_COUNTDOWN_ENABLED"` + Title template.HTML `yaml:"title" envconfig:"FRONTEND_COUNTDOWN_TITLE"` + Timestamp uint64 `yaml:"timestamp" envconfig:"FRONTEND_COUNTDOWN_TIMESTAMP"` + Info string `yaml:"info" envconfig:"FRONTEND_COUNTDOWN_INFO"` + } `yaml:"countdown"` + HttpReadTimeout time.Duration `yaml:"httpReadTimeout" envconfig:"FRONTEND_HTTP_READ_TIMEOUT"` + HttpWriteTimeout time.Duration `yaml:"httpWriteTimeout" envconfig:"FRONTEND_HTTP_WRITE_TIMEOUT"` + HttpIdleTimeout time.Duration `yaml:"httpIdleTimeout" envconfig:"FRONTEND_HTTP_IDLE_TIMEOUT"` + ClCurrency string `yaml:"clCurrency" envconfig:"FRONTEND_CL_CURRENCY"` + ClCurrencyDivisor int64 `yaml:"clCurrencyDivisor" envconfig:"FRONTEND_CL_CURRENCY_DIVISOR"` + ClCurrencyDecimals int64 `yaml:"clCurrencyDecimals" envconfig:"FRONTEND_CL_CURRENCY_DECIMALS"` + ElCurrency string `yaml:"elCurrency" envconfig:"FRONTEND_EL_CURRENCY"` + ElCurrencyDivisor int64 `yaml:"elCurrencyDivisor" envconfig:"FRONTEND_EL_CURRENCY_DIVISOR"` + ElCurrencyDecimals int64 `yaml:"elCurrencyDecimals" envconfig:"FRONTEND_EL_CURRENCY_DECIMALS"` + MainCurrency string `yaml:"mainCurrency" envconfig:"FRONTEND_MAIN_CURRENCY"` +} + type DatabaseConfig struct { Username string Password string From 43144fb636640a57fa8b5f140a6c9e1e308c39f4 Mon Sep 17 00:00:00 2001 From: Tangui Clairet <181825613+Tangui-Bitfly@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:04:09 +0200 Subject: [PATCH 02/40] fix: SQLReaderDb interface missing methods --- db/db.go | 3 +++ eth1data/eth1data_test.go | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/db/db.go b/db/db.go index 6f6216903d..4968138577 100644 --- a/db/db.go +++ b/db/db.go @@ -2,6 +2,7 @@ package db import ( "bytes" + "context" "database/sql" "embed" "encoding/hex" @@ -41,8 +42,10 @@ type SQLReaderDb interface { Close() error Get(dest interface{}, query string, args ...interface{}) error Select(dest interface{}, query string, args ...interface{}) error + SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error Query(query string, args ...any) (*sql.Rows, error) Preparex(query string) (*sqlx.Stmt, error) + Rebind(query string) string } // DB is a pointer to the explorer-database diff --git a/eth1data/eth1data_test.go b/eth1data/eth1data_test.go index 45a5c47051..d946893496 100644 --- a/eth1data/eth1data_test.go +++ b/eth1data/eth1data_test.go @@ -221,3 +221,13 @@ func (n noSQLReaderDb) Preparex(query string) (*sqlx.Stmt, error) { //TODO implement me panic("implement me") } + +func (n noSQLReaderDb) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error { + //TODO implement me + panic("implement me") +} + +func (n noSQLReaderDb) Rebind(query string) string { + //TODO implement me + panic("implement me") +} From 24087a7bda9b07f38ff24901a9ba366db1a02b78 Mon Sep 17 00:00:00 2001 From: Tangui Clairet <181825613+Tangui-Bitfly@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:54:55 +0000 Subject: [PATCH 03/40] fix(eth1tx): remove transfers if reverted --- db/bigtable_eth1.go | 1 + templates/eth1tx.html | 2 +- types/templates.go | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/db/bigtable_eth1.go b/db/bigtable_eth1.go index 45bd991ae4..d5678fcb91 100644 --- a/db/bigtable_eth1.go +++ b/db/bigtable_eth1.go @@ -2907,6 +2907,7 @@ func (bigtable *Bigtable) GetInternalTransfersForTransaction(transaction []byte, Amount: utils.FormatElCurrency(value, currency, 8, true, false, false, true), TracePath: utils.FormatTracePath(tx_type, parityTrace[i].TraceAddress, !reverted, bigtable.GetMethodLabel(input, from_contractInteraction)), Advanced: tx_type == "delegatecall" || string(value) == "\x00", + Reverted: reverted, } gaslimit, err := strconv.ParseUint(parityTrace[i].Action.Gas, 0, 0) diff --git a/templates/eth1tx.html b/templates/eth1tx.html index 85040600da..18800f7705 100644 --- a/templates/eth1tx.html +++ b/templates/eth1tx.html @@ -255,7 +255,7 @@

{{ if gt (len .InternalTxns) 0 }}