diff --git a/bridge-history-api/cmd/backend_server/app/app.go b/bridge-history-api/cmd/api/app/app.go similarity index 82% rename from bridge-history-api/cmd/backend_server/app/app.go rename to bridge-history-api/cmd/api/app/app.go index 82544c8b22..5a775a2f40 100644 --- a/bridge-history-api/cmd/backend_server/app/app.go +++ b/bridge-history-api/cmd/api/app/app.go @@ -11,11 +11,12 @@ import ( "github.com/scroll-tech/go-ethereum/log" "github.com/urfave/cli/v2" - "bridge-history-api/config" - "bridge-history-api/internal/controller" - "bridge-history-api/internal/route" - "bridge-history-api/observability" - "bridge-history-api/utils" + "scroll-tech/bridge-history-api/internal/config" + "scroll-tech/bridge-history-api/internal/controller/api" + "scroll-tech/bridge-history-api/internal/route" + "scroll-tech/common/database" + "scroll-tech/common/observability" + "scroll-tech/common/utils" ) var ( @@ -43,12 +44,12 @@ func action(ctx *cli.Context) error { if err != nil { log.Crit("failed to load config file", "config file", cfgFile, "error", err) } - db, err := utils.InitDB(cfg.DB) + db, err := database.InitDB(cfg.DB) if err != nil { log.Crit("failed to init db", "err", err) } defer func() { - if deferErr := utils.CloseDB(db); deferErr != nil { + if deferErr := database.CloseDB(db); deferErr != nil { log.Error("failed to close db", "err", err) } }() @@ -57,7 +58,7 @@ func action(ctx *cli.Context) error { Password: cfg.Redis.Password, DB: cfg.Redis.DB, }) - controller.InitController(db, redis) + api.InitController(db, redis) router := gin.Default() registry := prometheus.DefaultRegisterer diff --git a/bridge-history-api/cmd/api/main.go b/bridge-history-api/cmd/api/main.go new file mode 100644 index 0000000000..b0eb3a49aa --- /dev/null +++ b/bridge-history-api/cmd/api/main.go @@ -0,0 +1,7 @@ +package main + +import "scroll-tech/bridge-history-api/cmd/api/app" + +func main() { + app.Run() +} diff --git a/bridge-history-api/cmd/backend_server/main.go b/bridge-history-api/cmd/backend_server/main.go deleted file mode 100644 index 7920c63f7d..0000000000 --- a/bridge-history-api/cmd/backend_server/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "bridge-history-api/cmd/backend_server/app" - -func main() { - app.Run() -} diff --git a/bridge-history-api/cmd/cross_message_fetcher/main.go b/bridge-history-api/cmd/cross_message_fetcher/main.go deleted file mode 100644 index 2351ca543d..0000000000 --- a/bridge-history-api/cmd/cross_message_fetcher/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "bridge-history-api/cmd/cross_message_fetcher/app" - -func main() { - app.Run() -} diff --git a/bridge-history-api/cmd/db_cli/app/app.go b/bridge-history-api/cmd/db_cli/app/app.go index a8fa472f98..e452f90ce0 100644 --- a/bridge-history-api/cmd/db_cli/app/app.go +++ b/bridge-history-api/cmd/db_cli/app/app.go @@ -6,7 +6,7 @@ import ( "github.com/urfave/cli/v2" - "bridge-history-api/utils" + "scroll-tech/common/utils" ) var ( diff --git a/bridge-history-api/cmd/db_cli/app/client.go b/bridge-history-api/cmd/db_cli/app/client.go index 818794a303..280a86565e 100644 --- a/bridge-history-api/cmd/db_cli/app/client.go +++ b/bridge-history-api/cmd/db_cli/app/client.go @@ -5,9 +5,10 @@ import ( "github.com/urfave/cli/v2" "gorm.io/gorm" - "bridge-history-api/config" - "bridge-history-api/orm/migrate" - "bridge-history-api/utils" + "scroll-tech/bridge-history-api/internal/config" + "scroll-tech/bridge-history-api/internal/orm/migrate" + "scroll-tech/common/database" + "scroll-tech/common/utils" ) func getConfig(ctx *cli.Context) (*config.Config, error) { @@ -19,8 +20,8 @@ func getConfig(ctx *cli.Context) (*config.Config, error) { return dbCfg, nil } -func initDB(dbCfg *config.DBConfig) (*gorm.DB, error) { - return utils.InitDB(dbCfg) +func initDB(dbCfg *database.Config) (*gorm.DB, error) { + return database.InitDB(dbCfg) } // resetDB clean or reset database. diff --git a/bridge-history-api/cmd/db_cli/main.go b/bridge-history-api/cmd/db_cli/main.go index 53946494ac..93aaa442a8 100644 --- a/bridge-history-api/cmd/db_cli/main.go +++ b/bridge-history-api/cmd/db_cli/main.go @@ -1,6 +1,6 @@ package main -import "bridge-history-api/cmd/db_cli/app" +import "scroll-tech/bridge-history-api/cmd/db_cli/app" func main() { app.Run() diff --git a/bridge-history-api/cmd/cross_message_fetcher/app/app.go b/bridge-history-api/cmd/fetcher/app/app.go similarity index 81% rename from bridge-history-api/cmd/cross_message_fetcher/app/app.go rename to bridge-history-api/cmd/fetcher/app/app.go index 9a9cc84adb..a9084e157e 100644 --- a/bridge-history-api/cmd/cross_message_fetcher/app/app.go +++ b/bridge-history-api/cmd/fetcher/app/app.go @@ -10,9 +10,10 @@ import ( "github.com/scroll-tech/go-ethereum/log" "github.com/urfave/cli/v2" - "bridge-history-api/config" - "bridge-history-api/crossmessage/controller/eventfetcher" - "bridge-history-api/utils" + "scroll-tech/bridge-history-api/internal/config" + "scroll-tech/bridge-history-api/internal/controller/fetcher" + "scroll-tech/common/database" + "scroll-tech/common/utils" ) var ( @@ -52,12 +53,12 @@ func action(ctx *cli.Context) error { log.Crit("failed to connect to L2 geth", "endpoint", cfg.L2.Endpoint, "err", err) } - db, err := utils.InitDB(cfg.DB) + db, err := database.InitDB(cfg.DB) if err != nil { log.Crit("failed to init db", "err", err) } defer func() { - if deferErr := utils.CloseDB(db); deferErr != nil { + if deferErr := database.CloseDB(db); deferErr != nil { log.Error("failed to close db", "err", err) } }() @@ -65,13 +66,13 @@ func action(ctx *cli.Context) error { log.Crit("failed to connect to db", "config file", cfgFile, "error", err) } - l1MessageFetcher, err := eventfetcher.NewL1MessageFetcher(subCtx, cfg.L1, db, l1Client) + l1MessageFetcher, err := fetcher.NewL1MessageFetcher(subCtx, cfg.L1, db, l1Client) if err != nil { log.Crit("failed to create L1 cross message fetcher", "error", err) } go l1MessageFetcher.Start() - l2MessageFetcher, err := eventfetcher.NewL2MessageFetcher(subCtx, cfg.L2, db, l2Client) + l2MessageFetcher, err := fetcher.NewL2MessageFetcher(subCtx, cfg.L2, db, l2Client) if err != nil { log.Crit("failed to create L2 cross message fetcher", "error", err) } diff --git a/bridge-history-api/cmd/fetcher/main.go b/bridge-history-api/cmd/fetcher/main.go new file mode 100644 index 0000000000..ca46fde3f6 --- /dev/null +++ b/bridge-history-api/cmd/fetcher/main.go @@ -0,0 +1,7 @@ +package main + +import "scroll-tech/bridge-history-api/cmd/fetcher/app" + +func main() { + app.Run() +} diff --git a/bridge-history-api/config.json b/bridge-history-api/conf/config.json similarity index 100% rename from bridge-history-api/config.json rename to bridge-history-api/conf/config.json diff --git a/bridge-history-api/go.mod b/bridge-history-api/go.mod index 5724be1995..4b82b32d05 100644 --- a/bridge-history-api/go.mod +++ b/bridge-history-api/go.mod @@ -1,4 +1,4 @@ -module bridge-history-api +module scroll-tech/bridge-history-api go 1.19 diff --git a/bridge-history-api/config/config.go b/bridge-history-api/internal/config/config.go similarity index 83% rename from bridge-history-api/config/config.go rename to bridge-history-api/internal/config/config.go index f1cee2c66b..34ad434fb9 100644 --- a/bridge-history-api/config/config.go +++ b/bridge-history-api/internal/config/config.go @@ -4,6 +4,8 @@ import ( "encoding/json" "os" "path/filepath" + + "scroll-tech/common/database" ) // LayerConfig is the configuration of Layer1/Layer2 @@ -29,14 +31,6 @@ type LayerConfig struct { MessageQueueAddr string `json:"MessageQueueAddr"` } -// DBConfig db config -type DBConfig struct { - DSN string `json:"dsn"` - DriverName string `json:"driverName"` - MaxOpenNum int `json:"maxOpenNum"` - MaxIdleNum int `json:"maxIdleNum"` -} - // RedisConfig redis config type RedisConfig struct { Address string `json:"address"` @@ -51,11 +45,11 @@ type ServerConfig struct { // Config is the configuration of the bridge history backend type Config struct { - L1 *LayerConfig `json:"L1"` - L2 *LayerConfig `json:"L2"` - DB *DBConfig `json:"db"` - Redis *RedisConfig `json:"redis"` - Server *ServerConfig `json:"server"` + L1 *LayerConfig `json:"L1"` + L2 *LayerConfig `json:"L2"` + DB *database.Config `json:"db"` + Redis *RedisConfig `json:"redis"` + Server *ServerConfig `json:"server"` } // NewConfig returns a new instance of Config. diff --git a/bridge-history-api/internal/controller/controller.go b/bridge-history-api/internal/controller/api/controller.go similarity index 95% rename from bridge-history-api/internal/controller/controller.go rename to bridge-history-api/internal/controller/api/controller.go index b71222a93f..26a68d5a01 100644 --- a/bridge-history-api/internal/controller/controller.go +++ b/bridge-history-api/internal/controller/api/controller.go @@ -1,4 +1,4 @@ -package controller +package api import ( "sync" diff --git a/bridge-history-api/internal/controller/history_controller.go b/bridge-history-api/internal/controller/api/history_controller.go similarity index 99% rename from bridge-history-api/internal/controller/history_controller.go rename to bridge-history-api/internal/controller/api/history_controller.go index f37524cd58..6b7c1ef75c 100644 --- a/bridge-history-api/internal/controller/history_controller.go +++ b/bridge-history-api/internal/controller/api/history_controller.go @@ -1,4 +1,4 @@ -package controller +package api import ( "context" @@ -14,8 +14,8 @@ import ( "golang.org/x/sync/singleflight" "gorm.io/gorm" - "bridge-history-api/internal/logic" - "bridge-history-api/internal/types" + "scroll-tech/bridge-history-api/internal/logic" + "scroll-tech/bridge-history-api/internal/types" ) const ( diff --git a/bridge-history-api/internal/controller/metrics.go b/bridge-history-api/internal/controller/api/metrics.go similarity index 97% rename from bridge-history-api/internal/controller/metrics.go rename to bridge-history-api/internal/controller/api/metrics.go index 9036c5a8ac..3d41cf1903 100644 --- a/bridge-history-api/internal/controller/metrics.go +++ b/bridge-history-api/internal/controller/api/metrics.go @@ -1,4 +1,4 @@ -package controller +package api import ( "sync" diff --git a/bridge-history-api/crossmessage/controller/eventfetcher/l1_event_fetcher.go b/bridge-history-api/internal/controller/fetcher/l1_fetcher.go similarity index 97% rename from bridge-history-api/crossmessage/controller/eventfetcher/l1_event_fetcher.go rename to bridge-history-api/internal/controller/fetcher/l1_fetcher.go index e4db392f89..6588bb62ff 100644 --- a/bridge-history-api/crossmessage/controller/eventfetcher/l1_event_fetcher.go +++ b/bridge-history-api/internal/controller/fetcher/l1_fetcher.go @@ -1,4 +1,4 @@ -package eventfetcher +package fetcher import ( "context" @@ -12,11 +12,11 @@ import ( "github.com/scroll-tech/go-ethereum/log" "gorm.io/gorm" - backendabi "bridge-history-api/abi" - "bridge-history-api/config" - "bridge-history-api/crossmessage/logic" - "bridge-history-api/orm" - "bridge-history-api/utils" + backendabi "scroll-tech/bridge-history-api/abi" + "scroll-tech/bridge-history-api/internal/config" + "scroll-tech/bridge-history-api/internal/logic" + "scroll-tech/bridge-history-api/internal/orm" + "scroll-tech/bridge-history-api/internal/utils" ) // L1MessageFetcher fetches cross message events from L1 and saves them to database. diff --git a/bridge-history-api/crossmessage/controller/eventfetcher/l2_event_fetcher.go b/bridge-history-api/internal/controller/fetcher/l2_fetcher.go similarity index 96% rename from bridge-history-api/crossmessage/controller/eventfetcher/l2_event_fetcher.go rename to bridge-history-api/internal/controller/fetcher/l2_fetcher.go index 057c251979..a7d69526aa 100644 --- a/bridge-history-api/crossmessage/controller/eventfetcher/l2_event_fetcher.go +++ b/bridge-history-api/internal/controller/fetcher/l2_fetcher.go @@ -1,4 +1,4 @@ -package eventfetcher +package fetcher import ( "context" @@ -14,12 +14,11 @@ import ( "github.com/scroll-tech/go-ethereum/rpc" "gorm.io/gorm" - backendabi "bridge-history-api/abi" - "bridge-history-api/config" - "bridge-history-api/crossmessage/controller/messageproof" - "bridge-history-api/crossmessage/logic" - "bridge-history-api/orm" - "bridge-history-api/utils" + backendabi "scroll-tech/bridge-history-api/abi" + "scroll-tech/bridge-history-api/internal/config" + "scroll-tech/bridge-history-api/internal/logic" + "scroll-tech/bridge-history-api/internal/orm" + "scroll-tech/bridge-history-api/internal/utils" ) // L2MessageFetcher fetches cross message events from L2 and saves them to database. @@ -215,7 +214,7 @@ func (c *L2MessageFetcher) doFetchAndSaveEvents(ctx context.Context, from uint64 } func (c *L2MessageFetcher) updateL2WithdrawMessageProofs(ctx context.Context, l2WithdrawMessages []*orm.CrossMessage) error { - withdrawTrie := messageproof.NewWithdrawTrie() + withdrawTrie := utils.NewWithdrawTrie() message, err := c.crossMessageOrm.GetLatestL2Withdrawal(ctx) if err != nil { log.Error("failed to get latest L2 sent message event", "err", err) diff --git a/bridge-history-api/internal/logic/history_logic.go b/bridge-history-api/internal/logic/history_logic.go index 9683f9c9fa..1456690719 100644 --- a/bridge-history-api/internal/logic/history_logic.go +++ b/bridge-history-api/internal/logic/history_logic.go @@ -7,8 +7,8 @@ import ( "github.com/scroll-tech/go-ethereum/common" "gorm.io/gorm" - "bridge-history-api/internal/types" - "bridge-history-api/orm" + "scroll-tech/bridge-history-api/internal/orm" + "scroll-tech/bridge-history-api/internal/types" ) // HistoryLogic services. @@ -85,7 +85,7 @@ func getTxHistoryInfo(message *orm.CrossMessage) *types.TxHistoryInfo { L1Token: message.L1TokenAddress, L2Token: message.L2TokenAddress, IsL1: orm.MessageType(message.MessageType) == orm.MessageTypeL1SentMessage, - TxStatus: orm.TxStatusType(message.TxStatus), + TxStatus: message.TxStatus, CreatedAt: &message.CreatedAt, } if txHistory.IsL1 { diff --git a/bridge-history-api/crossmessage/logic/event_parser.go b/bridge-history-api/internal/logic/watcher_event_parser.go similarity index 99% rename from bridge-history-api/crossmessage/logic/event_parser.go rename to bridge-history-api/internal/logic/watcher_event_parser.go index a3c7508118..14acbb3793 100644 --- a/bridge-history-api/crossmessage/logic/event_parser.go +++ b/bridge-history-api/internal/logic/watcher_event_parser.go @@ -12,9 +12,9 @@ import ( "github.com/scroll-tech/go-ethereum/ethclient" "github.com/scroll-tech/go-ethereum/log" - backendabi "bridge-history-api/abi" - "bridge-history-api/orm" - "bridge-history-api/utils" + backendabi "scroll-tech/bridge-history-api/abi" + "scroll-tech/bridge-history-api/internal/orm" + "scroll-tech/bridge-history-api/internal/utils" ) // ParseL1CrossChainEventLogs parses L1 watched cross chain events. diff --git a/bridge-history-api/orm/batch_event.go b/bridge-history-api/internal/orm/batch_event.go similarity index 100% rename from bridge-history-api/orm/batch_event.go rename to bridge-history-api/internal/orm/batch_event.go diff --git a/bridge-history-api/orm/cross_message.go b/bridge-history-api/internal/orm/cross_message.go similarity index 100% rename from bridge-history-api/orm/cross_message.go rename to bridge-history-api/internal/orm/cross_message.go diff --git a/bridge-history-api/orm/migrate/migrate.go b/bridge-history-api/internal/orm/migrate/migrate.go similarity index 100% rename from bridge-history-api/orm/migrate/migrate.go rename to bridge-history-api/internal/orm/migrate/migrate.go diff --git a/bridge-history-api/orm/migrate/migrations/00001_cross_message.sql b/bridge-history-api/internal/orm/migrate/migrations/00001_cross_message.sql similarity index 100% rename from bridge-history-api/orm/migrate/migrations/00001_cross_message.sql rename to bridge-history-api/internal/orm/migrate/migrations/00001_cross_message.sql diff --git a/bridge-history-api/orm/migrate/migrations/00002_batch_event.sql b/bridge-history-api/internal/orm/migrate/migrations/00002_batch_event.sql similarity index 100% rename from bridge-history-api/orm/migrate/migrations/00002_batch_event.sql rename to bridge-history-api/internal/orm/migrate/migrations/00002_batch_event.sql diff --git a/bridge-history-api/internal/route/route.go b/bridge-history-api/internal/route/route.go index 37d2928139..0ae3fc42c9 100644 --- a/bridge-history-api/internal/route/route.go +++ b/bridge-history-api/internal/route/route.go @@ -7,9 +7,9 @@ import ( "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus" - "bridge-history-api/config" - "bridge-history-api/internal/controller" - "bridge-history-api/observability" + "scroll-tech/bridge-history-api/internal/config" + "scroll-tech/bridge-history-api/internal/controller/api" + "scroll-tech/common/observability" ) // Route routes the APIs @@ -25,9 +25,10 @@ func Route(router *gin.Engine, conf *config.Config, reg prometheus.Registerer) { observability.Use(router, "bridge_history_api", reg) r := router.Group("api/") - r.GET("/txs", controller.HistoryCtrler.GetTxsByAddress) - r.GET("/withdrawals", controller.HistoryCtrler.GetL2WithdrawalsByAddress) - r.GET("/claimablewithdrawals", controller.HistoryCtrler.GetL2ClaimableWithdrawalsByAddress) - r.POST("/txsbyhashes", controller.HistoryCtrler.PostQueryTxsByHashes) + r.GET("/txs", api.HistoryCtrler.GetTxsByAddress) + r.GET("/withdrawals", api.HistoryCtrler.GetL2WithdrawalsByAddress) + r.GET("/claimablewithdrawals", api.HistoryCtrler.GetL2ClaimableWithdrawalsByAddress) + + r.POST("/txsbyhashes", api.HistoryCtrler.PostQueryTxsByHashes) } diff --git a/bridge-history-api/internal/types/types.go b/bridge-history-api/internal/types/types.go index 75d988c4cd..abd1aac670 100644 --- a/bridge-history-api/internal/types/types.go +++ b/bridge-history-api/internal/types/types.go @@ -5,8 +5,6 @@ import ( "time" "github.com/gin-gonic/gin" - - "bridge-history-api/orm" ) const ( @@ -71,17 +69,17 @@ type UserClaimInfo struct { // TxHistoryInfo the schema of tx history infos type TxHistoryInfo struct { - Hash string `json:"hash"` - MsgHash string `json:"msgHash"` - Amount string `json:"amount"` - IsL1 bool `json:"isL1"` - L1Token string `json:"l1Token"` - L2Token string `json:"l2Token"` - BlockNumber uint64 `json:"blockNumber"` - TxStatus orm.TxStatusType `json:"txStatus"` - FinalizeTx *Finalized `json:"finalizeTx"` - ClaimInfo *UserClaimInfo `json:"claimInfo"` - CreatedAt *time.Time `json:"createdTime"` + Hash string `json:"hash"` + MsgHash string `json:"msgHash"` + Amount string `json:"amount"` + IsL1 bool `json:"isL1"` + L1Token string `json:"l1Token"` + L2Token string `json:"l2Token"` + BlockNumber uint64 `json:"blockNumber"` + TxStatus int `json:"txStatus"` + FinalizeTx *Finalized `json:"finalizeTx"` + ClaimInfo *UserClaimInfo `json:"claimInfo"` + CreatedAt *time.Time `json:"createdTime"` } // RenderJSON renders response with json diff --git a/bridge-history-api/utils/utils.go b/bridge-history-api/internal/utils/utils.go similarity index 98% rename from bridge-history-api/utils/utils.go rename to bridge-history-api/internal/utils/utils.go index 3d79c7592e..57c381eaff 100644 --- a/bridge-history-api/utils/utils.go +++ b/bridge-history-api/internal/utils/utils.go @@ -13,7 +13,7 @@ import ( "github.com/scroll-tech/go-ethereum/crypto" "github.com/scroll-tech/go-ethereum/ethclient" - backendabi "bridge-history-api/abi" + backendabi "scroll-tech/bridge-history-api/abi" ) // Keccak2 compute the keccack256 of two concatenations of bytes32 diff --git a/bridge-history-api/internal/utils/utils_test.go b/bridge-history-api/internal/utils/utils_test.go new file mode 100644 index 0000000000..e12413463c --- /dev/null +++ b/bridge-history-api/internal/utils/utils_test.go @@ -0,0 +1,38 @@ +package utils + +import ( + "testing" + + "github.com/scroll-tech/go-ethereum/common" + "github.com/stretchr/testify/assert" +) + +func TestKeccak2(t *testing.T) { + a := common.HexToHash("0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0") + b := common.HexToHash("0x222ff5e0b5877792c2bc1670e2ccd0c2c97cd7bb1672a57d598db05092d3d72c") + c := Keccak2(a, b) + assert.NotEmpty(t, c) + assert.NotEqual(t, a, c) + assert.NotEqual(t, b, c) + assert.Equal(t, "0xc0ffbd7f501bd3d49721b0724b2bff657cb2378f15d5a9b97cd7ea5bf630d512", c.Hex()) +} + +func TestGetBatchRangeFromCalldata(t *testing.T) { + // single chunk + start, finish, err := GetBatchRangeFromCalldata(common.Hex2Bytes("1325aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003d0100000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000100000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000")) + assert.NoError(t, err) + assert.Equal(t, start, uint64(1)) + assert.Equal(t, finish, uint64(1)) + + // multiple chunk + start, finish, err = GetBatchRangeFromCalldata(common.Hex2Bytes("1325aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000007900000000000000000100000000000000010000000000000001038433daac85a0b03cd443ed50bc85e832c883061651ae2182b2984751e0b340119b828c2a2798d2c957228ebeaff7e10bb099ae0d4e224f3eeb779ff61cba610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004c01000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000010000000001000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b403000000000000000b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000300000000000000000b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00050000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c01000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa800000000000000000000000000000000000000000000000000000000000000aa")) + assert.NoError(t, err) + assert.Equal(t, start, uint64(10)) + assert.Equal(t, finish, uint64(20)) + + // genesis batch + start, finish, err = GetBatchRangeFromCalldata(common.Hex2Bytes("3fdeecb200000000000000000000000000000000000000000000000000000000000000402dcb5308098d24a37fc1487a229fcedb09fa4343ede39cbad365bc925535bb09000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000c252bc9780c4d83cf11f14b8cd03c92c4d18ce07710ba836d31d12da216c8330000000000000000000000000000000000000000000000000000000000000000000000000000000")) + assert.NoError(t, err) + assert.Equal(t, start, uint64(0)) + assert.Equal(t, finish, uint64(0)) +} diff --git a/bridge-history-api/crossmessage/controller/messageproof/withdraw_trie.go b/bridge-history-api/internal/utils/withdraw_trie.go similarity index 93% rename from bridge-history-api/crossmessage/controller/messageproof/withdraw_trie.go rename to bridge-history-api/internal/utils/withdraw_trie.go index 1968eba76f..627f83635c 100644 --- a/bridge-history-api/crossmessage/controller/messageproof/withdraw_trie.go +++ b/bridge-history-api/internal/utils/withdraw_trie.go @@ -1,9 +1,7 @@ -package messageproof +package utils import ( "github.com/scroll-tech/go-ethereum/common" - - "bridge-history-api/utils" ) // MaxHeight is the maixium possible height of withdraw trie @@ -27,7 +25,7 @@ func NewWithdrawTrie() *WithdrawTrie { zeroes[0] = common.Hash{} for i := 1; i < MaxHeight; i++ { - zeroes[i] = utils.Keccak2(zeroes[i-1], zeroes[i-1]) + zeroes[i] = Keccak2(zeroes[i-1], zeroes[i-1]) } return &WithdrawTrie{ @@ -87,7 +85,7 @@ func (w *WithdrawTrie) AppendMessages(hashes []common.Hash) [][]byte { cache[h][maxIndex^1] = w.zeroes[h] } for i := minIndex; i <= maxIndex; i += 2 { - cache[h+1][i>>1] = utils.Keccak2(cache[h][i], cache[h][i^1]) + cache[h+1][i>>1] = Keccak2(cache[h][i], cache[h][i^1]) } minIndex >>= 1 maxIndex >>= 1 @@ -152,10 +150,10 @@ func UpdateBranchWithNewMessage(zeroes []common.Hash, branches []common.Hash, in branches[height] = root merkleProof = append(merkleProof, zeroes[height]) // it's a left child, the right child must be null - root = utils.Keccak2(root, zeroes[height]) + root = Keccak2(root, zeroes[height]) } else { // it's a right child, use previously computed hash - root = utils.Keccak2(branches[height], root) + root = Keccak2(branches[height], root) merkleProof = append(merkleProof, branches[height]) } index >>= 1 @@ -173,11 +171,11 @@ func RecoverBranchFromProof(proof []common.Hash, index uint64, msgHash common.Ha if index%2 == 0 { branches[height] = root // it's a left child, the right child must be null - root = utils.Keccak2(root, proof[height]) + root = Keccak2(root, proof[height]) } else { // it's a right child, use previously computed hash branches[height] = proof[height] - root = utils.Keccak2(proof[height], root) + root = Keccak2(proof[height], root) } index >>= 1 } diff --git a/bridge-history-api/crossmessage/controller/messageproof/withdraw_trie_test.go b/bridge-history-api/internal/utils/withdraw_trie_test.go similarity index 95% rename from bridge-history-api/crossmessage/controller/messageproof/withdraw_trie_test.go rename to bridge-history-api/internal/utils/withdraw_trie_test.go index 7e88270c88..8e89db64e5 100644 --- a/bridge-history-api/crossmessage/controller/messageproof/withdraw_trie_test.go +++ b/bridge-history-api/internal/utils/withdraw_trie_test.go @@ -1,4 +1,4 @@ -package messageproof +package utils import ( "math/big" @@ -6,8 +6,6 @@ import ( "github.com/scroll-tech/go-ethereum/common" "github.com/stretchr/testify/assert" - - "bridge-history-api/utils" ) func TestUpdateBranchWithNewMessage(t *testing.T) { @@ -15,7 +13,7 @@ func TestUpdateBranchWithNewMessage(t *testing.T) { branches := make([]common.Hash, 64) zeroes[0] = common.Hash{} for i := 1; i < 64; i++ { - zeroes[i] = utils.Keccak2(zeroes[i-1], zeroes[i-1]) + zeroes[i] = Keccak2(zeroes[i-1], zeroes[i-1]) } UpdateBranchWithNewMessage(zeroes, branches, 0, common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001")) @@ -68,7 +66,7 @@ func TestRecoverBranchFromProof(t *testing.T) { branches := make([]common.Hash, 64) zeroes[0] = common.Hash{} for i := 1; i < 64; i++ { - zeroes[i] = utils.Keccak2(zeroes[i-1], zeroes[i-1]) + zeroes[i] = Keccak2(zeroes[i-1], zeroes[i-1]) } proof := UpdateBranchWithNewMessage(zeroes, branches, 0, common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001")) @@ -178,9 +176,9 @@ func verifyMerkleProof(index uint64, leaf common.Hash, proof []common.Hash) comm root := leaf for _, h := range proof { if index%2 == 0 { - root = utils.Keccak2(root, h) + root = Keccak2(root, h) } else { - root = utils.Keccak2(h, root) + root = Keccak2(h, root) } index >>= 1 } @@ -200,13 +198,13 @@ func computeMerkleRoot(hashes []common.Hash) common.Hash { var newHashes []common.Hash for i := 0; i < len(hashes); i += 2 { if i+1 < len(hashes) { - newHashes = append(newHashes, utils.Keccak2(hashes[i], hashes[i+1])) + newHashes = append(newHashes, Keccak2(hashes[i], hashes[i+1])) } else { - newHashes = append(newHashes, utils.Keccak2(hashes[i], zeroHash)) + newHashes = append(newHashes, Keccak2(hashes[i], zeroHash)) } } hashes = newHashes - zeroHash = utils.Keccak2(zeroHash, zeroHash) + zeroHash = Keccak2(zeroHash, zeroHash) } return hashes[0] } diff --git a/bridge-history-api/observability/ginmetrics/bloom.go b/bridge-history-api/observability/ginmetrics/bloom.go deleted file mode 100644 index 9851ac29a9..0000000000 --- a/bridge-history-api/observability/ginmetrics/bloom.go +++ /dev/null @@ -1,57 +0,0 @@ -package ginmetrics - -import ( - "github.com/bits-and-blooms/bitset" -) - -const defaultSize = 2 << 24 - -var seeds = []uint{7, 11, 13, 31, 37, 61} - -// BloomFilter a simple bloom filter -type BloomFilter struct { - Set *bitset.BitSet - Funcs [6]simpleHash -} - -// NewBloomFilter new a BloomFilter -func NewBloomFilter() *BloomFilter { - bf := new(BloomFilter) - for i := 0; i < len(bf.Funcs); i++ { - bf.Funcs[i] = simpleHash{defaultSize, seeds[i]} - } - bf.Set = bitset.New(defaultSize) - return bf -} - -// Add a value to BloomFilter -func (bf *BloomFilter) Add(value string) { - for _, f := range bf.Funcs { - bf.Set.Set(f.hash(value)) - } -} - -// Contains check the value is in bloom filter -func (bf *BloomFilter) Contains(value string) bool { - if value == "" { - return false - } - ret := true - for _, f := range bf.Funcs { - ret = ret && bf.Set.Test(f.hash(value)) - } - return ret -} - -type simpleHash struct { - Cap uint - Seed uint -} - -func (s *simpleHash) hash(value string) uint { - var result uint = 0 - for i := 0; i < len(value); i++ { - result = result*s.Seed + uint(value[i]) - } - return (s.Cap - 1) & result -} diff --git a/bridge-history-api/observability/ginmetrics/metric.go b/bridge-history-api/observability/ginmetrics/metric.go deleted file mode 100644 index 9720460076..0000000000 --- a/bridge-history-api/observability/ginmetrics/metric.go +++ /dev/null @@ -1,89 +0,0 @@ -package ginmetrics - -import ( - "fmt" - - "github.com/prometheus/client_golang/prometheus" -) - -// Metric defines a metric object. Users can use it to save -// metric data. Every metric should be globally unique by name. -type Metric struct { - Type MetricType - Name string - Description string - Labels []string - Buckets []float64 - Objectives map[float64]float64 - - vec prometheus.Collector -} - -// SetGaugeValue set data for Gauge type Metric. -func (m *Metric) SetGaugeValue(labelValues []string, value float64) error { - if m.Type == None { - return fmt.Errorf("metric %s not existed", m.Name) - } - - if m.Type != Gauge { - return fmt.Errorf("metric %s not Gauge type", m.Name) - } - m.vec.(*prometheus.GaugeVec).WithLabelValues(labelValues...).Set(value) - return nil -} - -// Inc increases value for Counter/Gauge type metric, increments -// the counter by 1 -func (m *Metric) Inc(labelValues []string) error { - if m.Type == None { - return fmt.Errorf("metric %s not existed", m.Name) - } - - if m.Type != Gauge && m.Type != Counter { - return fmt.Errorf("metric %s not Gauge or Counter type", m.Name) - } - switch m.Type { - case Counter: - m.vec.(*prometheus.CounterVec).WithLabelValues(labelValues...).Inc() - case Gauge: - m.vec.(*prometheus.GaugeVec).WithLabelValues(labelValues...).Inc() - } - return nil -} - -// Add adds the given value to the Metric object. Only -// for Counter/Gauge type metric. -func (m *Metric) Add(labelValues []string, value float64) error { - if m.Type == None { - return fmt.Errorf("metric %s not existed", m.Name) - } - - if m.Type != Gauge && m.Type != Counter { - return fmt.Errorf("metric %s not Gauge or Counter type", m.Name) - } - switch m.Type { - case Counter: - m.vec.(*prometheus.CounterVec).WithLabelValues(labelValues...).Add(value) - case Gauge: - m.vec.(*prometheus.GaugeVec).WithLabelValues(labelValues...).Add(value) - } - return nil -} - -// Observe is used by Histogram and Summary type metric to -// add observations. -func (m *Metric) Observe(labelValues []string, value float64) error { - if m.Type == 0 { - return fmt.Errorf("metric %s not existed", m.Name) - } - if m.Type != Histogram && m.Type != Summary { - return fmt.Errorf("metric %s not Histogram or Summary type", m.Name) - } - switch m.Type { - case Histogram: - m.vec.(*prometheus.HistogramVec).WithLabelValues(labelValues...).Observe(value) - case Summary: - m.vec.(*prometheus.SummaryVec).WithLabelValues(labelValues...).Observe(value) - } - return nil -} diff --git a/bridge-history-api/observability/ginmetrics/middleware.go b/bridge-history-api/observability/ginmetrics/middleware.go deleted file mode 100644 index 79f74bee0d..0000000000 --- a/bridge-history-api/observability/ginmetrics/middleware.go +++ /dev/null @@ -1,155 +0,0 @@ -package ginmetrics - -import ( - "fmt" - "strconv" - "time" - - "github.com/gin-gonic/gin" - "github.com/prometheus/client_golang/prometheus/promhttp" -) - -var ( - metricRequestTotal = "request_total" - metricRequestUVTotal = "request_uv_total" - metricURIRequestTotal = "uri_request_total" - metricRequestBody = "request_body_total" - metricResponseBody = "response_body_total" - metricRequestDuration = "request_duration" - metricSlowRequest = "slow_request_total" - - bloomFilter *BloomFilter -) - -// Use set gin metrics middleware -func (m *Monitor) Use(r gin.IRoutes) { - m.initGinMetrics() - - r.Use(m.monitorInterceptor) - r.GET(m.metricPath, func(ctx *gin.Context) { - promhttp.Handler().ServeHTTP(ctx.Writer, ctx.Request) - }) -} - -// UseWithoutExposingEndpoint is used to add monitor interceptor to gin router -// It can be called multiple times to intercept from multiple gin.IRoutes -// http path is not set, to do that use Expose function -func (m *Monitor) UseWithoutExposingEndpoint(r gin.IRoutes) { - m.initGinMetrics() - r.Use(m.monitorInterceptor) -} - -// Expose adds metric path to a given router. -// The router can be different with the one passed to UseWithoutExposingEndpoint. -// This allows to expose metrics on different port. -func (m *Monitor) Expose(r gin.IRoutes) { - r.GET(m.metricPath, func(ctx *gin.Context) { - promhttp.Handler().ServeHTTP(ctx.Writer, ctx.Request) - }) -} - -// initGinMetrics used to init gin metrics -func (m *Monitor) initGinMetrics() { - bloomFilter = NewBloomFilter() - - _ = monitor.AddMetric(&Metric{ - Type: Counter, - Name: metricRequestTotal, - Description: "all the server received request num.", - Labels: nil, - }) - _ = monitor.AddMetric(&Metric{ - Type: Counter, - Name: metricRequestUVTotal, - Description: "all the server received ip num.", - Labels: nil, - }) - _ = monitor.AddMetric(&Metric{ - Type: Counter, - Name: metricURIRequestTotal, - Description: "all the server received request num with every uri.", - Labels: []string{"uri", "method", "code"}, - }) - _ = monitor.AddMetric(&Metric{ - Type: Counter, - Name: metricRequestBody, - Description: "the server received request body size, unit byte", - Labels: nil, - }) - _ = monitor.AddMetric(&Metric{ - Type: Counter, - Name: metricResponseBody, - Description: "the server send response body size, unit byte", - Labels: nil, - }) - _ = monitor.AddMetric(&Metric{ - Type: Histogram, - Name: metricRequestDuration, - Description: "the time server took to handle the request.", - Labels: []string{"uri"}, - Buckets: m.reqDuration, - }) - _ = monitor.AddMetric(&Metric{ - Type: Counter, - Name: metricSlowRequest, - Description: fmt.Sprintf("the server handled slow requests counter, t=%d.", m.slowTime), - Labels: []string{"uri", "method", "code"}, - }) -} - -// monitorInterceptor as gin monitor middleware. -func (m *Monitor) monitorInterceptor(ctx *gin.Context) { - if ctx.Request.URL.Path == m.metricPath { - ctx.Next() - return - } - startTime := time.Now() - - // execute normal process. - ctx.Next() - - // after request - m.ginMetricHandle(ctx, startTime) -} - -func (m *Monitor) ginMetricHandle(ctx *gin.Context, start time.Time) { - r := ctx.Request - w := ctx.Writer - - //set request total - _ = m.GetMetric(metricRequestTotal).Inc(nil) - - // set uv - if clientIP := ctx.ClientIP(); !bloomFilter.Contains(clientIP) { - bloomFilter.Add(clientIP) - _ = m.GetMetric(metricRequestUVTotal).Inc(nil) - } - - errCode := strconv.Itoa(ctx.GetInt("errcode")) - if len(errCode) == 0 { - errCode = strconv.Itoa(w.Status()) - } - - // set uri request total - _ = m.GetMetric(metricURIRequestTotal).Inc([]string{ctx.FullPath(), r.Method, errCode}) - - // set request body size - // since r.ContentLength can be negative (in some occasions) guard the operation - if r.ContentLength >= 0 { - _ = m.GetMetric(metricRequestBody).Add(nil, float64(r.ContentLength)) - } - - // set slow request - latency := time.Since(start) - if int32(latency.Seconds()) > m.slowTime { - _ = m.GetMetric(metricSlowRequest).Inc([]string{ctx.FullPath(), r.Method, strconv.Itoa(w.Status())}) - } - - // set request duration - _ = m.GetMetric(metricRequestDuration).Observe([]string{ctx.FullPath()}, latency.Seconds()) - - // set response size - if w.Size() > 0 { - _ = m.GetMetric(metricResponseBody).Add(nil, float64(w.Size())) - } -} diff --git a/bridge-history-api/observability/ginmetrics/types.go b/bridge-history-api/observability/ginmetrics/types.go deleted file mode 100644 index 113a580850..0000000000 --- a/bridge-history-api/observability/ginmetrics/types.go +++ /dev/null @@ -1,158 +0,0 @@ -package ginmetrics - -import ( - "errors" - "fmt" - - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" -) - -// MetricType define metric type -type MetricType int - -const ( - // None unknown metric type - None MetricType = iota - // Counter MetricType - Counter - // Gauge MetricType - Gauge - // Histogram MetricType - Histogram - // Summary MetricType - Summary - - defaultMetricPath = "/debug/metrics" - defaultSlowTime = int32(5) -) - -var ( - defaultDuration = []float64{0.1, 0.3, 1.2, 5, 10} - monitor *Monitor - - promTypeHandler = map[MetricType]func(metric *Metric, reg prometheus.Registerer){ - Counter: counterHandler, - Gauge: gaugeHandler, - Histogram: histogramHandler, - Summary: summaryHandler, - } -) - -// Monitor is an object that uses to set gin server monitor. -type Monitor struct { - slowTime int32 - metricPath string - reqDuration []float64 - metrics map[string]*Metric - register prometheus.Registerer -} - -// GetMonitor used to get global Monitor object, -// this function returns a singleton object. -func GetMonitor(reg prometheus.Registerer) *Monitor { - if monitor == nil { - monitor = &Monitor{ - metricPath: defaultMetricPath, - slowTime: defaultSlowTime, - reqDuration: defaultDuration, - metrics: make(map[string]*Metric), - register: reg, - } - } - return monitor -} - -// GetMetric used to get metric object by metric_name. -func (m *Monitor) GetMetric(name string) *Metric { - if metric, ok := m.metrics[name]; ok { - return metric - } - return &Metric{} -} - -// SetMetricPath set metricPath property. metricPath is used for Prometheus -// to get gin server monitoring data. -func (m *Monitor) SetMetricPath(path string) { - m.metricPath = path -} - -// SetSlowTime set slowTime property. slowTime is used to determine whether -// the request is slow. For "gin_slow_request_total" metric. -func (m *Monitor) SetSlowTime(slowTime int32) { - m.slowTime = slowTime -} - -// SetDuration set reqDuration property. reqDuration is used to ginRequestDuration -// metric buckets. -func (m *Monitor) SetDuration(duration []float64) { - m.reqDuration = duration -} - -// SetMetricPrefix set the metric prefix -func (m *Monitor) SetMetricPrefix(prefix string) { - metricRequestTotal = prefix + metricRequestTotal - metricRequestUVTotal = prefix + metricRequestUVTotal - metricURIRequestTotal = prefix + metricURIRequestTotal - metricRequestBody = prefix + metricRequestBody - metricResponseBody = prefix + metricResponseBody - metricRequestDuration = prefix + metricRequestDuration - metricSlowRequest = prefix + metricSlowRequest -} - -// SetMetricSuffix set the metric suffix -func (m *Monitor) SetMetricSuffix(suffix string) { - metricRequestTotal += suffix - metricRequestUVTotal += suffix - metricURIRequestTotal += suffix - metricRequestBody += suffix - metricResponseBody += suffix - metricRequestDuration += suffix - metricSlowRequest += suffix -} - -// AddMetric add custom monitor metric. -func (m *Monitor) AddMetric(metric *Metric) error { - if _, ok := m.metrics[metric.Name]; ok { - return fmt.Errorf("metric %s is existed", metric.Name) - } - - if metric.Name == "" { - return errors.New("metric name cannot be empty") - } - - if f, ok := promTypeHandler[metric.Type]; ok { - f(metric, m.register) - m.metrics[metric.Name] = metric - } - - return nil -} - -func counterHandler(metric *Metric, register prometheus.Registerer) { - metric.vec = promauto.With(register).NewCounterVec( - prometheus.CounterOpts{Name: metric.Name, Help: metric.Description}, - metric.Labels, - ) -} - -func gaugeHandler(metric *Metric, register prometheus.Registerer) { - metric.vec = promauto.With(register).NewGaugeVec( - prometheus.GaugeOpts{Name: metric.Name, Help: metric.Description}, - metric.Labels, - ) -} - -func histogramHandler(metric *Metric, register prometheus.Registerer) { - metric.vec = promauto.With(register).NewHistogramVec( - prometheus.HistogramOpts{Name: metric.Name, Help: metric.Description, Buckets: metric.Buckets}, - metric.Labels, - ) -} - -func summaryHandler(metric *Metric, register prometheus.Registerer) { - promauto.With(register).NewSummaryVec( - prometheus.SummaryOpts{Name: metric.Name, Help: metric.Description, Objectives: metric.Objectives}, - metric.Labels, - ) -} diff --git a/bridge-history-api/observability/middleware.go b/bridge-history-api/observability/middleware.go deleted file mode 100644 index 03ff90e8a0..0000000000 --- a/bridge-history-api/observability/middleware.go +++ /dev/null @@ -1,18 +0,0 @@ -package observability - -import ( - "github.com/gin-gonic/gin" - "github.com/prometheus/client_golang/prometheus" - - "bridge-history-api/observability/ginmetrics" -) - -// Use register the gin metric -func Use(router *gin.Engine, metricsPrefix string, reg prometheus.Registerer) { - m := ginmetrics.GetMonitor(reg) - m.SetMetricPath("/metrics") - m.SetMetricPrefix(metricsPrefix + "_") - m.SetSlowTime(1) - m.SetDuration([]float64{0.025, .05, .1, .5, 1, 5, 10}) - m.UseWithoutExposingEndpoint(router) -} diff --git a/bridge-history-api/observability/probes.go b/bridge-history-api/observability/probes.go deleted file mode 100644 index 339c1b7422..0000000000 --- a/bridge-history-api/observability/probes.go +++ /dev/null @@ -1,35 +0,0 @@ -package observability - -import ( - "github.com/gin-gonic/gin" - "gorm.io/gorm" - - "bridge-history-api/internal/types" - "bridge-history-api/utils" -) - -// ProbesController probe check controller -type ProbesController struct { - db *gorm.DB -} - -// NewProbesController returns an ProbesController instance -func NewProbesController(db *gorm.DB) *ProbesController { - return &ProbesController{ - db: db, - } -} - -// HealthCheck the api controller for health check -func (a *ProbesController) HealthCheck(c *gin.Context) { - if _, err := utils.Ping(a.db); err != nil { - types.RenderFatal(c, err) - return - } - types.RenderSuccess(c, nil) -} - -// Ready the api controller for ready check -func (a *ProbesController) Ready(c *gin.Context) { - types.RenderSuccess(c, nil) -} diff --git a/bridge-history-api/observability/server.go b/bridge-history-api/observability/server.go deleted file mode 100644 index e589afa2fb..0000000000 --- a/bridge-history-api/observability/server.go +++ /dev/null @@ -1,53 +0,0 @@ -package observability - -import ( - "errors" - "fmt" - "net/http" - "time" - - // enable the pprof - _ "net/http/pprof" - - "github.com/gin-contrib/pprof" - "github.com/gin-gonic/gin" - "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/scroll-tech/go-ethereum/log" - "github.com/urfave/cli/v2" - "gorm.io/gorm" - - "bridge-history-api/utils" -) - -// Server starts the metrics server on the given address, will be closed when the given -// context is canceled. -func Server(c *cli.Context, db *gorm.DB) { - if !c.Bool(utils.MetricsEnabled.Name) { - return - } - - r := gin.New() - r.Use(gin.Recovery()) - pprof.Register(r) - r.GET("/metrics", func(context *gin.Context) { - promhttp.Handler().ServeHTTP(context.Writer, context.Request) - }) - - probeController := NewProbesController(db) - r.GET("/health", probeController.HealthCheck) - r.GET("/ready", probeController.Ready) - - address := fmt.Sprintf(":%s", c.String(utils.MetricsPort.Name)) - server := &http.Server{ - Addr: address, - Handler: r, - ReadHeaderTimeout: time.Minute, - } - log.Info("Starting metrics server", "address", address) - - go func() { - if runServerErr := server.ListenAndServe(); runServerErr != nil && !errors.Is(runServerErr, http.ErrServerClosed) { - log.Crit("run metrics http server failure", "error", runServerErr) - } - }() -} diff --git a/bridge-history-api/utils/database.go b/bridge-history-api/utils/database.go deleted file mode 100644 index a71011d093..0000000000 --- a/bridge-history-api/utils/database.go +++ /dev/null @@ -1,115 +0,0 @@ -package utils - -import ( - "context" - "database/sql" - "fmt" - "time" - - "github.com/scroll-tech/go-ethereum/log" - "gorm.io/driver/postgres" - "gorm.io/gorm" - "gorm.io/gorm/logger" - "gorm.io/gorm/utils" - - "bridge-history-api/config" -) - -type gormLogger struct { - gethLogger log.Logger -} - -func (g *gormLogger) LogMode(level logger.LogLevel) logger.Interface { - return g -} - -func (g *gormLogger) Info(_ context.Context, msg string, data ...interface{}) { - infoMsg := fmt.Sprintf(msg, data...) - g.gethLogger.Info("gorm", "info message", infoMsg) -} - -func (g *gormLogger) Warn(_ context.Context, msg string, data ...interface{}) { - warnMsg := fmt.Sprintf(msg, data...) - g.gethLogger.Warn("gorm", "warn message", warnMsg) -} - -func (g *gormLogger) Error(_ context.Context, msg string, data ...interface{}) { - errMsg := fmt.Sprintf(msg, data...) - g.gethLogger.Error("gorm", "err message", errMsg) -} - -func (g *gormLogger) Trace(_ context.Context, begin time.Time, fc func() (string, int64), err error) { - elapsed := time.Since(begin) - sql, rowsAffected := fc() - g.gethLogger.Debug("gorm", "line", utils.FileWithLineNum(), "cost", elapsed, "sql", sql, "rowsAffected", rowsAffected, "err", err) -} - -// InitDB init the db handler -func InitDB(config *config.DBConfig) (*gorm.DB, error) { - tmpGormLogger := gormLogger{ - gethLogger: log.Root(), - } - - db, err := gorm.Open(postgres.Open(config.DSN), &gorm.Config{ - Logger: &tmpGormLogger, - NowFunc: func() time.Time { - // why set time to UTC. - // if now set this, the inserted data time will use local timezone. like 2023-07-18 18:24:00 CST+8 - // but when inserted, store to postgres is 2023-07-18 18:24:00 UTC+0 the timezone is incorrect. - // As mysql dsn user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local, we cant set - // the timezone by loc=Local. but postgres's dsn don't have loc option to set timezone, so just need set the gorm option like that. - t, err := nowUTC() - if err != nil { - log.Error("Can not get UTC time: ", "err", err) - } - return t - }, - }) - if err != nil { - return nil, err - } - - sqlDB, pingErr := Ping(db) - if pingErr != nil { - return nil, pingErr - } - - sqlDB.SetMaxOpenConns(config.MaxOpenNum) - sqlDB.SetMaxIdleConns(config.MaxIdleNum) - - return db, nil -} - -// Ping check db status -func Ping(db *gorm.DB) (*sql.DB, error) { - sqlDB, err := db.DB() - if err != nil { - return nil, err - } - - if err = sqlDB.Ping(); err != nil { - return nil, err - } - return sqlDB, nil -} - -// CloseDB close the db handler. notice the db handler only can close when then program exit. -func CloseDB(db *gorm.DB) error { - sqlDB, err := db.DB() - if err != nil { - return err - } - if err := sqlDB.Close(); err != nil { - return err - } - return nil -} - -// nowUTC get the utc time.Now -func nowUTC() (time.Time, error) { - utc, err := time.LoadLocation("") - if err != nil { - return time.Time{}, err - } - return time.Now().In(utc), nil -} diff --git a/bridge-history-api/utils/flags.go b/bridge-history-api/utils/flags.go deleted file mode 100644 index 3e96c9e325..0000000000 --- a/bridge-history-api/utils/flags.go +++ /dev/null @@ -1,69 +0,0 @@ -package utils - -import ( - "github.com/urfave/cli/v2" -) - -var ( - // CommonFlags is used for app common flags in different modules - CommonFlags = []cli.Flag{ - &ConfigFileFlag, - &VerbosityFlag, - &LogFileFlag, - &LogJSONFormat, - &LogDebugFlag, - &MetricsEnabled, - &MetricsAddr, - &MetricsPort, - } - // ConfigFileFlag load json type config file. - ConfigFileFlag = cli.StringFlag{ - Name: "config", - Usage: "JSON configuration file", - Value: "./config.json", - } - // VerbosityFlag log level. - VerbosityFlag = cli.IntFlag{ - Name: "verbosity", - Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail", - Value: 3, - } - // LogFileFlag decides where the logger output is sent. If this flag is left - // empty, it will log to stdout. - LogFileFlag = cli.StringFlag{ - Name: "log.file", - Usage: "Tells the module where to write log entries", - } - // LogJSONFormat decides the log format is json or not - LogJSONFormat = cli.BoolFlag{ - Name: "log.json", - Usage: "Tells the module whether log format is json or not", - Value: true, - } - // LogDebugFlag make log messages with call-site location - LogDebugFlag = cli.BoolFlag{ - Name: "log.debug", - Usage: "Prepends log messages with call-site location (file and line number)", - } - // MetricsEnabled enable metrics collection and reporting - MetricsEnabled = cli.BoolFlag{ - Name: "metrics", - Usage: "Enable metrics collection and reporting", - Category: "METRICS", - Value: false, - } - // MetricsAddr is listening address of Metrics reporting server - MetricsAddr = cli.StringFlag{ - Name: "metrics.addr", - Usage: "Metrics reporting server listening address", - Category: "METRICS", - Value: "127.0.0.1", - } - // MetricsPort is listening port of Metrics reporting server - MetricsPort = cli.IntFlag{ - Name: "metrics.port", - Usage: "Metrics reporting server listening port", - Category: "METRICS", - Value: 6060, - } -) diff --git a/bridge-history-api/utils/logger.go b/bridge-history-api/utils/logger.go deleted file mode 100644 index 81ee32e486..0000000000 --- a/bridge-history-api/utils/logger.go +++ /dev/null @@ -1,43 +0,0 @@ -package utils - -import ( - "io" - "os" - "path/filepath" - - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" - "github.com/scroll-tech/go-ethereum/cmd/utils" - "github.com/scroll-tech/go-ethereum/log" - "github.com/urfave/cli/v2" -) - -// LogSetup is for setup logger -func LogSetup(ctx *cli.Context) error { - var ostream log.Handler - if logFile := ctx.String(LogFileFlag.Name); len(logFile) > 0 { - fp, err := os.OpenFile(filepath.Clean(logFile), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600) - if err != nil { - utils.Fatalf("Failed to open log file", "err", err) - } - if ctx.Bool(LogJSONFormat.Name) { - ostream = log.StreamHandler(io.Writer(fp), log.JSONFormat()) - } else { - ostream = log.StreamHandler(io.Writer(fp), log.TerminalFormat(true)) - } - } else { - output := io.Writer(os.Stderr) - usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb" - if usecolor { - output = colorable.NewColorableStderr() - } - ostream = log.StreamHandler(output, log.TerminalFormat(usecolor)) - } - // show the call file and line number - log.PrintOrigins(ctx.Bool(LogDebugFlag.Name)) - glogger := log.NewGlogHandler(ostream) - // Set log level - glogger.Verbosity(log.Lvl(ctx.Int(VerbosityFlag.Name))) - log.Root().SetHandler(glogger) - return nil -} diff --git a/bridge-history-api/utils/utils_test.go b/bridge-history-api/utils/utils_test.go deleted file mode 100644 index 2d7adabdfd..0000000000 --- a/bridge-history-api/utils/utils_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package utils_test - -import ( - "testing" - - "github.com/scroll-tech/go-ethereum/common" - "github.com/stretchr/testify/assert" - - "bridge-history-api/utils" -) - -func TestKeccak2(t *testing.T) { - a := common.HexToHash("0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0") - b := common.HexToHash("0x222ff5e0b5877792c2bc1670e2ccd0c2c97cd7bb1672a57d598db05092d3d72c") - c := utils.Keccak2(a, b) - assert.NotEmpty(t, c) - assert.NotEqual(t, a, c) - assert.NotEqual(t, b, c) - assert.Equal(t, "0xc0ffbd7f501bd3d49721b0724b2bff657cb2378f15d5a9b97cd7ea5bf630d512", c.Hex()) -} - -func TestGetBatchRangeFromCalldata(t *testing.T) { - // single chunk - start, finish, err := utils.GetBatchRangeFromCalldata(common.Hex2Bytes("1325aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003d0100000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000100000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000")) - assert.NoError(t, err) - assert.Equal(t, start, uint64(1)) - assert.Equal(t, finish, uint64(1)) - - // multiple chunk - start, finish, err = utils.GetBatchRangeFromCalldata(common.Hex2Bytes("1325aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000007900000000000000000100000000000000010000000000000001038433daac85a0b03cd443ed50bc85e832c883061651ae2182b2984751e0b340119b828c2a2798d2c957228ebeaff7e10bb099ae0d4e224f3eeb779ff61cba610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004c01000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000010000000001000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b403000000000000000b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000300000000000000000b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00050000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c01000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa800000000000000000000000000000000000000000000000000000000000000aa")) - assert.NoError(t, err) - assert.Equal(t, start, uint64(10)) - assert.Equal(t, finish, uint64(20)) - - // genesis batch - start, finish, err = utils.GetBatchRangeFromCalldata(common.Hex2Bytes("3fdeecb200000000000000000000000000000000000000000000000000000000000000402dcb5308098d24a37fc1487a229fcedb09fa4343ede39cbad365bc925535bb09000000000000000000000000000000000000000000000000000000000000005900000000000000000000000000000000000000000000000000c252bc9780c4d83cf11f14b8cd03c92c4d18ce07710ba836d31d12da216c8330000000000000000000000000000000000000000000000000000000000000000000000000000000")) - assert.NoError(t, err) - assert.Equal(t, start, uint64(0)) - assert.Equal(t, finish, uint64(0)) -}