diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7ea01174be..dda8f68f11 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -69,7 +69,7 @@ jobs: tags: scrolltech/rollup-relayer:${{github.ref_name}} # cache-from: type=gha,scope=${{ github.workflow }} # cache-to: type=gha,scope=${{ github.workflow }} - bridgehistoryapi-cross-msg-fetcher: + bridgehistoryapi-fetcher: runs-on: ubuntu-latest steps: - name: Checkout code @@ -81,16 +81,16 @@ jobs: with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push bridgehistoryapi-cross-msg-fetcher docker + - name: Build and push bridgehistoryapi-fetcher docker uses: docker/build-push-action@v2 with: context: . - file: ./build/dockerfiles/bridgehistoryapi-cross-msg-fetcher.Dockerfile + file: ./build/dockerfiles/bridgehistoryapi-fetcher.Dockerfile push: true - tags: scrolltech/bridgehistoryapi-cross-msg-fetcher:${{github.ref_name}} + tags: scrolltech/bridgehistoryapi-fetcher:${{github.ref_name}} # cache-from: type=gha,scope=${{ github.workflow }} # cache-to: type=gha,scope=${{ github.workflow }} - bridgehistoryapi-server: + bridgehistoryapi-api: runs-on: ubuntu-latest steps: - name: Checkout code @@ -102,13 +102,13 @@ jobs: with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push bridgehistoryapi-server docker + - name: Build and push bridgehistoryapi-api docker uses: docker/build-push-action@v2 with: context: . - file: ./build/dockerfiles/bridgehistoryapi-server.Dockerfile + file: ./build/dockerfiles/bridgehistoryapi-api.Dockerfile push: true - tags: scrolltech/bridgehistoryapi-server:${{github.ref_name}} + tags: scrolltech/bridgehistoryapi-api:${{github.ref_name}} # cache-from: type=gha,scope=${{ github.workflow }} # cache-to: type=gha,scope=${{ github.workflow }} coordinator-api: diff --git a/bridge-history-api/Makefile b/bridge-history-api/Makefile index 6f689a905d..3a90e47db5 100644 --- a/bridge-history-api/Makefile +++ b/bridge-history-api/Makefile @@ -17,14 +17,23 @@ bridgehistoryapi-fetcher: bridgehistoryapi-api: go build -o $(PWD)/build/bin/bridgehistoryapi-api ./cmd/api +redis-docker: + if docker ps -a -q -f name=bridgehistoryapi-redis | grep -q . ; then \ + docker stop bridgehistoryapi-redis; \ + docker rm bridgehistoryapi-redis; \ + fi + docker run --name bridgehistoryapi-redis -d -p 6379:6379 redis:latest + reset-db-docker: - -docker stop bridgehistoryapi-history-db - -docker rm bridgehistoryapi-history-db + if docker ps -a -q -f name=bridgehistoryapi-history-db | grep -q . ; then \ + docker stop bridgehistoryapi-history-db; \ + docker rm bridgehistoryapi-history-db; \ + fi docker run --name bridgehistoryapi-history-db -p 5444:5432 -e POSTGRES_PASSWORD=123456 -e POSTGRES_DB=test -d postgres go build -o $(PWD)/build/bin/bridgehistoryapi-db-cli ./cmd/db_cli & sleep 2 $(PWD)/build/bin/bridgehistoryapi-db-cli reset bridgehistoryapi-docker: - DOCKER_BUILDKIT=1 docker build -t scrolltech/bridgehistoryapi-cross-message-fetcher:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/bridgehistoryapi-cross-message-fetcher.Dockerfile - DOCKER_BUILDKIT=1 docker build -t scrolltech/bridgehistoryapi-server:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/bridgehistoryapi-server.Dockerfile + DOCKER_BUILDKIT=1 docker build -t scrolltech/bridgehistoryapi-fetcher:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/bridgehistoryapi-fetcher.Dockerfile + DOCKER_BUILDKIT=1 docker build -t scrolltech/bridgehistoryapi-api:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/bridgehistoryapi-api.Dockerfile DOCKER_BUILDKIT=1 docker build -t scrolltech/bridgehistoryapi-db-cli:${IMAGE_VERSION} ${REPO_ROOT_DIR}/ -f ${REPO_ROOT_DIR}/build/dockerfiles/bridgehistoryapi-db-cli.Dockerfile \ No newline at end of file diff --git a/bridge-history-api/README.md b/bridge-history-api/README.md index 4793ec301d..848c9b7546 100644 --- a/bridge-history-api/README.md +++ b/bridge-history-api/README.md @@ -14,30 +14,27 @@ Provide init, show version, rollback, check status services of DB ./build/bin/bridgehistoryapi-db-cli [command] ``` -### bridgehistoryapi-cross-msg-fetcher +### bridgehistoryapi-fetcher Fetch the transactions from both L1 and L2 ``` cd ./bridge-history-api - make bridgehistoryapi-cross-msg-fetcher - ./build/bin/bridgehistoryapi-cross-msg-fetcher + make bridgehistoryapi-fetcher + ./build/bin/bridgehistoryapi-fetcher ``` -### bridgehistoryapi-server +### bridgehistoryapi-api provides REST APIs. Please refer to the API details below. ``` cd ./bridge-history-api - make bridgehistoryapi-server - ./build/bin/bridgehistoryapi-server + make bridgehistoryapi-api + ./build/bin/bridgehistoryapi-api ``` -## APIs provided by bridgehistoryapi-server +## APIs provided by bridgehistoryapi-api -assume `bridgehistoryapi-server` listening on `https://localhost:8080` -can change this port thru modify `config.json` - -1. `/txs` +1. `/api/txs` ``` // @Summary get all txs under given address // @Accept plain @@ -49,7 +46,7 @@ can change this port thru modify `config.json` // @Router /api/txs [get] ``` -2. `/withdrawals` +2. `/api/l2/withdrawals` ``` // @Summary get all L2 withdrawals under given address // @Accept plain @@ -58,22 +55,22 @@ can change this port thru modify `config.json` // @Param page_size query int true "page size" // @Param page query int true "page" // @Success 200 -// @Router /api/withdrawals [get] +// @Router /api/l2/withdrawals [get] ``` -3. `/claimablewithdrawals` +3. `/api/l2/unclaimed/withdrawals` ``` -// @Summary get all L2 claimable withdrawals under given address +// @Summary get all L2 unclaimed withdrawals under given address // @Accept plain // @Produce plain // @Param address query string true "wallet address" // @Param page_size query int true "page size" // @Param page query int true "page" // @Success 200 -// @Router /api/claimablewithdrawals [get] +// @Router /api/l2/unclaimed/withdrawals [get] ``` -4. `/txsbyhashes` +4. `/api/txsbyhashes` ``` // @Summary get txs by given tx hashes // @Accept plain diff --git a/bridge-history-api/cmd/api/app/app.go b/bridge-history-api/cmd/api/app/app.go index fce7430d37..7c5e7e8aa3 100644 --- a/bridge-history-api/cmd/api/app/app.go +++ b/bridge-history-api/cmd/api/app/app.go @@ -28,8 +28,8 @@ func init() { app = cli.NewApp() app.Action = action - app.Name = "Scroll Bridge History Web Service" - app.Usage = "The Scroll Bridge History Web Service" + app.Name = "Scroll Bridge History API Web Service" + app.Usage = "The Scroll Bridge History API Web Service" app.Flags = append(app.Flags, utils.CommonFlags...) app.Commands = []*cli.Command{} @@ -66,7 +66,7 @@ func action(ctx *cli.Context) error { route.Route(router, cfg, registry) go func() { - port := utils.ServicePortFlag.Value + port := ctx.Int(utils.ServicePortFlag.Name) if runServerErr := router.Run(fmt.Sprintf(":%d", port)); runServerErr != nil { log.Crit("run http server failure", "error", runServerErr) } diff --git a/bridge-history-api/cmd/fetcher/app/app.go b/bridge-history-api/cmd/fetcher/app/app.go index e6ef6e5a3e..26af0bb3ae 100644 --- a/bridge-history-api/cmd/fetcher/app/app.go +++ b/bridge-history-api/cmd/fetcher/app/app.go @@ -67,13 +67,16 @@ func action(ctx *cli.Context) error { log.Crit("failed to connect to db", "config file", cfgFile, "error", err) } - l1MessageFetcher, err := fetcher.NewL1MessageFetcher(subCtx, cfg.L1, db, l1Client) + // syncInfo is used to store the shared info between L1 fetcher and L2 fetcher, e.g., the sync height. + syncInfo := &fetcher.SyncInfo{} + + l1MessageFetcher, err := fetcher.NewL1MessageFetcher(subCtx, cfg.L1, db, l1Client, syncInfo) if err != nil { log.Crit("failed to create L1 cross message fetcher", "error", err) } go l1MessageFetcher.Start() - l2MessageFetcher, err := fetcher.NewL2MessageFetcher(subCtx, cfg.L2, db, l2Client) + l2MessageFetcher, err := fetcher.NewL2MessageFetcher(subCtx, cfg.L2, db, l2Client, syncInfo) if err != nil { log.Crit("failed to create L2 cross message fetcher", "error", err) } diff --git a/bridge-history-api/internal/controller/api/history_controller.go b/bridge-history-api/internal/controller/api/history_controller.go index 521d63549e..c92cfb4690 100644 --- a/bridge-history-api/internal/controller/api/history_controller.go +++ b/bridge-history-api/internal/controller/api/history_controller.go @@ -23,15 +23,15 @@ func NewHistoryController(db *gorm.DB, redis *redis.Client) *HistoryController { } } -// GetL2ClaimableWithdrawalsByAddress defines the http get method behavior -func (c *HistoryController) GetL2ClaimableWithdrawalsByAddress(ctx *gin.Context) { +// GetL2UnclaimedWithdrawalsByAddress defines the http get method behavior +func (c *HistoryController) GetL2UnclaimedWithdrawalsByAddress(ctx *gin.Context) { var req types.QueryByAddressRequest if err := ctx.ShouldBind(&req); err != nil { types.RenderFailure(ctx, types.ErrParameterInvalidNo, err) return } - pagedTxs, total, err := c.historyLogic.GetL2ClaimableWithdrawalsByAddress(ctx, req.Address, req.Page, req.PageSize) + pagedTxs, total, err := c.historyLogic.GetL2UnclaimedWithdrawalsByAddress(ctx, req.Address, req.Page, req.PageSize) if err != nil { types.RenderFailure(ctx, types.ErrGetL2ClaimableWithdrawalsError, err) return diff --git a/bridge-history-api/internal/controller/fetcher/l1_fetcher.go b/bridge-history-api/internal/controller/fetcher/l1_fetcher.go index 9cfe9bee3f..6b19cf2fb0 100644 --- a/bridge-history-api/internal/controller/fetcher/l1_fetcher.go +++ b/bridge-history-api/internal/controller/fetcher/l1_fetcher.go @@ -28,10 +28,11 @@ type L1MessageFetcher struct { batchEventOrm *orm.BatchEvent client *ethclient.Client addressList []common.Address + syncInfo *SyncInfo } // NewL1MessageFetcher creates a new L1MessageFetcher instance. -func NewL1MessageFetcher(ctx context.Context, cfg *config.LayerConfig, db *gorm.DB, client *ethclient.Client) (*L1MessageFetcher, error) { +func NewL1MessageFetcher(ctx context.Context, cfg *config.LayerConfig, db *gorm.DB, client *ethclient.Client, syncInfo *SyncInfo) (*L1MessageFetcher, error) { addressList := []common.Address{ common.HexToAddress(cfg.ETHGatewayAddr), @@ -67,6 +68,7 @@ func NewL1MessageFetcher(ctx context.Context, cfg *config.LayerConfig, db *gorm. batchEventOrm: orm.NewBatchEvent(db), client: client, addressList: addressList, + syncInfo: syncInfo, }, nil } @@ -240,12 +242,12 @@ func (c *L1MessageFetcher) doFetchAndSaveEvents(ctx context.Context, from uint64 } func (c *L1MessageFetcher) updateBatchIndexAndStatus(ctx context.Context) error { - latestMessageHeight, err := c.crossMessageOrm.GetLatestFinalizedL2WithdrawalBlockHeight(ctx) - if err != nil { - log.Error("failed to get latest finalized L2 sent message block height", "error", err) - return err + l2ScannedHeight := c.syncInfo.GetL2ScanHeight() + if l2ScannedHeight == 0 { + log.Info("L2 fetcher has not successfully synced at least one round yet") + return nil } - batches, err := c.batchEventOrm.GetBatchesGEBlockHeight(ctx, latestMessageHeight+1) + batches, err := c.batchEventOrm.GetBatchesLEBlockHeight(ctx, l2ScannedHeight) if err != nil { log.Error("failed to get batches >= block height", "error", err) return err @@ -256,6 +258,10 @@ func (c *L1MessageFetcher) updateBatchIndexAndStatus(ctx context.Context) error log.Error("failed to update batch status of L2 sent messages", "start", batch.StartBlockNumber, "end", batch.EndBlockNumber, "index", batch.BatchIndex, "error", err) return err } + if err := c.batchEventOrm.UpdateBatchEventStatus(ctx, batch.BatchIndex); err != nil { + log.Error("failed to update batch event status as updated", "start", batch.StartBlockNumber, "end", batch.EndBlockNumber, "index", batch.BatchIndex, "error", err) + return err + } } return nil } diff --git a/bridge-history-api/internal/controller/fetcher/l2_fetcher.go b/bridge-history-api/internal/controller/fetcher/l2_fetcher.go index 47483e480f..dbbb417433 100644 --- a/bridge-history-api/internal/controller/fetcher/l2_fetcher.go +++ b/bridge-history-api/internal/controller/fetcher/l2_fetcher.go @@ -30,10 +30,11 @@ type L2MessageFetcher struct { crossMessageOrm *orm.CrossMessage client *ethclient.Client addressList []common.Address + syncInfo *SyncInfo } // NewL2MessageFetcher creates a new L2MessageFetcher instance. -func NewL2MessageFetcher(ctx context.Context, cfg *config.LayerConfig, db *gorm.DB, client *ethclient.Client) (*L2MessageFetcher, error) { +func NewL2MessageFetcher(ctx context.Context, cfg *config.LayerConfig, db *gorm.DB, client *ethclient.Client, syncInfo *SyncInfo) (*L2MessageFetcher, error) { addressList := []common.Address{ common.HexToAddress(cfg.ETHGatewayAddr), @@ -64,6 +65,7 @@ func NewL2MessageFetcher(ctx context.Context, cfg *config.LayerConfig, db *gorm. crossMessageOrm: orm.NewCrossMessage(db), client: client, addressList: addressList, + syncInfo: syncInfo, }, nil } @@ -111,6 +113,7 @@ func (c *L2MessageFetcher) fetchAndSaveEvents(confirmation uint64) { log.Error("failed to fetch and save L2 events", "from", from, "to", to, "err", err) return } + c.syncInfo.SetL2ScanHeight(to) } } @@ -168,7 +171,7 @@ func (c *L2MessageFetcher) doFetchAndSaveEvents(ctx context.Context, from uint64 // Check if the transaction failed if receipt.Status == types.ReceiptStatusFailed { l2RevertedRelayedMessages = append(l2RevertedRelayedMessages, &orm.CrossMessage{ - MessageHash: common.Bytes2Hex(crypto.Keccak256(tx.AsL1MessageTx().Data)), + MessageHash: "0x" + common.Bytes2Hex(crypto.Keccak256(tx.AsL1MessageTx().Data)), L2TxHash: tx.Hash().String(), TxStatus: int(orm.TxStatusTypeRelayedFailed), L2BlockNumber: receipt.BlockNumber.Uint64(), diff --git a/bridge-history-api/internal/controller/fetcher/sync.go b/bridge-history-api/internal/controller/fetcher/sync.go new file mode 100644 index 0000000000..8fdfa23256 --- /dev/null +++ b/bridge-history-api/internal/controller/fetcher/sync.go @@ -0,0 +1,18 @@ +package fetcher + +import "sync/atomic" + +// SyncInfo is a struct that stores synchronization information shared between L1 fetcher and L2 fetcher. +type SyncInfo struct { + l2ScanHeight uint64 +} + +// SetL2ScanHeight is a method that sets the value of l2ScanHeight in SyncInfo. +func (s *SyncInfo) SetL2ScanHeight(height uint64) { + atomic.StoreUint64(&s.l2ScanHeight, height) +} + +// GetL2ScanHeight is a method that retrieves the value of l2ScanHeight in SyncInfo. +func (s *SyncInfo) GetL2ScanHeight() uint64 { + return atomic.LoadUint64(&s.l2ScanHeight) +} diff --git a/bridge-history-api/internal/logic/history_logic.go b/bridge-history-api/internal/logic/history_logic.go index 6c7a1866fa..e3ffe4c723 100644 --- a/bridge-history-api/internal/logic/history_logic.go +++ b/bridge-history-api/internal/logic/history_logic.go @@ -46,8 +46,8 @@ func NewHistoryLogic(db *gorm.DB, redis *redis.Client) *HistoryLogic { return logic } -// GetL2ClaimableWithdrawalsByAddress gets all claimable withdrawal txs under given address. -func (h *HistoryLogic) GetL2ClaimableWithdrawalsByAddress(ctx context.Context, address string, page, pageSize uint64) ([]*types.TxHistoryInfo, uint64, error) { +// GetL2UnclaimedWithdrawalsByAddress gets all unclaimed withdrawal txs under given address. +func (h *HistoryLogic) GetL2UnclaimedWithdrawalsByAddress(ctx context.Context, address string, page, pageSize uint64) ([]*types.TxHistoryInfo, uint64, error) { cacheKey := cacheKeyPrefixL2ClaimableWithdrawalsByAddr + address pagedTxs, total, isHit, err := h.getCachedTxsInfo(ctx, cacheKey, page, pageSize) if err != nil { @@ -56,17 +56,17 @@ func (h *HistoryLogic) GetL2ClaimableWithdrawalsByAddress(ctx context.Context, a } if isHit { - h.cacheMetrics.cacheHits.WithLabelValues("GetL2ClaimableWithdrawalsByAddress").Inc() + h.cacheMetrics.cacheHits.WithLabelValues("GetL2UnclaimedWithdrawalsByAddress").Inc() log.Info("cache hit", "cache key", cacheKey) return pagedTxs, total, nil } - h.cacheMetrics.cacheMisses.WithLabelValues("GetL2ClaimableWithdrawalsByAddress").Inc() + h.cacheMetrics.cacheMisses.WithLabelValues("GetL2UnclaimedWithdrawalsByAddress").Inc() log.Info("cache miss", "cache key", cacheKey) result, err, _ := h.singleFlight.Do(cacheKey, func() (interface{}, error) { var messages []*orm.CrossMessage - messages, err = h.crossMessageOrm.GetL2ClaimableWithdrawalsByAddress(ctx, address) + messages, err = h.crossMessageOrm.GetL2UnclaimedWithdrawalsByAddress(ctx, address) if err != nil { return nil, err } @@ -278,6 +278,7 @@ func getTxHistoryInfo(message *orm.CrossMessage) *types.TxHistoryInfo { Message: message.MessageData, Proof: common.Bytes2Hex(message.MerkleProof), BatchIndex: strconv.FormatUint(message.BatchIndex, 10), + Claimable: true, } } } @@ -285,29 +286,34 @@ func getTxHistoryInfo(message *orm.CrossMessage) *types.TxHistoryInfo { } func (h *HistoryLogic) getCachedTxsInfo(ctx context.Context, cacheKey string, pageNum, pageSize uint64) ([]*types.TxHistoryInfo, uint64, bool, error) { - start := int64(pageNum * pageSize) - end := int64((pageNum+1)*pageSize - 1) + start := int64((pageNum - 1) * pageSize) + end := start + int64(pageSize) total, err := h.redis.ZCard(ctx, cacheKey).Result() if err != nil { - if err == redis.Nil { - // Key does not exist, cache miss. - return nil, 0, false, nil - } log.Error("failed to get zcard result", "error", err) return nil, 0, false, err } + if total == 0 { + return nil, 0, false, nil + } + values, err := h.redis.ZRange(ctx, cacheKey, start, end).Result() if err != nil { - if err == redis.Nil { - // Key does not exist, cache miss. - return nil, 0, false, nil - } log.Error("failed to get zrange result", "error", err) return nil, 0, false, err } + if len(values) == 0 { + return nil, 0, false, nil + } + + // check if it's empty place holder. + if len(values) == 1 && values[0] == "empty_page" { + return nil, 0, true, nil + } + var pagedTxs []*types.TxHistoryInfo for _, v := range values { var tx types.TxHistoryInfo @@ -323,12 +329,24 @@ func (h *HistoryLogic) getCachedTxsInfo(ctx context.Context, cacheKey string, pa func (h *HistoryLogic) cacheTxsInfo(ctx context.Context, cacheKey string, txs []*types.TxHistoryInfo) error { _, err := h.redis.TxPipelined(ctx, func(pipe redis.Pipeliner) error { - // The transactions are sorted, thus we set the score as their indices. - for i, tx := range txs { - if err := pipe.ZAdd(ctx, cacheKey, &redis.Z{Score: float64(i), Member: tx}).Err(); err != nil { - log.Error("failed to add transaction to sorted set", "error", err) + if len(txs) == 0 { + if err := pipe.ZAdd(ctx, cacheKey, &redis.Z{Score: 0, Member: "empty_page"}).Err(); err != nil { + log.Error("failed to add empty page indicator to sorted set", "error", err) return err } + } else { + // The transactions are sorted, thus we set the score as their indices. + for i, tx := range txs { + txBytes, err := json.Marshal(tx) + if err != nil { + log.Error("failed to marshal transaction to json", "error", err) + return err + } + if err := pipe.ZAdd(ctx, cacheKey, &redis.Z{Score: float64(i), Member: txBytes}).Err(); err != nil { + log.Error("failed to add transaction to sorted set", "error", err) + return err + } + } } if err := pipe.Expire(ctx, cacheKey, cacheKeyExpiredTime).Err(); err != nil { log.Error("failed to set expiry time", "error", err) diff --git a/bridge-history-api/internal/logic/watcher_event_parser.go b/bridge-history-api/internal/logic/watcher_event_parser.go index a26d212cf9..e986eadb95 100644 --- a/bridge-history-api/internal/logic/watcher_event_parser.go +++ b/bridge-history-api/internal/logic/watcher_event_parser.go @@ -28,15 +28,10 @@ func ParseL1CrossChainEventLogs(ctx context.Context, logs []types.Log, blockTime return nil, nil, err } lastMessage := l1DepositMessages[len(l1DepositMessages)-1] - lastMessage.L1BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeETH) - lastMessage.L1TxHash = vlog.TxHash.String() lastMessage.TokenAmounts = event.Amount.String() - lastMessage.MessageType = int(orm.MessageTypeL1SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L1DepositERC20Sig: event := backendabi.ERC20MessageEvent{} err := utils.UnpackLog(backendabi.IL1ERC20GatewayABI, &event, "DepositERC20", vlog) @@ -45,17 +40,12 @@ func ParseL1CrossChainEventLogs(ctx context.Context, logs []types.Log, blockTime return nil, nil, err } lastMessage := l1DepositMessages[len(l1DepositMessages)-1] - lastMessage.L1BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC20) - lastMessage.L1TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenAmounts = event.Amount.String() - lastMessage.MessageType = int(orm.MessageTypeL1SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L1DepositERC721Sig: event := backendabi.ERC721MessageEvent{} if err := utils.UnpackLog(backendabi.IL1ERC721GatewayABI, &event, "DepositERC721", vlog); err != nil { @@ -63,17 +53,12 @@ func ParseL1CrossChainEventLogs(ctx context.Context, logs []types.Log, blockTime return nil, nil, err } lastMessage := l1DepositMessages[len(l1DepositMessages)-1] - lastMessage.L1BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC721) - lastMessage.L1TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenIDs = event.TokenID.String() - lastMessage.MessageType = int(orm.MessageTypeL1SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L1BatchDepositERC721Sig: event := backendabi.BatchERC721MessageEvent{} if err := utils.UnpackLog(backendabi.IL1ERC721GatewayABI, &event, "BatchDepositERC721", vlog); err != nil { @@ -81,17 +66,12 @@ func ParseL1CrossChainEventLogs(ctx context.Context, logs []types.Log, blockTime return nil, nil, err } lastMessage := l1DepositMessages[len(l1DepositMessages)-1] - lastMessage.L1BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC721) - lastMessage.L1TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenIDs = convertBigIntArrayToString(event.TokenIDs) - lastMessage.MessageType = int(orm.MessageTypeL1SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L1DepositERC1155Sig: event := backendabi.ERC1155MessageEvent{} if err := utils.UnpackLog(backendabi.IL1ERC1155GatewayABI, &event, "DepositERC1155", vlog); err != nil { @@ -99,18 +79,13 @@ func ParseL1CrossChainEventLogs(ctx context.Context, logs []types.Log, blockTime return nil, nil, err } lastMessage := l1DepositMessages[len(l1DepositMessages)-1] - lastMessage.L1BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC1155) - lastMessage.L1TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenIDs = event.TokenID.String() lastMessage.TokenAmounts = event.Amount.String() - lastMessage.MessageType = int(orm.MessageTypeL1SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L1BatchDepositERC1155Sig: event := backendabi.BatchERC1155MessageEvent{} if err := utils.UnpackLog(backendabi.IL1ERC1155GatewayABI, &event, "BatchDepositERC1155", vlog); err != nil { @@ -118,18 +93,13 @@ func ParseL1CrossChainEventLogs(ctx context.Context, logs []types.Log, blockTime return nil, nil, err } lastMessage := l1DepositMessages[len(l1DepositMessages)-1] - lastMessage.L1BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC1155) - lastMessage.L1TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenIDs = convertBigIntArrayToString(event.TokenIDs) lastMessage.TokenAmounts = convertBigIntArrayToString(event.TokenAmounts) - lastMessage.MessageType = int(orm.MessageTypeL1SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L1SentMessageEventSig: event := backendabi.L1SentMessageEvent{} if err := utils.UnpackLog(backendabi.IL1ScrollMessengerABI, &event, "SentMessage", vlog); err != nil { @@ -139,15 +109,17 @@ func ParseL1CrossChainEventLogs(ctx context.Context, logs []types.Log, blockTime // Use this messageHash as next deposit event's messageHash messageHash := utils.ComputeMessageHash(event.Sender, event.Target, event.Value, event.MessageNonce, event.Message).String() l1DepositMessages = append(l1DepositMessages, &orm.CrossMessage{ - L1BlockNumber: vlog.BlockNumber, - Sender: event.Sender.String(), - Receiver: event.Target.String(), - TokenType: int(orm.TokenTypeETH), - L1TxHash: vlog.TxHash.String(), - TokenAmounts: event.Value.String(), - MessageNonce: event.MessageNonce.Uint64(), - MessageType: int(orm.MessageTypeL1SentMessage), - MessageHash: messageHash, + L1BlockNumber: vlog.BlockNumber, + Sender: event.Sender.String(), + Receiver: event.Target.String(), + TokenType: int(orm.TokenTypeETH), + L1TxHash: vlog.TxHash.String(), + TokenAmounts: event.Value.String(), + MessageNonce: event.MessageNonce.Uint64(), + MessageType: int(orm.MessageTypeL1SentMessage), + TxStatus: int(orm.TxStatusTypeSent), + BlockTimestamp: blockTimestampsMap[vlog.BlockNumber], + MessageHash: messageHash, }) case backendabi.L1RelayedMessageEventSig: event := backendabi.L1RelayedMessageEvent{} @@ -293,15 +265,10 @@ func ParseL2EventLogs(logs []types.Log, blockTimestampsMap map[uint64]uint64) ([ return nil, nil, err } lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1] - lastMessage.L2BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeETH) - lastMessage.L2TxHash = vlog.TxHash.String() lastMessage.TokenAmounts = event.Amount.String() - lastMessage.MessageType = int(orm.MessageTypeL2SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L2WithdrawERC20Sig: event := backendabi.ERC20MessageEvent{} err := utils.UnpackLog(backendabi.IL2ERC20GatewayABI, &event, "WithdrawERC20", vlog) @@ -310,17 +277,12 @@ func ParseL2EventLogs(logs []types.Log, blockTimestampsMap map[uint64]uint64) ([ return nil, nil, err } lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1] - lastMessage.L2BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC20) - lastMessage.L2TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenAmounts = event.Amount.String() - lastMessage.MessageType = int(orm.MessageTypeL2SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L2WithdrawERC721Sig: event := backendabi.ERC721MessageEvent{} err := utils.UnpackLog(backendabi.IL2ERC721GatewayABI, &event, "WithdrawERC721", vlog) @@ -329,17 +291,12 @@ func ParseL2EventLogs(logs []types.Log, blockTimestampsMap map[uint64]uint64) ([ return nil, nil, err } lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1] - lastMessage.L2BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC721) - lastMessage.L2TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenIDs = event.TokenID.String() - lastMessage.MessageType = int(orm.MessageTypeL2SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L2BatchWithdrawERC721Sig: event := backendabi.BatchERC721MessageEvent{} err := utils.UnpackLog(backendabi.IL2ERC721GatewayABI, &event, "BatchWithdrawERC721", vlog) @@ -348,17 +305,12 @@ func ParseL2EventLogs(logs []types.Log, blockTimestampsMap map[uint64]uint64) ([ return nil, nil, err } lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1] - lastMessage.L2BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC721) - lastMessage.L2TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenIDs = convertBigIntArrayToString(event.TokenIDs) - lastMessage.MessageType = int(orm.MessageTypeL2SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L2WithdrawERC1155Sig: event := backendabi.ERC1155MessageEvent{} err := utils.UnpackLog(backendabi.IL2ERC1155GatewayABI, &event, "WithdrawERC1155", vlog) @@ -367,18 +319,13 @@ func ParseL2EventLogs(logs []types.Log, blockTimestampsMap map[uint64]uint64) ([ return nil, nil, err } lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1] - lastMessage.L2BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC1155) - lastMessage.L2TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenIDs = event.TokenID.String() lastMessage.TokenAmounts = event.Amount.String() - lastMessage.MessageType = int(orm.MessageTypeL2SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L2BatchWithdrawERC1155Sig: event := backendabi.BatchERC1155MessageEvent{} err := utils.UnpackLog(backendabi.IL2ERC1155GatewayABI, &event, "BatchWithdrawERC1155", vlog) @@ -387,18 +334,13 @@ func ParseL2EventLogs(logs []types.Log, blockTimestampsMap map[uint64]uint64) ([ return nil, nil, err } lastMessage := l2WithdrawMessages[len(l2WithdrawMessages)-1] - lastMessage.L2BlockNumber = vlog.BlockNumber lastMessage.Sender = event.From.String() lastMessage.Receiver = event.To.String() lastMessage.TokenType = int(orm.TokenTypeERC1155) - lastMessage.L2TxHash = vlog.TxHash.String() lastMessage.L1TokenAddress = event.L1Token.String() lastMessage.L2TokenAddress = event.L2Token.String() lastMessage.TokenIDs = convertBigIntArrayToString(event.TokenIDs) lastMessage.TokenAmounts = convertBigIntArrayToString(event.TokenAmounts) - lastMessage.MessageType = int(orm.MessageTypeL2SentMessage) - lastMessage.TxStatus = int(orm.TxStatusTypeSent) - lastMessage.BlockTimestamp = blockTimestampsMap[vlog.BlockNumber] case backendabi.L2SentMessageEventSig: event := backendabi.L2SentMessageEvent{} err := utils.UnpackLog(backendabi.IL2ScrollMessengerABI, &event, "SentMessage", vlog) @@ -409,17 +351,21 @@ func ParseL2EventLogs(logs []types.Log, blockTimestampsMap map[uint64]uint64) ([ // Use this messageHash as next deposit event's messageHash messageHash := utils.ComputeMessageHash(event.Sender, event.Target, event.Value, event.MessageNonce, event.Message) l2WithdrawMessages = append(l2WithdrawMessages, &orm.CrossMessage{ - MessageHash: messageHash.String(), - Sender: event.Sender.String(), - Receiver: event.Target.String(), - TokenType: int(orm.TokenTypeETH), - L2TxHash: vlog.TxHash.String(), - TokenAmounts: event.Value.String(), - MessageFrom: event.Sender.String(), - MessageTo: event.Target.String(), - MessageValue: event.Value.String(), - MessageNonce: event.MessageNonce.Uint64(), - MessageData: hexutil.Encode(event.Message), + MessageHash: messageHash.String(), + Sender: event.Sender.String(), + Receiver: event.Target.String(), + TokenType: int(orm.TokenTypeETH), + L2TxHash: vlog.TxHash.String(), + TokenAmounts: event.Value.String(), + MessageFrom: event.Sender.String(), + MessageTo: event.Target.String(), + MessageValue: event.Value.String(), + MessageNonce: event.MessageNonce.Uint64(), + MessageData: hexutil.Encode(event.Message), + MessageType: int(orm.MessageTypeL2SentMessage), + TxStatus: int(orm.TxStatusTypeSent), + BlockTimestamp: blockTimestampsMap[vlog.BlockNumber], + L2BlockNumber: vlog.BlockNumber, }) case backendabi.L2RelayedMessageEventSig: event := backendabi.L2RelayedMessageEvent{} diff --git a/bridge-history-api/internal/orm/batch_event.go b/bridge-history-api/internal/orm/batch_event.go index 47022ff344..8db63be702 100644 --- a/bridge-history-api/internal/orm/batch_event.go +++ b/bridge-history-api/internal/orm/batch_event.go @@ -19,6 +19,15 @@ const ( BatchStatusTypeFinalized ) +// UpdateStatusType represents the whether batch info is updated in message table. +type UpdateStatusType int + +// Constants for UpdateStatusType. +const ( + UpdateStatusTypeUnupdated UpdateStatusType = iota + UpdateStatusTypeUpdated +) + // BatchEvent represents a batch event. type BatchEvent struct { db *gorm.DB `gorm:"column:-"` @@ -29,6 +38,7 @@ type BatchEvent struct { BatchHash string `json:"batch_hash" gorm:"column:batch_hash"` StartBlockNumber uint64 `json:"start_block_number" gorm:"column:start_block_number"` EndBlockNumber uint64 `json:"end_block_number" gorm:"column:end_block_number"` + UpdateStatus int `json:"update_status" gorm:"column:update_status"` CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"` DeletedAt *time.Time `json:"deleted_at" gorm:"column:deleted_at"` @@ -44,12 +54,13 @@ func NewBatchEvent(db *gorm.DB) *BatchEvent { return &BatchEvent{db: db} } -// GetBatchesGEBlockHeight returns the batches with end block >= given block height in db. -func (c *BatchEvent) GetBatchesGEBlockHeight(ctx context.Context, blockHeight uint64) ([]*BatchEvent, error) { +// GetBatchesLEBlockHeight returns the batches with end block <= given block height in db. +func (c *BatchEvent) GetBatchesLEBlockHeight(ctx context.Context, blockHeight uint64) ([]*BatchEvent, error) { var batches []*BatchEvent db := c.db.WithContext(ctx) db = db.Model(&BatchEvent{}) - db = db.Where("end_block_number >= ?", blockHeight) + db = db.Where("end_block_number <= ?", blockHeight) + db = db.Where("update_status = ?", UpdateStatusTypeUnupdated) db = db.Order("batch_index asc") if err := db.Find(&batches).Error; err != nil { if err == gorm.ErrRecordNotFound { @@ -97,3 +108,17 @@ func (c *BatchEvent) InsertOrUpdateBatchEvents(ctx context.Context, l1BatchEvent } return nil } + +// UpdateBatchEventStatus updates the UpdateStatusType of a BatchEvent given its batch index. +func (c *BatchEvent) UpdateBatchEventStatus(ctx context.Context, batchIndex uint64) error { + db := c.db.WithContext(ctx) + db = db.Model(&BatchEvent{}) + db = db.Where("batch_index = ?", batchIndex) + updateFields := map[string]interface{}{ + "update_status": UpdateStatusTypeUpdated, + } + if err := db.Updates(updateFields).Error; err != nil { + return fmt.Errorf("failed to update batch event status, batchIndex: %d, error: %w", batchIndex, err) + } + return nil +} diff --git a/bridge-history-api/internal/orm/cross_message.go b/bridge-history-api/internal/orm/cross_message.go index aca6edfca4..1c1e70c72c 100644 --- a/bridge-history-api/internal/orm/cross_message.go +++ b/bridge-history-api/internal/orm/cross_message.go @@ -162,46 +162,27 @@ func (c *CrossMessage) GetLatestL2Withdrawal(ctx context.Context) (*CrossMessage return &message, nil } -// GetLatestFinalizedL2WithdrawalBlockHeight returns the latest finalized L2 sent message block height from the database. -func (c *CrossMessage) GetLatestFinalizedL2WithdrawalBlockHeight(ctx context.Context) (uint64, error) { - var message CrossMessage - db := c.db.WithContext(ctx) - db = db.Model(&CrossMessage{}) - db = db.Where("message_type = ?", MessageTypeL2SentMessage) - db = db.Where("rollup_status", RollupStatusTypeFinalized) - db = db.Where("tx_status != ?", TxStatusTypeSentFailed) - db = db.Order("message_nonce desc") - if err := db.First(&message).Error; err != nil { - if err == gorm.ErrRecordNotFound { - return 0, nil - } - return 0, fmt.Errorf("failed to get latest L2 sent message event, error: %w", err) - } - return message.L2BlockNumber, nil -} - // GetMessagesByTxHashes retrieves all cross messages from the database that match the provided transaction hashes. func (c *CrossMessage) GetMessagesByTxHashes(ctx context.Context, txHashes []string) ([]*CrossMessage, error) { var messages []*CrossMessage db := c.db.WithContext(ctx) db = db.Model(&CrossMessage{}) - db = db.Where("l1_tx_hash IN (?) OR l2_tx_hash IN (?)", txHashes, txHashes) + db = db.Where("l1_tx_hash in (?) or l2_tx_hash in (?)", txHashes, txHashes) if err := db.Find(&messages).Error; err != nil { return nil, fmt.Errorf("failed to get L2 messages by tx hashes, tx hashes: %v, error: %w", txHashes, err) } return messages, nil } -// GetL2ClaimableWithdrawalsByAddress retrieves all L2 claimable withdrawal messages for a given sender address. -func (c *CrossMessage) GetL2ClaimableWithdrawalsByAddress(ctx context.Context, sender string) ([]*CrossMessage, error) { +// GetL2UnclaimedWithdrawalsByAddress retrieves all L2 unclaimed withdrawal messages for a given sender address. +func (c *CrossMessage) GetL2UnclaimedWithdrawalsByAddress(ctx context.Context, sender string) ([]*CrossMessage, error) { var messages []*CrossMessage db := c.db.WithContext(ctx) db = db.Model(&CrossMessage{}) db = db.Where("message_type = ?", MessageTypeL2SentMessage) db = db.Where("tx_status = ?", TxStatusTypeSent) - db = db.Where("rollup_status = ?", RollupStatusTypeFinalized) db = db.Where("sender = ?", sender) - db = db.Order("block_timestamp DESC") + db = db.Order("block_timestamp desc") db = db.Limit(500) if err := db.Find(&messages).Error; err != nil { return nil, fmt.Errorf("failed to get L2 claimable withdrawal messages by sender address, sender: %v, error: %w", sender, err) @@ -216,7 +197,7 @@ func (c *CrossMessage) GetL2WithdrawalsByAddress(ctx context.Context, sender str db = db.Model(&CrossMessage{}) db = db.Where("message_type = ?", MessageTypeL2SentMessage) db = db.Where("sender = ?", sender) - db = db.Order("block_timestamp DESC") + db = db.Order("block_timestamp desc") db = db.Limit(500) if err := db.Find(&messages).Error; err != nil { return nil, fmt.Errorf("failed to get L2 withdrawal messages by sender address, sender: %v, error: %w", sender, err) @@ -230,7 +211,7 @@ func (c *CrossMessage) GetTxsByAddress(ctx context.Context, sender string) ([]*C db := c.db.WithContext(ctx) db = db.Model(&CrossMessage{}) db = db.Where("sender = ?", sender) - db = db.Order("block_timestamp DESC") + db = db.Order("block_timestamp desc") db = db.Limit(500) if err := db.Find(&messages).Error; err != nil { return nil, fmt.Errorf("failed to get all txs by sender address, sender: %v, error: %w", sender, err) diff --git a/bridge-history-api/internal/orm/migrate/migrations/00002_batch_event.sql b/bridge-history-api/internal/orm/migrate/migrations/00002_batch_event.sql index 988f380cbe..ca4378b72a 100644 --- a/bridge-history-api/internal/orm/migrate/migrations/00002_batch_event.sql +++ b/bridge-history-api/internal/orm/migrate/migrations/00002_batch_event.sql @@ -8,6 +8,7 @@ create table batch_event batch_hash VARCHAR NOT NULL, start_block_number BIGINT NOT NULL, end_block_number BIGINT NOT NULL, + update_status SMALLINT NOT NULL, created_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP(0) DEFAULT NULL diff --git a/bridge-history-api/internal/route/route.go b/bridge-history-api/internal/route/route.go index 90650095ee..9123d6ca48 100644 --- a/bridge-history-api/internal/route/route.go +++ b/bridge-history-api/internal/route/route.go @@ -28,8 +28,8 @@ func Route(router *gin.Engine, conf *config.Config, reg prometheus.Registerer) { r := router.Group("api/") r.GET("/txs", api.HistoryCtrler.GetTxsByAddress) - r.GET("/withdrawals", api.HistoryCtrler.GetL2WithdrawalsByAddress) - r.GET("/claimablewithdrawals", api.HistoryCtrler.GetL2ClaimableWithdrawalsByAddress) + r.GET("/l2/withdrawals", api.HistoryCtrler.GetL2WithdrawalsByAddress) + r.GET("/l2/unclaimed/withdrawals", api.HistoryCtrler.GetL2UnclaimedWithdrawalsByAddress) 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 48032d1ab6..dc19fc99cc 100644 --- a/bridge-history-api/internal/types/types.go +++ b/bridge-history-api/internal/types/types.go @@ -27,7 +27,7 @@ const ( // QueryByAddressRequest the request parameter of address api type QueryByAddressRequest struct { Address string `form:"address" binding:"required"` - Page uint64 `form:"page" binding:"required"` + Page uint64 `form:"page" binding:"required,min=1"` PageSize uint64 `form:"page_size" binding:"required,min=1,max=100"` } diff --git a/build/dockerfiles/bridgehistoryapi-api.Dockerfile b/build/dockerfiles/bridgehistoryapi-api.Dockerfile new file mode 100644 index 0000000000..161d9b1414 --- /dev/null +++ b/build/dockerfiles/bridgehistoryapi-api.Dockerfile @@ -0,0 +1,21 @@ +# Download Go dependencies +FROM golang:1.20-alpine3.16 as base + +WORKDIR /src +COPY go.mod* ./ +COPY ./bridge-history-api/go.* ./ +RUN go mod download -x + +# Build bridgehistoryapi-api +FROM base as builder + +RUN --mount=target=. \ + --mount=type=cache,target=/root/.cache/go-build \ + cd /src/bridge-history-api/cmd/api && go build -v -p 4 -o /bin/bridgehistoryapi-api + +# Pull bridgehistoryapi-api into a second stage deploy alpine container +FROM alpine:latest + +COPY --from=builder /bin/bridgehistoryapi-api /bin/ + +ENTRYPOINT ["bridgehistoryapi-api"] \ No newline at end of file diff --git a/build/dockerfiles/bridgehistoryapi-cross-msg-fetcher.Dockerfile b/build/dockerfiles/bridgehistoryapi-cross-msg-fetcher.Dockerfile deleted file mode 100644 index d5087a8a4b..0000000000 --- a/build/dockerfiles/bridgehistoryapi-cross-msg-fetcher.Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# Download Go dependencies -FROM golang:1.20-alpine3.16 as base - -WORKDIR /src -COPY go.mod* ./ -COPY ./bridge-history-api/go.* ./ -RUN go mod download -x - -# Build bridgehistoryapi-cross-msg-fetcher -FROM base as builder - -RUN --mount=target=. \ - --mount=type=cache,target=/root/.cache/go-build \ - cd /src/bridge-history-api/cmd/cross_msg_fetcher && go build -v -p 4 -o /bin/bridgehistoryapi-cross-msg-fetcher - -# Pull bridgehistoryapi-cross-msg-fetcher into a second stage deploy alpine container -FROM alpine:latest - -COPY --from=builder /bin/bridgehistoryapi-cross-msg-fetcher /bin/ - -ENTRYPOINT ["bridgehistoryapi-cross-msg-fetcher"] \ No newline at end of file diff --git a/build/dockerfiles/bridgehistoryapi-fetcher.Dockerfile b/build/dockerfiles/bridgehistoryapi-fetcher.Dockerfile new file mode 100644 index 0000000000..7819cd18f6 --- /dev/null +++ b/build/dockerfiles/bridgehistoryapi-fetcher.Dockerfile @@ -0,0 +1,21 @@ +# Download Go dependencies +FROM golang:1.20-alpine3.16 as base + +WORKDIR /src +COPY go.mod* ./ +COPY ./bridge-history-api/go.* ./ +RUN go mod download -x + +# Build bridgehistoryapi-fetcher +FROM base as builder + +RUN --mount=target=. \ + --mount=type=cache,target=/root/.cache/go-build \ + cd /src/bridge-history-api/cmd/fetcher && go build -v -p 4 -o /bin/bridgehistoryapi-fetcher + +# Pull bridgehistoryapi-fetcher into a second stage deploy alpine container +FROM alpine:latest + +COPY --from=builder /bin/bridgehistoryapi-fetcher /bin/ + +ENTRYPOINT ["bridgehistoryapi-fetcher"] \ No newline at end of file diff --git a/build/dockerfiles/bridgehistoryapi-server.Dockerfile b/build/dockerfiles/bridgehistoryapi-server.Dockerfile deleted file mode 100644 index 7026eec7eb..0000000000 --- a/build/dockerfiles/bridgehistoryapi-server.Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# Download Go dependencies -FROM golang:1.20-alpine3.16 as base - -WORKDIR /src -COPY go.mod* ./ -COPY ./bridge-history-api/go.* ./ -RUN go mod download -x - -# Build bridgehistoryapi-server -FROM base as builder - -RUN --mount=target=. \ - --mount=type=cache,target=/root/.cache/go-build \ - cd /src/bridge-history-api/cmd/backend_server && go build -v -p 4 -o /bin/bridgehistoryapi-server - -# Pull bridgehistoryapi-server into a second stage deploy alpine container -FROM alpine:latest - -COPY --from=builder /bin/bridgehistoryapi-server /bin/ - -ENTRYPOINT ["bridgehistoryapi-server"] \ No newline at end of file