diff --git a/api/api.go b/api/api.go index a67dfd3..4e70acc 100644 --- a/api/api.go +++ b/api/api.go @@ -27,19 +27,28 @@ func MustInit(client *web3go.Client, store *store.MysqlStore) { var charge struct { Erc20TokenAddress string + Symbol string + Decimals uint8 } viperUtil.MustUnmarshalKey("charge", &charge) - name, symbol, decimals, err := nhContract.TokenInfo(client, charge.Erc20TokenAddress) - if err != nil { - logrus.WithError(err).Fatal("Get erc20 token info") - } - - chargeToken = &TokenInfo{ - Address: charge.Erc20TokenAddress, - Name: name, - Symbol: symbol, - Decimals: decimals, + if charge.Erc20TokenAddress != "" { + name, symbol, decimals, err := nhContract.TokenInfo(client, charge.Erc20TokenAddress) + if err != nil { + logrus.WithError(err).Fatal("Get erc20 token info") + } + chargeToken = &TokenInfo{ + Address: charge.Erc20TokenAddress, + Name: name, + Symbol: symbol, + Decimals: decimals, + } + } else { + chargeToken = &TokenInfo{ + Symbol: charge.Symbol, + Decimals: charge.Decimals, + } + chargeToken.Native = true } var flow struct { @@ -49,7 +58,7 @@ func MustInit(client *web3go.Client, store *store.MysqlStore) { viperUtil.MustUnmarshalKey("flow", &flow) } -// @title 0G Storage Scan API +// @title 0G Storage Scan API // @version 1.0 // @description Use any http client to fetch data from the 0G Storage Scan. func init() { @@ -60,7 +69,7 @@ func init() { // // @Summary Statistics dashboard // @Description Query statistics dashboard includes `storage fee` and `log sync height` -// @Tags statistic +// @Tags (deprecated)statistic // @Produce json // @Success 200 {object} api.BusinessError{Data=Dashboard} // @Failure 600 {object} api.BusinessError @@ -73,7 +82,7 @@ func dashboardHandler(c *gin.Context) { // // @Summary Transaction statistics // @Description Query transaction statistics, including incremental and full data, and support querying at hourly or daily time intervals -// @Tags statistic +// @Tags (deprecated)statistic // @Accept json // @Produce json // @Param skip query int false "The number of skipped records, usually it's pageSize * (pageNumber - 1)" minimum(0) default(0) @@ -93,7 +102,7 @@ func listTxStatHandler(c *gin.Context) { // // @Summary Data storage statistics // @Description Query data storage statistics, including incremental and full data, and support querying at hourly or daily time intervals -// @Tags statistic +// @Tags (deprecated)statistic // @Accept json // @Produce json // @Param skip query int false "The number of skipped records, usually it's pageSize * (pageNumber - 1)" minimum(0) default(0) @@ -113,7 +122,7 @@ func listDataStatHandler(c *gin.Context) { // // @Summary fee statistics // @Description Query fee statistics, including incremental and full data, and support querying at hourly or daily time intervals -// @Tags statistic +// @Tags (deprecated)statistic // @Accept json // @Produce json // @Param skip query int false "The number of skipped records, usually it's pageSize * (pageNumber - 1)" minimum(0) default(0) @@ -133,7 +142,7 @@ func listFeeStatHandler(c *gin.Context) { // // @Summary Layer2 transaction list // @Description Query layer2 transactions, support address and root hash filter -// @Tags transaction +// @Tags (deprecated)transaction // @Accept json // @Produce json // @Param skip query int false "The number of skipped records, usually it's pageSize * (pageNumber - 1)" minimum(0) default(0) @@ -151,7 +160,7 @@ func listTxHandler(c *gin.Context) { // // @Summary Layer2 transaction overview // @Description Query layer2 transaction overview by txSeq -// @Tags transaction +// @Tags (deprecated)transaction // @Accept json // @Produce json // @Param txSeq query string true "Lay2 transaction sequence number" @@ -166,7 +175,7 @@ func getTxBriefHandler(c *gin.Context) { // // @Summary Layer2 transaction advanced info // @Description Query layer2 transaction advanced info by txSeq -// @Tags transaction +// @Tags (deprecated)transaction // @Accept json // @Produce json // @Param txSeq query string true "Lay2 transaction sequence number" @@ -191,5 +200,140 @@ func RegisterRouter(router *gin.Engine) { txRoute.GET("brief", getTxBriefHandler) txRoute.GET("detail", getTxDetailHandler) + statsRoute := apiRoute.Group("/stats") + statsRoute.GET("summary", summaryHandler) + statsRoute.GET("layer1-tx", listTxStatsHandler) + statsRoute.GET("storage", listDataStatsHandler) + statsRoute.GET("fee", listFeeStatsHandler) + + txsRoute := apiRoute.Group("/txs") + txsRoute.GET("", listTxsHandler) + txsRoute.GET(":txSeq", getTxHandler) + + accountsRoute := apiRoute.Group("/accounts") + accountsRoute.GET(":address/txs", listAddressTxsHandler) + router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) } + +// summaryHandler godoc +// +// @Summary Statistics summary +// @Description Query statistics summary includes `storage fee` and `log sync height` +// @Tags statistic +// @Produce json +// @Success 200 {object} api.BusinessError{Data=Summary} +// @Failure 600 {object} api.BusinessError +// @Router /stats/summary [get] +func summaryHandler(c *gin.Context) { + api.Wrap(summary)(c) +} + +// listTxStatsHandler godoc +// +// @Summary Layer1 transaction statistics +// @Description Query transaction statistics, including incremental and full data, and support querying at hourly or daily time intervals +// @Tags statistic +// @Accept json +// @Produce json +// @Param skip query int false "The number of skipped records, usually it's pageSize * (pageNumber - 1)" minimum(0) default(0) +// @Param limit query int false "The number of records displayed on the page" minimum(1) maximum(2000) default(10) +// @Param minTimestamp query int false "Timestamp in seconds" +// @Param maxTimestamp query int false "Timestamp in seconds" +// @Param intervalType query string false "Statistics interval" Enums(hour, day) default(day) +// @Param sort query string false "Sort by timestamp" Enums(asc, desc) default(desc) +// @Success 200 {object} api.BusinessError{Data=TxStatList} +// @Failure 600 {object} api.BusinessError +// @Router /stats/layer1-tx [get] +func listTxStatsHandler(c *gin.Context) { + api.Wrap(listTxStat)(c) +} + +// listDataStatsHandler godoc +// +// @Summary Data storage statistics +// @Description Query data storage statistics, including incremental and full data, and support querying at hourly or daily time intervals +// @Tags statistic +// @Accept json +// @Produce json +// @Param skip query int false "The number of skipped records, usually it's pageSize * (pageNumber - 1)" minimum(0) default(0) +// @Param limit query int false "The number of records displayed on the page" minimum(1) maximum(2000) default(10) +// @Param minTimestamp query int false "Timestamp in seconds" +// @Param maxTimestamp query int false "Timestamp in seconds" +// @Param intervalType query string false "Statistics interval" Enums(hour, day) default(day) +// @Param sort query string false "Sort by timestamp" Enums(asc, desc) default(desc) +// @Success 200 {object} api.BusinessError{Data=DataStatList} +// @Failure 600 {object} api.BusinessError +// @Router /stats/storage [get] +func listDataStatsHandler(c *gin.Context) { + api.Wrap(listDataStat)(c) +} + +// listFeeStatsHandler godoc +// +// @Summary Storage fee statistics +// @Description Query fee statistics, including incremental and full data, and support querying at hourly or daily time intervals +// @Tags statistic +// @Accept json +// @Produce json +// @Param skip query int false "The number of skipped records, usually it's pageSize * (pageNumber - 1)" minimum(0) default(0) +// @Param limit query int false "The number of records displayed on the page" minimum(1) maximum(2000) default(10) +// @Param minTimestamp query int false "Timestamp in seconds" +// @Param maxTimestamp query int false "Timestamp in seconds" +// @Param intervalType query string false "Statistics interval" Enums(hour, day) default(day) +// @Param sort query string false "Sort by timestamp" Enums(asc, desc) default(desc) +// @Success 200 {object} api.BusinessError{Data=FeeStatList} +// @Failure 600 {object} api.BusinessError +// @Router /stats/fee [get] +func listFeeStatsHandler(c *gin.Context) { + api.Wrap(listFeeStat)(c) +} + +// listTxsHandler godoc +// +// @Summary Storage transaction list +// @Description Query storage transactions, support address and root hash filter +// @Tags transaction +// @Accept json +// @Produce json +// @Param skip query int false "The number of skipped records, usually it's pageSize * (pageNumber - 1)" minimum(0) default(0) +// @Param limit query int false "The number of records displayed on the page" minimum(1) maximum(100) default(10) +// @Success 200 {object} api.BusinessError{Data=StorageTxList} +// @Failure 600 {object} api.BusinessError +// @Router /txs [get] +func listTxsHandler(c *gin.Context) { + api.Wrap(listStorageTx)(c) +} + +// getTxHandler godoc +// +// @Summary Storage transaction information +// @Description Query storage transaction by txSeq +// @Tags transaction +// @Accept json +// @Produce json +// @Param txSeq path string true "storage transaction sequence number" +// @Success 200 {object} api.BusinessError{Data=StorageTxDetail} +// @Failure 600 {object} api.BusinessError +// @Router /txs/{txSeq} [get] +func getTxHandler(c *gin.Context) { + api.Wrap(getStorageTx)(c) +} + +// listAddressTxsHandler godoc +// +// @Summary Account's storage transaction list +// @Description Query storage transactions for specified account, support root hash filter +// @Tags account +// @Accept json +// @Produce json +// @Param address path string false "The submitter address of the uploaded file" +// @Param skip query int false "The number of skipped records, usually it's pageSize * (pageNumber - 1)" minimum(0) default(0) +// @Param limit query int false "The number of records displayed on the page" minimum(1) maximum(100) default(10) +// @Param rootHash query string false "The merkle root hash of the uploaded file" +// @Success 200 {object} api.BusinessError{Data=StorageTxList} +// @Failure 600 {object} api.BusinessError +// @Router /accounts/{address}/txs [get] +func listAddressTxsHandler(c *gin.Context) { + api.Wrap(listAddressStorageTx)(c) +} diff --git a/api/stat_api.go b/api/stat_api.go index 34895cf..4392a7a 100644 --- a/api/stat_api.go +++ b/api/stat_api.go @@ -105,9 +105,9 @@ func getSubmitStatByType(c *gin.Context, t Type) (interface{}, error) { list := make([]FeeStat, 0) for _, r := range records { list = append(list, FeeStat{ - StatTime: r.StatTime, - BaseFee: r.BaseFee, - BaseFeeTotal: r.BaseFeeTotal, + StatTime: r.StatTime, + StorageFee: r.BaseFee, + StorageFeeTotal: r.BaseFeeTotal, }) } result["list"] = list @@ -117,3 +117,37 @@ func getSubmitStatByType(c *gin.Context, t Type) (interface{}, error) { return result, nil } + +func summary(_ *gin.Context) (interface{}, error) { + value, exist, err := db.ConfigStore.Get(store.KeyLogSyncInfo) + if err != nil { + return nil, commonApi.ErrInternal(err) + } + if !exist { + return nil, ErrConfigNotFound + } + + var logSyncInfo stat.LogSyncInfo + if err := json.Unmarshal([]byte(value), &logSyncInfo); err != nil { + return nil, commonApi.ErrInternal(err) + } + + submitStat, err := db.SubmitStatStore.LastByType(store.Day) + if err != nil { + return nil, commonApi.ErrInternal(err) + } + if submitStat == nil { + return nil, ErrStorageBaseFeeNotStat + } + + storageFee := StorageFeeStat{ + TokenInfo: *chargeToken, + StorageFeeTotal: submitStat.BaseFeeTotal, + } + result := Summary{ + StorageFeeStat: storageFee, + LogSyncInfo: logSyncInfo, + } + + return result, nil +} diff --git a/api/tx_api.go b/api/tx_api.go index 91c7a63..e5026c1 100644 --- a/api/tx_api.go +++ b/api/tx_api.go @@ -48,18 +48,16 @@ func listTx(c *gin.Context) (interface{}, error) { storageTxs := make([]StorageTx, 0) for _, submit := range submits { storageTx := StorageTx{ - TxSeq: submit.SubmissionIndex, - BlockNum: submit.BlockNumber, - TxHash: submit.TxHash, - RootHash: submit.RootHash, - Address: addrMap[submit.SenderID].Address, - Method: "submit", - Status: submit.Status, - TotalSegNum: submit.TotalSegNum, - UploadedSegNum: submit.UploadedSegNum, - Timestamp: submit.BlockTime.Unix(), - DataSize: submit.Length, - BaseFee: submit.Fee, + TxSeq: submit.SubmissionIndex, + BlockNum: submit.BlockNumber, + TxHash: submit.TxHash, + RootHash: submit.RootHash, + Address: addrMap[submit.SenderID].Address, + Method: "submit", + Status: submit.Status, + Timestamp: submit.BlockTime.Unix(), + DataSize: submit.Length, + BaseFee: submit.Fee, } storageTxs = append(storageTxs, storageTx) } @@ -188,3 +186,144 @@ func listSubmits(addressID *uint64, rootHash *string, idDesc bool, skip, limit i return total, submits, nil } + +func convertTxList(total int64, submits []store.Submit) (*StorageTxList, error) { + addrIDs := make([]uint64, 0) + for _, submit := range submits { + addrIDs = append(addrIDs, submit.SenderID) + } + addrMap, err := db.BatchGetAddresses(addrIDs) + if err != nil { + return nil, err + } + + storageTxs := make([]StorageTxInfo, 0) + for _, submit := range submits { + storageTx := StorageTxInfo{ + TxSeq: submit.SubmissionIndex, + BlockNumber: submit.BlockNumber, + TxHash: submit.TxHash, + RootHash: submit.RootHash, + From: addrMap[submit.SenderID].Address, + Method: "submit", + Status: submit.Status, + Segments: submit.TotalSegNum, + UploadedSegments: submit.UploadedSegNum, + Timestamp: submit.BlockTime.Unix(), + DataSize: submit.Length, + StorageFee: submit.Fee, + } + storageTxs = append(storageTxs, storageTx) + } + + return &StorageTxList{ + Total: total, + List: storageTxs, + }, nil +} + +func listAddressStorageTx(c *gin.Context) (interface{}, error) { + address := c.Param("address") + if address == "" { + logrus.Error("Failed to parse nil address") + return nil, errors.Errorf("Biz error, nil address %v", address) + } + addr, exist, err := db.AddressStore.Get(address) + if err != nil { + return nil, commonApi.ErrInternal(err) + } + if !exist { + return TxList{}, nil + } + addrIDPtr := &addr.ID + + var param listAddressStorageTxParam + if err := c.ShouldBind(¶m); err != nil { + return nil, err + } + + total, submits, err := listSubmits(addrIDPtr, param.RootHash, param.isDesc(), param.Skip, param.Limit) + if err != nil { + return nil, err + } + + return convertTxList(total, submits) +} + +func listStorageTx(c *gin.Context) (interface{}, error) { + var param listStorageTxParam + if err := c.ShouldBind(¶m); err != nil { + return nil, err + } + + total, submits, err := listSubmits(nil, nil, param.isDesc(), param.Skip, param.Limit) + if err != nil { + return nil, err + } + + return convertTxList(total, submits) +} + +func getStorageTx(c *gin.Context) (interface{}, error) { + txSeqParam := c.Param("txSeq") + txSeq, err := strconv.ParseUint(txSeqParam, 10, 64) + if err != nil { + logrus.WithError(err).Error("Failed to parse txSeq") + return nil, errors.Errorf("Biz error, invalid txSeq %v", txSeq) + } + + var submit store.Submit + exist, err := db.Store.Exists(&submit, "submission_index = ?", txSeq) + if err != nil { + logrus.WithError(err).Error("Failed to query databases") + return nil, errors.Errorf("Biz error, txSeq %v", txSeq) + } + if !exist { + return nil, errors.Errorf("Record not found, txSeq %v", txSeq) + } + + addrIDs := []uint64{submit.SenderID} + addrMap, err := db.BatchGetAddresses(addrIDs) + if err != nil { + return nil, err + } + + result := StorageTxDetail{ + TxSeq: strconv.FormatUint(submit.SubmissionIndex, 10), + From: addrMap[submit.SenderID].Address, + Method: "submit", + RootHash: submit.RootHash, + DataSize: submit.Length, + Status: submit.Status, + StorageFee: submit.Fee, + BlockNumber: submit.BlockNumber, + TxHash: submit.TxHash, + Timestamp: uint64(submit.BlockTime.Unix()), + } + + var extra store.SubmitExtra + if err := json.Unmarshal(submit.Extra, &extra); err != nil { + logrus.WithError(err).Error("Failed to unmarshal submit extra") + return nil, errors.Errorf("Unmarshal submit extra error, txSeq %v", txSeq) + } + result.StartPosition = extra.StartPos.Uint64() + result.EndPosition = extra.StartPos.Uint64() + submit.Length + result.Segments = submit.TotalSegNum + + hash := common.HexToHash(submit.TxHash) + tx, err := sdk.Eth.TransactionByHash(hash) + if err != nil { + logrus.WithError(err).WithField("txSeq", txSeq).Error("Failed to get transaction") + return nil, errors.Errorf("Get tx error, txSeq %v", txSeq) + } + rcpt, err := sdk.Eth.TransactionReceipt(hash) + if err != nil { + logrus.WithError(err).WithField("txSeq", txSeq).Error("Failed to get receipt") + return nil, errors.Errorf("Get receitp error, txSeq %v", txSeq) + } + result.GasFee = tx.GasPrice.Uint64() * rcpt.GasUsed + result.GasUsed = rcpt.GasUsed + result.GasLimit = tx.Gas + + return result, nil +} diff --git a/api/types.go b/api/types.go index c31446c..19976d9 100644 --- a/api/types.go +++ b/api/types.go @@ -37,24 +37,22 @@ func (sp *listTxParam) isDesc() bool { } type queryTxParam struct { - TxSeq *uint64 `form:"txSeq" binding:"required,number,gte=0"` + TxSeq *uint64 `uri:"txSeq" form:"txSeq" binding:"required,number,gte=0"` } // StorageTx model info // @Description Submission information type StorageTx struct { - TxSeq uint64 `json:"txSeq"` // Submission index in submit event - BlockNum uint64 `json:"blockNum"` // The block where the submit event is emitted - TxHash string `json:"txHash"` // The transaction where the submit event is emitted - RootHash string `json:"rootHash"` // Merkle root of the file to upload - Address string `json:"address"` // File uploader address - Method string `json:"method"` // The name of the submit event is always `submit` - Status uint8 `json:"status"` // File upload status, 0-not uploaded,1-uploading,2-uploaded - TotalSegNum uint64 `json:"totalSegNum"` // The total number of segments the file is split into - UploadedSegNum uint64 `json:"uploadedSegNum"` // The number of segments the file has been uploaded - Timestamp int64 `json:"timestamp"` // The block time when submit event emits - DataSize uint64 `json:"dataSize"` // File size in bytes - BaseFee decimal.Decimal `json:"baseFee"` // The token fee required to upload the file + TxSeq uint64 `json:"txSeq"` // Submission index in submit event + BlockNum uint64 `json:"blockNum"` // The block where the submit event is emitted + TxHash string `json:"txHash"` // The transaction where the submit event is emitted + RootHash string `json:"rootHash"` // Merkle root of the file to upload + Address string `json:"address"` // File uploader address + Method string `json:"method"` // The name of the submit event is always `submit` + Status uint8 `json:"status"` // File upload status, 0-not uploaded,1-uploading,2-uploaded + Timestamp int64 `json:"timestamp"` // The block time when submit event emits + DataSize uint64 `json:"dataSize"` // File size in bytes + BaseFee decimal.Decimal `json:"baseFee"` // The storage fee required to upload the file } // TokenInfo model info @@ -64,6 +62,7 @@ type TokenInfo struct { Name string `json:"name"` // Token name Symbol string `json:"symbol"` // Token symbol Decimals uint8 `json:"decimals"` // Token decimals + Native bool `json:"native"` // True is native token, otherwise is not } // CostInfo model info @@ -168,7 +167,100 @@ type TxStat struct { // FeeStat model info // @Description Storage fee information type FeeStat struct { - StatTime time.Time `json:"statTime"` // Statistics time - BaseFee decimal.Decimal `json:"baseFee"` // The base fee for storage in a specific time interval - BaseFeeTotal decimal.Decimal `json:"baseFeeTotal"` // The total base fee for storage by a certain time + StatTime time.Time `json:"statTime"` // Statistics time + StorageFee decimal.Decimal `json:"storageFee"` // The base fee for storage in a specific time interval + StorageFeeTotal decimal.Decimal `json:"storageFeeTotal"` // The total base fee for storage by a certain time +} + +type listStorageTxParam struct { + PageParam + Sort string `form:"sort,default=desc" binding:"omitempty,oneof=asc desc"` +} + +func (sp *listStorageTxParam) isDesc() bool { + return strings.EqualFold(sp.Sort, "desc") +} + +type listAddressStorageTxParam struct { + PageParam + RootHash *string `form:"rootHash" binding:"omitempty"` + Sort string `form:"sort,default=desc" binding:"omitempty,oneof=asc desc"` +} + +func (sp *listAddressStorageTxParam) isDesc() bool { + return strings.EqualFold(sp.Sort, "desc") +} + +// Summary model info +// @Description Storage summary information +type Summary struct { + StorageFeeStat `json:"storageFee"` // Storage fee information + stat.LogSyncInfo `json:"logSync"` // Synchronization information of submit event +} + +// StorageFeeStat model info +// @Description Stat storage fee information +type StorageFeeStat struct { + TokenInfo `json:"chargeToken"` // Charge token info + StorageFeeTotal decimal.Decimal `json:"storageFeeTotal"` // Total storage fee +} + +// StorageTxInfo model info +// @Description Submission transaction information +type StorageTxInfo struct { + TxSeq uint64 `json:"txSeq"` // Submission index in submit event + From string `json:"from"` // File uploader address + Method string `json:"method"` // The name of the submit event is always `submit` + + RootHash string `json:"rootHash"` // Merkle root of the file to upload + DataSize uint64 `json:"dataSize"` // File size in bytes + StorageFee decimal.Decimal `json:"storageFee"` // The storage fee required to upload the file + Status uint8 `json:"status"` // File upload status, 0-not uploaded,1-uploading,2-uploaded + + BlockNumber uint64 `json:"blockNumber"` // The block where the submit event is emitted + TxHash string `json:"txHash"` // The transaction where the submit event is emitted + Timestamp int64 `json:"timestamp"` // The block time when submit event emits + + Segments uint64 `json:"segments"` // The total number of segments the file is split into + UploadedSegments uint64 `json:"uploadedSegments"` // The number of segments the file has been uploaded +} + +// StorageTxList model info +// @Description Submission information list +type StorageTxList struct { + Total int64 `json:"total"` // The total number of submission returned + List []StorageTxInfo `json:"list"` // Submission list +} + +// StorageTxDetail model info +// @Description Submission transaction information +type StorageTxDetail struct { + TxSeq string `json:"txSeq"` // Submission index in submit event + From string `json:"from"` // File uploader address + Method string `json:"method"` // The name of the submit event is always `submit` + + RootHash string `json:"rootHash"` // Merkle root of the file to upload + DataSize uint64 `json:"dataSize"` // File size in bytes + Expiration uint64 `json:"expiration"` // Expiration date of the uploaded file + StorageFee decimal.Decimal `json:"storageFee"` // The storage fee required to upload the file + Status uint8 `json:"status"` // File upload status, 0-not uploaded,1-uploading,2-uploaded + + StartPosition uint64 `json:"startPosition"` // The starting position of the file stored in the storage node + EndPosition uint64 `json:"endPosition"` // The ending position of the file stored in the storage node + Segments uint64 `json:"segments"` // The total number of segments the file is split into + + BlockNumber uint64 `json:"blockNumber"` // The block where the submit event is emitted + TxHash string `json:"txHash"` // The transaction where the submit event is emitted + Timestamp uint64 `json:"timestamp"` // The block time when submit event emits + + GasFee uint64 `json:"gasFee"` // The gas fee of the transaction on layer1 + GasUsed uint64 `json:"gasUsed"` // The gas used of the transaction on layer1 + GasLimit uint64 `json:"gasLimit"` // The gas limit of the transaction on layer1 +} + +// StorageFee model info +// @Description Storage fee information +type StorageFee struct { + TokenInfo `json:"chargeToken"` // Charge token info + StorageFee decimal.Decimal `json:"storageFee"` // Storage fee } diff --git a/config/config.yml b/config/config.yml index 0879241..95e034c 100644 --- a/config/config.yml +++ b/config/config.yml @@ -45,11 +45,17 @@ flow: submitEventSignature: 0x167ce04d2aa1981994d3a31695da0d785373335b1078cec239a1a3a2c7675555 # Charge info configurations +# When charging in ERC20 token, configure `erc20TokenAddress` and `erc20TransferEventSignature` +# When charging in native token, configure `symbol` and `decimals` charge: # Charge in ERC20 token address erc20TokenAddress: 0x7d682e65efc5c13bf4e394b8f376c48e6bae0355 # ERC20 transfer event signature erc20TransferEventSignature: 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef + # Token symbol + symbol: A0GI + # Token decimals + decimals: 18 # MySQL database configurations store: diff --git a/docs/docs.go b/docs/docs.go index f36ee48..3ca094e 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -15,6 +15,78 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/accounts/{address}/txs": { + "get": { + "description": "Query storage transactions for specified account, support root hash filter", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "account" + ], + "summary": "Account's storage transaction list", + "parameters": [ + { + "type": "string", + "description": "The submitter address of the uploaded file", + "name": "address", + "in": "path" + }, + { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 100, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "The merkle root hash of the uploaded file", + "name": "rootHash", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.StorageTxList" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, "/statistic/dashboard": { "get": { "description": "Query statistics dashboard includes ` + "`" + `storage fee` + "`" + ` and ` + "`" + `log sync height` + "`" + `", @@ -22,7 +94,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "statistic" + "(deprecated)statistic" ], "summary": "Statistics dashboard", "responses": { @@ -63,7 +135,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "statistic" + "(deprecated)statistic" ], "summary": "fee statistics", "parameters": [ @@ -157,7 +229,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "statistic" + "(deprecated)statistic" ], "summary": "Data storage statistics", "parameters": [ @@ -251,7 +323,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "statistic" + "(deprecated)statistic" ], "summary": "Transaction statistics", "parameters": [ @@ -335,9 +407,9 @@ const docTemplate = `{ } } }, - "/transaction/brief": { + "/stats/fee": { "get": { - "description": "Query layer2 transaction overview by txSeq", + "description": "Query fee statistics, including incremental and full data, and support querying at hourly or daily time intervals", "consumes": [ "application/json" ], @@ -345,16 +417,60 @@ const docTemplate = `{ "application/json" ], "tags": [ - "transaction" + "statistic" ], - "summary": "Layer2 transaction overview", + "summary": "Storage fee statistics", "parameters": [ { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 2000, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "minTimestamp", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "maxTimestamp", + "in": "query" + }, + { + "enum": [ + "hour", + "day" + ], "type": "string", - "description": "Lay2 transaction sequence number", - "name": "txSeq", - "in": "query", - "required": true + "default": "day", + "description": "Statistics interval", + "name": "intervalType", + "in": "query" + }, + { + "enum": [ + "asc", + "desc" + ], + "type": "string", + "default": "desc", + "description": "Sort by timestamp", + "name": "sort", + "in": "query" } ], "responses": { @@ -369,7 +485,7 @@ const docTemplate = `{ "type": "object", "properties": { "Data": { - "$ref": "#/definitions/api.TxBrief" + "$ref": "#/definitions/api.FeeStatList" } } } @@ -385,9 +501,9 @@ const docTemplate = `{ } } }, - "/transaction/detail": { + "/stats/layer1-tx": { "get": { - "description": "Query layer2 transaction advanced info by txSeq", + "description": "Query transaction statistics, including incremental and full data, and support querying at hourly or daily time intervals", "consumes": [ "application/json" ], @@ -395,16 +511,60 @@ const docTemplate = `{ "application/json" ], "tags": [ - "transaction" + "statistic" ], - "summary": "Layer2 transaction advanced info", + "summary": "Layer1 transaction statistics", "parameters": [ { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 2000, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "minTimestamp", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "maxTimestamp", + "in": "query" + }, + { + "enum": [ + "hour", + "day" + ], "type": "string", - "description": "Lay2 transaction sequence number", - "name": "txSeq", - "in": "query", - "required": true + "default": "day", + "description": "Statistics interval", + "name": "intervalType", + "in": "query" + }, + { + "enum": [ + "asc", + "desc" + ], + "type": "string", + "default": "desc", + "description": "Sort by timestamp", + "name": "sort", + "in": "query" } ], "responses": { @@ -419,7 +579,7 @@ const docTemplate = `{ "type": "object", "properties": { "Data": { - "$ref": "#/definitions/api.TxDetail" + "$ref": "#/definitions/api.TxStatList" } } } @@ -435,9 +595,9 @@ const docTemplate = `{ } } }, - "/transaction/list": { + "/stats/storage": { "get": { - "description": "Query layer2 transactions, support address and root hash filter", + "description": "Query data storage statistics, including incremental and full data, and support querying at hourly or daily time intervals", "consumes": [ "application/json" ], @@ -445,9 +605,9 @@ const docTemplate = `{ "application/json" ], "tags": [ - "transaction" + "statistic" ], - "summary": "Layer2 transaction list", + "summary": "Data storage statistics", "parameters": [ { "minimum": 0, @@ -458,7 +618,7 @@ const docTemplate = `{ "in": "query" }, { - "maximum": 100, + "maximum": 2000, "minimum": 1, "type": "integer", "default": 10, @@ -467,15 +627,37 @@ const docTemplate = `{ "in": "query" }, { + "type": "integer", + "description": "Timestamp in seconds", + "name": "minTimestamp", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "maxTimestamp", + "in": "query" + }, + { + "enum": [ + "hour", + "day" + ], "type": "string", - "description": "The submitter address of the uploaded file", - "name": "address", + "default": "day", + "description": "Statistics interval", + "name": "intervalType", "in": "query" }, { + "enum": [ + "asc", + "desc" + ], "type": "string", - "description": "The merkle root hash of the uploaded file", - "name": "rootHash", + "default": "desc", + "description": "Sort by timestamp", + "name": "sort", "in": "query" } ], @@ -491,7 +673,7 @@ const docTemplate = `{ "type": "object", "properties": { "Data": { - "$ref": "#/definitions/api.TxList" + "$ref": "#/definitions/api.DataStatList" } } } @@ -506,32 +688,352 @@ const docTemplate = `{ } } } - } - }, - "definitions": { - "api.BusinessError": { - "type": "object", - "properties": { - "code": { - "type": "integer" - }, - "data": {}, - "message": { - "type": "string" - } - } }, - "api.CostInfo": { - "description": "Charge fee information", - "type": "object", - "properties": { - "basicCost": { - "description": "Charge fee", - "type": "number" - }, - "tokenInfo": { - "description": "Charge token info", - "allOf": [ + "/stats/summary": { + "get": { + "description": "Query statistics summary includes ` + "`" + `storage fee` + "`" + ` and ` + "`" + `log sync height` + "`" + `", + "produces": [ + "application/json" + ], + "tags": [ + "statistic" + ], + "summary": "Statistics summary", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.Summary" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/transaction/brief": { + "get": { + "description": "Query layer2 transaction overview by txSeq", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "(deprecated)transaction" + ], + "summary": "Layer2 transaction overview", + "parameters": [ + { + "type": "string", + "description": "Lay2 transaction sequence number", + "name": "txSeq", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.TxBrief" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/transaction/detail": { + "get": { + "description": "Query layer2 transaction advanced info by txSeq", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "(deprecated)transaction" + ], + "summary": "Layer2 transaction advanced info", + "parameters": [ + { + "type": "string", + "description": "Lay2 transaction sequence number", + "name": "txSeq", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.TxDetail" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/transaction/list": { + "get": { + "description": "Query layer2 transactions, support address and root hash filter", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "(deprecated)transaction" + ], + "summary": "Layer2 transaction list", + "parameters": [ + { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 100, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "The submitter address of the uploaded file", + "name": "address", + "in": "query" + }, + { + "type": "string", + "description": "The merkle root hash of the uploaded file", + "name": "rootHash", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.TxList" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/txs": { + "get": { + "description": "Query storage transactions, support address and root hash filter", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "transaction" + ], + "summary": "Storage transaction list", + "parameters": [ + { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 100, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.StorageTxList" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/txs/{txSeq}": { + "get": { + "description": "Query storage transaction by txSeq", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "transaction" + ], + "summary": "Storage transaction information", + "parameters": [ + { + "type": "string", + "description": "storage transaction sequence number", + "name": "txSeq", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.StorageTxDetail" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + } + }, + "definitions": { + "api.BusinessError": { + "type": "object", + "properties": { + "code": { + "type": "integer" + }, + "data": {}, + "message": { + "type": "string" + } + } + }, + "api.CostInfo": { + "description": "Charge fee information", + "type": "object", + "properties": { + "basicCost": { + "description": "Charge fee", + "type": "number" + }, + "tokenInfo": { + "description": "Charge token info", + "allOf": [ { "$ref": "#/definitions/api.TokenInfo" } @@ -608,17 +1110,17 @@ const docTemplate = `{ "description": "Storage fee information", "type": "object", "properties": { - "baseFee": { + "statTime": { + "description": "Statistics time", + "type": "string" + }, + "storageFee": { "description": "The base fee for storage in a specific time interval", "type": "number" }, - "baseFeeTotal": { + "storageFeeTotal": { "description": "The total base fee for storage by a certain time", "type": "number" - }, - "statTime": { - "description": "Statistics time", - "type": "string" } } }, @@ -659,12 +1161,34 @@ const docTemplate = `{ "description": "Token name", "type": "string" }, + "native": { + "description": "True is native token, otherwise is not", + "type": "boolean" + }, "symbol": { "description": "Token symbol", "type": "string" } } }, + "api.StorageFeeStat": { + "description": "Stat storage fee information", + "type": "object", + "properties": { + "chargeToken": { + "description": "Charge token info", + "allOf": [ + { + "$ref": "#/definitions/api.TokenInfo" + } + ] + }, + "storageFeeTotal": { + "description": "Total storage fee", + "type": "number" + } + } + }, "api.StorageTx": { "description": "Submission information", "type": "object", @@ -674,7 +1198,7 @@ const docTemplate = `{ "type": "string" }, "baseFee": { - "description": "The token fee required to upload the file", + "description": "The storage fee required to upload the file", "type": "number" }, "blockNum": { @@ -701,24 +1225,183 @@ const docTemplate = `{ "description": "The block time when submit event emits", "type": "integer" }, - "totalSegNum": { + "txHash": { + "description": "The transaction where the submit event is emitted", + "type": "string" + }, + "txSeq": { + "description": "Submission index in submit event", + "type": "integer" + } + } + }, + "api.StorageTxDetail": { + "description": "Submission transaction information", + "type": "object", + "properties": { + "blockNumber": { + "description": "The block where the submit event is emitted", + "type": "integer" + }, + "dataSize": { + "description": "File size in bytes", + "type": "integer" + }, + "endPosition": { + "description": "The ending position of the file stored in the storage node", + "type": "integer" + }, + "expiration": { + "description": "Expiration date of the uploaded file", + "type": "integer" + }, + "from": { + "description": "File uploader address", + "type": "string" + }, + "gasFee": { + "description": "The gas fee of the transaction on layer1", + "type": "integer" + }, + "gasLimit": { + "description": "The gas limit of the transaction on layer1", + "type": "integer" + }, + "gasUsed": { + "description": "The gas used of the transaction on layer1", + "type": "integer" + }, + "method": { + "description": "The name of the submit event is always ` + "`" + `submit` + "`" + `", + "type": "string" + }, + "rootHash": { + "description": "Merkle root of the file to upload", + "type": "string" + }, + "segments": { "description": "The total number of segments the file is split into", "type": "integer" }, + "startPosition": { + "description": "The starting position of the file stored in the storage node", + "type": "integer" + }, + "status": { + "description": "File upload status, 0-not uploaded,1-uploading,2-uploaded", + "type": "integer" + }, + "storageFee": { + "description": "The storage fee required to upload the file", + "type": "number" + }, + "timestamp": { + "description": "The block time when submit event emits", + "type": "integer" + }, "txHash": { "description": "The transaction where the submit event is emitted", "type": "string" }, "txSeq": { "description": "Submission index in submit event", + "type": "string" + } + } + }, + "api.StorageTxInfo": { + "description": "Submission transaction information", + "type": "object", + "properties": { + "blockNumber": { + "description": "The block where the submit event is emitted", "type": "integer" }, - "uploadedSegNum": { + "dataSize": { + "description": "File size in bytes", + "type": "integer" + }, + "from": { + "description": "File uploader address", + "type": "string" + }, + "method": { + "description": "The name of the submit event is always ` + "`" + `submit` + "`" + `", + "type": "string" + }, + "rootHash": { + "description": "Merkle root of the file to upload", + "type": "string" + }, + "segments": { + "description": "The total number of segments the file is split into", + "type": "integer" + }, + "status": { + "description": "File upload status, 0-not uploaded,1-uploading,2-uploaded", + "type": "integer" + }, + "storageFee": { + "description": "The storage fee required to upload the file", + "type": "number" + }, + "timestamp": { + "description": "The block time when submit event emits", + "type": "integer" + }, + "txHash": { + "description": "The transaction where the submit event is emitted", + "type": "string" + }, + "txSeq": { + "description": "Submission index in submit event", + "type": "integer" + }, + "uploadedSegments": { "description": "The number of segments the file has been uploaded", "type": "integer" } } }, + "api.StorageTxList": { + "description": "Submission information list", + "type": "object", + "properties": { + "list": { + "description": "Submission list", + "type": "array", + "items": { + "$ref": "#/definitions/api.StorageTxInfo" + } + }, + "total": { + "description": "The total number of submission returned", + "type": "integer" + } + } + }, + "api.Summary": { + "description": "Storage summary information", + "type": "object", + "properties": { + "logSync": { + "description": "Synchronization information of submit event", + "allOf": [ + { + "$ref": "#/definitions/stat.LogSyncInfo" + } + ] + }, + "storageFee": { + "description": "Storage fee information", + "allOf": [ + { + "$ref": "#/definitions/api.StorageFeeStat" + } + ] + } + } + }, "api.TokenInfo": { "description": "Charge token information", "type": "object", @@ -735,6 +1418,10 @@ const docTemplate = `{ "description": "Token name", "type": "string" }, + "native": { + "description": "True is native token, otherwise is not", + "type": "boolean" + }, "symbol": { "description": "Token symbol", "type": "string" @@ -886,12 +1573,15 @@ const docTemplate = `{ } }, "stat.LogSyncInfo": { + "description": "Submit log sync information", "type": "object", "properties": { - "l2LogSyncHeight": { + "layer1-logSyncHeight": { + "description": "Synchronization height of submit log on blockchain", "type": "integer" }, "logSyncHeight": { + "description": "Synchronization height of submit log on storage node", "type": "integer" } } diff --git a/docs/swagger.json b/docs/swagger.json index 8054296..75aa506 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -7,6 +7,78 @@ "version": "1.0" }, "paths": { + "/accounts/{address}/txs": { + "get": { + "description": "Query storage transactions for specified account, support root hash filter", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "account" + ], + "summary": "Account's storage transaction list", + "parameters": [ + { + "type": "string", + "description": "The submitter address of the uploaded file", + "name": "address", + "in": "path" + }, + { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 100, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "The merkle root hash of the uploaded file", + "name": "rootHash", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.StorageTxList" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, "/statistic/dashboard": { "get": { "description": "Query statistics dashboard includes `storage fee` and `log sync height`", @@ -14,7 +86,7 @@ "application/json" ], "tags": [ - "statistic" + "(deprecated)statistic" ], "summary": "Statistics dashboard", "responses": { @@ -55,7 +127,7 @@ "application/json" ], "tags": [ - "statistic" + "(deprecated)statistic" ], "summary": "fee statistics", "parameters": [ @@ -149,7 +221,7 @@ "application/json" ], "tags": [ - "statistic" + "(deprecated)statistic" ], "summary": "Data storage statistics", "parameters": [ @@ -243,7 +315,7 @@ "application/json" ], "tags": [ - "statistic" + "(deprecated)statistic" ], "summary": "Transaction statistics", "parameters": [ @@ -327,9 +399,9 @@ } } }, - "/transaction/brief": { + "/stats/fee": { "get": { - "description": "Query layer2 transaction overview by txSeq", + "description": "Query fee statistics, including incremental and full data, and support querying at hourly or daily time intervals", "consumes": [ "application/json" ], @@ -337,16 +409,60 @@ "application/json" ], "tags": [ - "transaction" + "statistic" ], - "summary": "Layer2 transaction overview", + "summary": "Storage fee statistics", "parameters": [ { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 2000, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "minTimestamp", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "maxTimestamp", + "in": "query" + }, + { + "enum": [ + "hour", + "day" + ], "type": "string", - "description": "Lay2 transaction sequence number", - "name": "txSeq", - "in": "query", - "required": true + "default": "day", + "description": "Statistics interval", + "name": "intervalType", + "in": "query" + }, + { + "enum": [ + "asc", + "desc" + ], + "type": "string", + "default": "desc", + "description": "Sort by timestamp", + "name": "sort", + "in": "query" } ], "responses": { @@ -361,7 +477,7 @@ "type": "object", "properties": { "Data": { - "$ref": "#/definitions/api.TxBrief" + "$ref": "#/definitions/api.FeeStatList" } } } @@ -377,9 +493,9 @@ } } }, - "/transaction/detail": { + "/stats/layer1-tx": { "get": { - "description": "Query layer2 transaction advanced info by txSeq", + "description": "Query transaction statistics, including incremental and full data, and support querying at hourly or daily time intervals", "consumes": [ "application/json" ], @@ -387,16 +503,60 @@ "application/json" ], "tags": [ - "transaction" + "statistic" ], - "summary": "Layer2 transaction advanced info", + "summary": "Layer1 transaction statistics", "parameters": [ { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 2000, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "minTimestamp", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "maxTimestamp", + "in": "query" + }, + { + "enum": [ + "hour", + "day" + ], "type": "string", - "description": "Lay2 transaction sequence number", - "name": "txSeq", - "in": "query", - "required": true + "default": "day", + "description": "Statistics interval", + "name": "intervalType", + "in": "query" + }, + { + "enum": [ + "asc", + "desc" + ], + "type": "string", + "default": "desc", + "description": "Sort by timestamp", + "name": "sort", + "in": "query" } ], "responses": { @@ -411,7 +571,7 @@ "type": "object", "properties": { "Data": { - "$ref": "#/definitions/api.TxDetail" + "$ref": "#/definitions/api.TxStatList" } } } @@ -427,9 +587,9 @@ } } }, - "/transaction/list": { + "/stats/storage": { "get": { - "description": "Query layer2 transactions, support address and root hash filter", + "description": "Query data storage statistics, including incremental and full data, and support querying at hourly or daily time intervals", "consumes": [ "application/json" ], @@ -437,9 +597,9 @@ "application/json" ], "tags": [ - "transaction" + "statistic" ], - "summary": "Layer2 transaction list", + "summary": "Data storage statistics", "parameters": [ { "minimum": 0, @@ -450,7 +610,7 @@ "in": "query" }, { - "maximum": 100, + "maximum": 2000, "minimum": 1, "type": "integer", "default": 10, @@ -459,15 +619,37 @@ "in": "query" }, { + "type": "integer", + "description": "Timestamp in seconds", + "name": "minTimestamp", + "in": "query" + }, + { + "type": "integer", + "description": "Timestamp in seconds", + "name": "maxTimestamp", + "in": "query" + }, + { + "enum": [ + "hour", + "day" + ], "type": "string", - "description": "The submitter address of the uploaded file", - "name": "address", + "default": "day", + "description": "Statistics interval", + "name": "intervalType", "in": "query" }, { + "enum": [ + "asc", + "desc" + ], "type": "string", - "description": "The merkle root hash of the uploaded file", - "name": "rootHash", + "default": "desc", + "description": "Sort by timestamp", + "name": "sort", "in": "query" } ], @@ -483,7 +665,7 @@ "type": "object", "properties": { "Data": { - "$ref": "#/definitions/api.TxList" + "$ref": "#/definitions/api.DataStatList" } } } @@ -498,32 +680,352 @@ } } } - } - }, - "definitions": { - "api.BusinessError": { - "type": "object", - "properties": { - "code": { - "type": "integer" - }, - "data": {}, - "message": { - "type": "string" - } - } }, - "api.CostInfo": { - "description": "Charge fee information", - "type": "object", - "properties": { - "basicCost": { - "description": "Charge fee", - "type": "number" - }, - "tokenInfo": { - "description": "Charge token info", - "allOf": [ + "/stats/summary": { + "get": { + "description": "Query statistics summary includes `storage fee` and `log sync height`", + "produces": [ + "application/json" + ], + "tags": [ + "statistic" + ], + "summary": "Statistics summary", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.Summary" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/transaction/brief": { + "get": { + "description": "Query layer2 transaction overview by txSeq", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "(deprecated)transaction" + ], + "summary": "Layer2 transaction overview", + "parameters": [ + { + "type": "string", + "description": "Lay2 transaction sequence number", + "name": "txSeq", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.TxBrief" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/transaction/detail": { + "get": { + "description": "Query layer2 transaction advanced info by txSeq", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "(deprecated)transaction" + ], + "summary": "Layer2 transaction advanced info", + "parameters": [ + { + "type": "string", + "description": "Lay2 transaction sequence number", + "name": "txSeq", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.TxDetail" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/transaction/list": { + "get": { + "description": "Query layer2 transactions, support address and root hash filter", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "(deprecated)transaction" + ], + "summary": "Layer2 transaction list", + "parameters": [ + { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 100, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "The submitter address of the uploaded file", + "name": "address", + "in": "query" + }, + { + "type": "string", + "description": "The merkle root hash of the uploaded file", + "name": "rootHash", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.TxList" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/txs": { + "get": { + "description": "Query storage transactions, support address and root hash filter", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "transaction" + ], + "summary": "Storage transaction list", + "parameters": [ + { + "minimum": 0, + "type": "integer", + "default": 0, + "description": "The number of skipped records, usually it's pageSize * (pageNumber - 1)", + "name": "skip", + "in": "query" + }, + { + "maximum": 100, + "minimum": 1, + "type": "integer", + "default": 10, + "description": "The number of records displayed on the page", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.StorageTxList" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + }, + "/txs/{txSeq}": { + "get": { + "description": "Query storage transaction by txSeq", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "transaction" + ], + "summary": "Storage transaction information", + "parameters": [ + { + "type": "string", + "description": "storage transaction sequence number", + "name": "txSeq", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/api.BusinessError" + }, + { + "type": "object", + "properties": { + "Data": { + "$ref": "#/definitions/api.StorageTxDetail" + } + } + } + ] + } + }, + "600": { + "description": "", + "schema": { + "$ref": "#/definitions/api.BusinessError" + } + } + } + } + } + }, + "definitions": { + "api.BusinessError": { + "type": "object", + "properties": { + "code": { + "type": "integer" + }, + "data": {}, + "message": { + "type": "string" + } + } + }, + "api.CostInfo": { + "description": "Charge fee information", + "type": "object", + "properties": { + "basicCost": { + "description": "Charge fee", + "type": "number" + }, + "tokenInfo": { + "description": "Charge token info", + "allOf": [ { "$ref": "#/definitions/api.TokenInfo" } @@ -600,17 +1102,17 @@ "description": "Storage fee information", "type": "object", "properties": { - "baseFee": { + "statTime": { + "description": "Statistics time", + "type": "string" + }, + "storageFee": { "description": "The base fee for storage in a specific time interval", "type": "number" }, - "baseFeeTotal": { + "storageFeeTotal": { "description": "The total base fee for storage by a certain time", "type": "number" - }, - "statTime": { - "description": "Statistics time", - "type": "string" } } }, @@ -651,12 +1153,34 @@ "description": "Token name", "type": "string" }, + "native": { + "description": "True is native token, otherwise is not", + "type": "boolean" + }, "symbol": { "description": "Token symbol", "type": "string" } } }, + "api.StorageFeeStat": { + "description": "Stat storage fee information", + "type": "object", + "properties": { + "chargeToken": { + "description": "Charge token info", + "allOf": [ + { + "$ref": "#/definitions/api.TokenInfo" + } + ] + }, + "storageFeeTotal": { + "description": "Total storage fee", + "type": "number" + } + } + }, "api.StorageTx": { "description": "Submission information", "type": "object", @@ -666,7 +1190,7 @@ "type": "string" }, "baseFee": { - "description": "The token fee required to upload the file", + "description": "The storage fee required to upload the file", "type": "number" }, "blockNum": { @@ -693,24 +1217,183 @@ "description": "The block time when submit event emits", "type": "integer" }, - "totalSegNum": { + "txHash": { + "description": "The transaction where the submit event is emitted", + "type": "string" + }, + "txSeq": { + "description": "Submission index in submit event", + "type": "integer" + } + } + }, + "api.StorageTxDetail": { + "description": "Submission transaction information", + "type": "object", + "properties": { + "blockNumber": { + "description": "The block where the submit event is emitted", + "type": "integer" + }, + "dataSize": { + "description": "File size in bytes", + "type": "integer" + }, + "endPosition": { + "description": "The ending position of the file stored in the storage node", + "type": "integer" + }, + "expiration": { + "description": "Expiration date of the uploaded file", + "type": "integer" + }, + "from": { + "description": "File uploader address", + "type": "string" + }, + "gasFee": { + "description": "The gas fee of the transaction on layer1", + "type": "integer" + }, + "gasLimit": { + "description": "The gas limit of the transaction on layer1", + "type": "integer" + }, + "gasUsed": { + "description": "The gas used of the transaction on layer1", + "type": "integer" + }, + "method": { + "description": "The name of the submit event is always `submit`", + "type": "string" + }, + "rootHash": { + "description": "Merkle root of the file to upload", + "type": "string" + }, + "segments": { "description": "The total number of segments the file is split into", "type": "integer" }, + "startPosition": { + "description": "The starting position of the file stored in the storage node", + "type": "integer" + }, + "status": { + "description": "File upload status, 0-not uploaded,1-uploading,2-uploaded", + "type": "integer" + }, + "storageFee": { + "description": "The storage fee required to upload the file", + "type": "number" + }, + "timestamp": { + "description": "The block time when submit event emits", + "type": "integer" + }, "txHash": { "description": "The transaction where the submit event is emitted", "type": "string" }, "txSeq": { "description": "Submission index in submit event", + "type": "string" + } + } + }, + "api.StorageTxInfo": { + "description": "Submission transaction information", + "type": "object", + "properties": { + "blockNumber": { + "description": "The block where the submit event is emitted", "type": "integer" }, - "uploadedSegNum": { + "dataSize": { + "description": "File size in bytes", + "type": "integer" + }, + "from": { + "description": "File uploader address", + "type": "string" + }, + "method": { + "description": "The name of the submit event is always `submit`", + "type": "string" + }, + "rootHash": { + "description": "Merkle root of the file to upload", + "type": "string" + }, + "segments": { + "description": "The total number of segments the file is split into", + "type": "integer" + }, + "status": { + "description": "File upload status, 0-not uploaded,1-uploading,2-uploaded", + "type": "integer" + }, + "storageFee": { + "description": "The storage fee required to upload the file", + "type": "number" + }, + "timestamp": { + "description": "The block time when submit event emits", + "type": "integer" + }, + "txHash": { + "description": "The transaction where the submit event is emitted", + "type": "string" + }, + "txSeq": { + "description": "Submission index in submit event", + "type": "integer" + }, + "uploadedSegments": { "description": "The number of segments the file has been uploaded", "type": "integer" } } }, + "api.StorageTxList": { + "description": "Submission information list", + "type": "object", + "properties": { + "list": { + "description": "Submission list", + "type": "array", + "items": { + "$ref": "#/definitions/api.StorageTxInfo" + } + }, + "total": { + "description": "The total number of submission returned", + "type": "integer" + } + } + }, + "api.Summary": { + "description": "Storage summary information", + "type": "object", + "properties": { + "logSync": { + "description": "Synchronization information of submit event", + "allOf": [ + { + "$ref": "#/definitions/stat.LogSyncInfo" + } + ] + }, + "storageFee": { + "description": "Storage fee information", + "allOf": [ + { + "$ref": "#/definitions/api.StorageFeeStat" + } + ] + } + } + }, "api.TokenInfo": { "description": "Charge token information", "type": "object", @@ -727,6 +1410,10 @@ "description": "Token name", "type": "string" }, + "native": { + "description": "True is native token, otherwise is not", + "type": "boolean" + }, "symbol": { "description": "Token symbol", "type": "string" @@ -878,12 +1565,15 @@ } }, "stat.LogSyncInfo": { + "description": "Submit log sync information", "type": "object", "properties": { - "l2LogSyncHeight": { + "layer1-logSyncHeight": { + "description": "Synchronization height of submit log on blockchain", "type": "integer" }, "logSyncHeight": { + "description": "Synchronization height of submit log on storage node", "type": "integer" } } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index ff52114..21f9a91 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -64,15 +64,15 @@ definitions: api.FeeStat: description: Storage fee information properties: - baseFee: + statTime: + description: Statistics time + type: string + storageFee: description: The base fee for storage in a specific time interval type: number - baseFeeTotal: + storageFeeTotal: description: The total base fee for storage by a certain time type: number - statTime: - description: Statistics time - type: string type: object api.FeeStatList: description: Storage fee list @@ -101,10 +101,24 @@ definitions: name: description: Token name type: string + native: + description: True is native token, otherwise is not + type: boolean symbol: description: Token symbol type: string type: object + api.StorageFeeStat: + description: Stat storage fee information + properties: + chargeToken: + allOf: + - $ref: '#/definitions/api.TokenInfo' + description: Charge token info + storageFeeTotal: + description: Total storage fee + type: number + type: object api.StorageTx: description: Submission information properties: @@ -112,7 +126,7 @@ definitions: description: File uploader address type: string baseFee: - description: The token fee required to upload the file + description: The storage fee required to upload the file type: number blockNum: description: The block where the submit event is emitted @@ -132,19 +146,132 @@ definitions: timestamp: description: The block time when submit event emits type: integer - totalSegNum: + txHash: + description: The transaction where the submit event is emitted + type: string + txSeq: + description: Submission index in submit event + type: integer + type: object + api.StorageTxDetail: + description: Submission transaction information + properties: + blockNumber: + description: The block where the submit event is emitted + type: integer + dataSize: + description: File size in bytes + type: integer + endPosition: + description: The ending position of the file stored in the storage node + type: integer + expiration: + description: Expiration date of the uploaded file + type: integer + from: + description: File uploader address + type: string + gasFee: + description: The gas fee of the transaction on layer1 + type: integer + gasLimit: + description: The gas limit of the transaction on layer1 + type: integer + gasUsed: + description: The gas used of the transaction on layer1 + type: integer + method: + description: The name of the submit event is always `submit` + type: string + rootHash: + description: Merkle root of the file to upload + type: string + segments: description: The total number of segments the file is split into type: integer + startPosition: + description: The starting position of the file stored in the storage node + type: integer + status: + description: File upload status, 0-not uploaded,1-uploading,2-uploaded + type: integer + storageFee: + description: The storage fee required to upload the file + type: number + timestamp: + description: The block time when submit event emits + type: integer + txHash: + description: The transaction where the submit event is emitted + type: string + txSeq: + description: Submission index in submit event + type: string + type: object + api.StorageTxInfo: + description: Submission transaction information + properties: + blockNumber: + description: The block where the submit event is emitted + type: integer + dataSize: + description: File size in bytes + type: integer + from: + description: File uploader address + type: string + method: + description: The name of the submit event is always `submit` + type: string + rootHash: + description: Merkle root of the file to upload + type: string + segments: + description: The total number of segments the file is split into + type: integer + status: + description: File upload status, 0-not uploaded,1-uploading,2-uploaded + type: integer + storageFee: + description: The storage fee required to upload the file + type: number + timestamp: + description: The block time when submit event emits + type: integer txHash: description: The transaction where the submit event is emitted type: string txSeq: description: Submission index in submit event type: integer - uploadedSegNum: + uploadedSegments: description: The number of segments the file has been uploaded type: integer type: object + api.StorageTxList: + description: Submission information list + properties: + list: + description: Submission list + items: + $ref: '#/definitions/api.StorageTxInfo' + type: array + total: + description: The total number of submission returned + type: integer + type: object + api.Summary: + description: Storage summary information + properties: + logSync: + allOf: + - $ref: '#/definitions/stat.LogSyncInfo' + description: Synchronization information of submit event + storageFee: + allOf: + - $ref: '#/definitions/api.StorageFeeStat' + description: Storage fee information + type: object api.TokenInfo: description: Charge token information properties: @@ -157,6 +284,9 @@ definitions: name: description: Token name type: string + native: + description: True is native token, otherwise is not + type: boolean symbol: description: Token symbol type: string @@ -265,10 +395,13 @@ definitions: type: integer type: object stat.LogSyncInfo: + description: Submit log sync information properties: - l2LogSyncHeight: + layer1-logSyncHeight: + description: Synchronization height of submit log on blockchain type: integer logSyncHeight: + description: Synchronization height of submit log on storage node type: integer type: object info: @@ -277,6 +410,54 @@ info: title: 0G Storage Scan API version: "1.0" paths: + /accounts/{address}/txs: + get: + consumes: + - application/json + description: Query storage transactions for specified account, support root + hash filter + parameters: + - description: The submitter address of the uploaded file + in: path + name: address + type: string + - default: 0 + description: The number of skipped records, usually it's pageSize * (pageNumber + - 1) + in: query + minimum: 0 + name: skip + type: integer + - default: 10 + description: The number of records displayed on the page + in: query + maximum: 100 + minimum: 1 + name: limit + type: integer + - description: The merkle root hash of the uploaded file + in: query + name: rootHash + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/api.BusinessError' + - properties: + Data: + $ref: '#/definitions/api.StorageTxList' + type: object + "600": + description: "" + schema: + $ref: '#/definitions/api.BusinessError' + summary: Account's storage transaction list + tags: + - account /statistic/dashboard: get: description: Query statistics dashboard includes `storage fee` and `log sync @@ -299,7 +480,7 @@ paths: $ref: '#/definitions/api.BusinessError' summary: Statistics dashboard tags: - - statistic + - (deprecated)statistic /statistic/fee/list: get: consumes: @@ -363,7 +544,7 @@ paths: $ref: '#/definitions/api.BusinessError' summary: fee statistics tags: - - statistic + - (deprecated)statistic /statistic/storage/list: get: consumes: @@ -427,7 +608,7 @@ paths: $ref: '#/definitions/api.BusinessError' summary: Data storage statistics tags: - - statistic + - (deprecated)statistic /statistic/transaction/list: get: consumes: @@ -491,6 +672,220 @@ paths: $ref: '#/definitions/api.BusinessError' summary: Transaction statistics tags: + - (deprecated)statistic + /stats/fee: + get: + consumes: + - application/json + description: Query fee statistics, including incremental and full data, and + support querying at hourly or daily time intervals + parameters: + - default: 0 + description: The number of skipped records, usually it's pageSize * (pageNumber + - 1) + in: query + minimum: 0 + name: skip + type: integer + - default: 10 + description: The number of records displayed on the page + in: query + maximum: 2000 + minimum: 1 + name: limit + type: integer + - description: Timestamp in seconds + in: query + name: minTimestamp + type: integer + - description: Timestamp in seconds + in: query + name: maxTimestamp + type: integer + - default: day + description: Statistics interval + enum: + - hour + - day + in: query + name: intervalType + type: string + - default: desc + description: Sort by timestamp + enum: + - asc + - desc + in: query + name: sort + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/api.BusinessError' + - properties: + Data: + $ref: '#/definitions/api.FeeStatList' + type: object + "600": + description: "" + schema: + $ref: '#/definitions/api.BusinessError' + summary: Storage fee statistics + tags: + - statistic + /stats/layer1-tx: + get: + consumes: + - application/json + description: Query transaction statistics, including incremental and full data, + and support querying at hourly or daily time intervals + parameters: + - default: 0 + description: The number of skipped records, usually it's pageSize * (pageNumber + - 1) + in: query + minimum: 0 + name: skip + type: integer + - default: 10 + description: The number of records displayed on the page + in: query + maximum: 2000 + minimum: 1 + name: limit + type: integer + - description: Timestamp in seconds + in: query + name: minTimestamp + type: integer + - description: Timestamp in seconds + in: query + name: maxTimestamp + type: integer + - default: day + description: Statistics interval + enum: + - hour + - day + in: query + name: intervalType + type: string + - default: desc + description: Sort by timestamp + enum: + - asc + - desc + in: query + name: sort + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/api.BusinessError' + - properties: + Data: + $ref: '#/definitions/api.TxStatList' + type: object + "600": + description: "" + schema: + $ref: '#/definitions/api.BusinessError' + summary: Layer1 transaction statistics + tags: + - statistic + /stats/storage: + get: + consumes: + - application/json + description: Query data storage statistics, including incremental and full data, + and support querying at hourly or daily time intervals + parameters: + - default: 0 + description: The number of skipped records, usually it's pageSize * (pageNumber + - 1) + in: query + minimum: 0 + name: skip + type: integer + - default: 10 + description: The number of records displayed on the page + in: query + maximum: 2000 + minimum: 1 + name: limit + type: integer + - description: Timestamp in seconds + in: query + name: minTimestamp + type: integer + - description: Timestamp in seconds + in: query + name: maxTimestamp + type: integer + - default: day + description: Statistics interval + enum: + - hour + - day + in: query + name: intervalType + type: string + - default: desc + description: Sort by timestamp + enum: + - asc + - desc + in: query + name: sort + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/api.BusinessError' + - properties: + Data: + $ref: '#/definitions/api.DataStatList' + type: object + "600": + description: "" + schema: + $ref: '#/definitions/api.BusinessError' + summary: Data storage statistics + tags: + - statistic + /stats/summary: + get: + description: Query statistics summary includes `storage fee` and `log sync height` + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/api.BusinessError' + - properties: + Data: + $ref: '#/definitions/api.Summary' + type: object + "600": + description: "" + schema: + $ref: '#/definitions/api.BusinessError' + summary: Statistics summary + tags: - statistic /transaction/brief: get: @@ -521,7 +916,7 @@ paths: $ref: '#/definitions/api.BusinessError' summary: Layer2 transaction overview tags: - - transaction + - (deprecated)transaction /transaction/detail: get: consumes: @@ -551,7 +946,7 @@ paths: $ref: '#/definitions/api.BusinessError' summary: Layer2 transaction advanced info tags: - - transaction + - (deprecated)transaction /transaction/list: get: consumes: @@ -598,5 +993,74 @@ paths: $ref: '#/definitions/api.BusinessError' summary: Layer2 transaction list tags: + - (deprecated)transaction + /txs: + get: + consumes: + - application/json + description: Query storage transactions, support address and root hash filter + parameters: + - default: 0 + description: The number of skipped records, usually it's pageSize * (pageNumber + - 1) + in: query + minimum: 0 + name: skip + type: integer + - default: 10 + description: The number of records displayed on the page + in: query + maximum: 100 + minimum: 1 + name: limit + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/api.BusinessError' + - properties: + Data: + $ref: '#/definitions/api.StorageTxList' + type: object + "600": + description: "" + schema: + $ref: '#/definitions/api.BusinessError' + summary: Storage transaction list + tags: + - transaction + /txs/{txSeq}: + get: + consumes: + - application/json + description: Query storage transaction by txSeq + parameters: + - description: storage transaction sequence number + in: path + name: txSeq + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/api.BusinessError' + - properties: + Data: + $ref: '#/definitions/api.StorageTxDetail' + type: object + "600": + description: "" + schema: + $ref: '#/definitions/api.BusinessError' + summary: Storage transaction information + tags: - transaction swagger: "2.0" diff --git a/stat/stat_sync_status.go b/stat/stat_sync_status.go index 752d0de..da14d3c 100644 --- a/stat/stat_sync_status.go +++ b/stat/stat_sync_status.go @@ -66,8 +66,8 @@ func (s *LogSyncInfoStat) DoStat(ctx context.Context, wg *sync.WaitGroup) { } status := LogSyncInfo{ - LogSyncHeight: block.BlockNumber, - L2LogSyncHeight: nodeStatus.LogSyncHeight, + Layer1LogSyncHeight: block.BlockNumber, + LogSyncHeight: nodeStatus.LogSyncHeight, } statusBytes, err := json.Marshal(status) if err != nil { diff --git a/stat/types.go b/stat/types.go index b3a3b50..9fe672f 100644 --- a/stat/types.go +++ b/stat/types.go @@ -1,6 +1,8 @@ package stat +// LogSyncInfo model info +// @Description Submit log sync information type LogSyncInfo struct { - LogSyncHeight uint64 `json:"logSyncHeight"` - L2LogSyncHeight uint64 `json:"l2LogSyncHeight"` + Layer1LogSyncHeight uint64 `json:"layer1-logSyncHeight"` // Synchronization height of submit log on blockchain + LogSyncHeight uint64 `json:"logSyncHeight"` // Synchronization height of submit log on storage node } diff --git a/store/store.go b/store/store.go index 337f24d..535db4f 100644 --- a/store/store.go +++ b/store/store.go @@ -117,7 +117,7 @@ func SenderID(si uint64) func(db *gorm.DB) *gorm.DB { func RootHash(rh string) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { - return db.Where("root_hash = ?", strings.ToLower(strings.TrimPrefix(rh, "0x"))) + return db.Where("root_hash = ?", strings.ToLower(rh)) } } diff --git a/store/store_address_submit.go b/store/store_address_submit.go index 302e618..f7fa502 100644 --- a/store/store_address_submit.go +++ b/store/store_address_submit.go @@ -71,9 +71,9 @@ func (ass *AddressSubmitStore) List(addressID *uint64, rootHash *string, idDesc var orderBy string if idDesc { - orderBy = "sender_id DESC" + orderBy = "submission_index DESC" } else { - orderBy = "sender_id ASC" + orderBy = "submission_index ASC" } list := new([]AddressSubmit)