diff --git a/api/tx_api.go b/api/tx_api.go index 4a09953..91c7a63 100644 --- a/api/tx_api.go +++ b/api/tx_api.go @@ -1,10 +1,10 @@ package api import ( - "encoding/hex" "encoding/json" "strconv" + "github.com/0glabs/0g-storage-client/core" "github.com/0glabs/0g-storage-scan/store" commonApi "github.com/Conflux-Chain/go-conflux-util/api" "github.com/ethereum/go-ethereum/common" @@ -48,16 +48,18 @@ 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, - 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, + TotalSegNum: submit.TotalSegNum, + UploadedSegNum: submit.UploadedSegNum, + Timestamp: submit.BlockTime.Unix(), + DataSize: submit.Length, + BaseFee: submit.Fee, } storageTxs = append(storageTxs, storageTx) } @@ -146,21 +148,12 @@ func getTxDetail(c *gin.Context) (interface{}, error) { return nil, errors.Errorf("Unmarshal submit extra error, txSeq %v", *param.TxSeq) } - nodes := make([]SubmissionNode, 0) - for _, n := range extra.Submission.Nodes { - nodes = append(nodes, SubmissionNode{ - Root: "0x" + hex.EncodeToString(n.Root[:]), - Height: n.Height, - }) - } - result := TxDetail{ TxSeq: strconv.FormatUint(submit.SubmissionIndex, 10), RootHash: submit.RootHash, StartPos: extra.StartPos.Uint64(), EndPos: extra.StartPos.Uint64() + submit.Length, - PieceCounts: uint64(len(nodes)), - Pieces: nodes, + PieceCounts: (submit.Length-1)/core.DefaultSegmentSize + 1, } return result, nil @@ -187,6 +180,8 @@ func listSubmits(addressID *uint64, rootHash *string, idDesc bool, skip, limit i BlockTime: as.BlockTime, TxHash: as.TxHash, Status: as.Status, + TotalSegNum: as.TotalSegNum, + UploadedSegNum: as.UploadedSegNum, Fee: as.Fee, }) } diff --git a/api/types.go b/api/types.go index ef773c3..c31446c 100644 --- a/api/types.go +++ b/api/types.go @@ -1,7 +1,6 @@ package api import ( - "math/big" "strings" "time" @@ -41,111 +40,135 @@ type queryTxParam struct { TxSeq *uint64 `form:"txSeq" binding:"required,number,gte=0"` } +// StorageTx model info +// @Description Submission information type StorageTx struct { - TxSeq uint64 `json:"txSeq"` - BlockNum uint64 `json:"blockNum"` - TxHash string `json:"txHash"` - RootHash string `json:"rootHash"` - Address string `json:"address"` - Method string `json:"method"` - Status uint64 `json:"status"` - Timestamp int64 `json:"timestamp"` - DataSize uint64 `json:"dataSize"` - BaseFee decimal.Decimal `json:"baseFee"` -} - + 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 +} + +// TokenInfo model info +// @Description Charge token information type TokenInfo struct { - Address string `json:"address"` - Name string `json:"name"` - Symbol string `json:"symbol"` - Decimals uint8 `json:"decimals"` + Address string `json:"address"` // The address of the token contract + Name string `json:"name"` // Token name + Symbol string `json:"symbol"` // Token symbol + Decimals uint8 `json:"decimals"` // Token decimals } +// CostInfo model info +// @Description Charge fee information type CostInfo struct { - TokenInfo `json:"tokenInfo"` - BasicCost decimal.Decimal `json:"basicCost"` -} - -type SubmissionNode struct { - Root string `json:"root"` - Height *big.Int `json:"height"` + TokenInfo `json:"tokenInfo"` // Charge token info + BasicCost decimal.Decimal `json:"basicCost"` // Charge fee } +// TxList model info +// @Description Submission information list type TxList struct { - Total int64 `json:"total"` - List []StorageTx `json:"list"` + Total int64 `json:"total"` // The total number of submission returned + List []StorageTx `json:"list"` // Submission list } +// TxBrief model info +// @Description Submission brief information type TxBrief struct { - TxSeq string `json:"txSeq"` - From string `json:"from"` - Method string `json:"method"` - - RootHash string `json:"rootHash"` - DataSize uint64 `json:"dataSize"` - Expiration uint64 `json:"expiration"` - CostInfo *CostInfo `json:"costInfo"` - - BlockNumber uint64 `json:"blockNumber"` - TxHash string `json:"txHash"` - Timestamp uint64 `json:"timestamp"` - Status uint64 `json:"status"` - GasFee uint64 `json:"gasFee"` - GasUsed uint64 `json:"gasUsed"` - GasLimit uint64 `json:"gasLimit"` -} - + 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 + CostInfo *CostInfo `json:"costInfo"` // Charge fee information + + 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 + Status uint8 `json:"status"` // The status of the transaction on layer1 + 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 +} + +// TxDetail model info +// @Description Submission detail information type TxDetail struct { - TxSeq string `json:"txSeq"` - RootHash string `json:"rootHash"` + TxSeq string `json:"txSeq"` // Submission index in submit event + RootHash string `json:"rootHash"` // Merkle root of the file to upload - StartPos uint64 `json:"startPos"` - EndPos uint64 `json:"endPos"` - PieceCounts uint64 `json:"pieceCounts"` - Pieces []SubmissionNode `json:"pieces"` + StartPos uint64 `json:"startPos"` // The starting position of the file stored in the storage node + EndPos uint64 `json:"endPos"` // The ending position of the file stored in the storage node + PieceCounts uint64 `json:"pieceCounts"` // The total number of segments the file is split into } +// StorageBasicCost model info +// @Description Storage fee information type StorageBasicCost struct { - TokenInfo - BasicCostTotal decimal.Decimal `json:"basicCostTotal"` + TokenInfo // Charge token info + BasicCostTotal decimal.Decimal `json:"basicCostTotal"` // Total storage fee } +// Dashboard model info +// @Description Storage status information type Dashboard struct { - StorageBasicCost `json:"storageBasicCost"` - stat.LogSyncInfo `json:"logSyncInfo"` + StorageBasicCost `json:"storageBasicCost"` // Storage fee information + stat.LogSyncInfo `json:"logSyncInfo"` // Synchronization information of submit event } +// DataStatList model info +// @Description Storage data list type DataStatList struct { - Total int64 `json:"total"` - List []DataStat `json:"list"` + Total int64 `json:"total"` // The total number of stat returned + List []DataStat `json:"list"` // Stat list } +// TxStatList model info +// @Description Storage transaction list type TxStatList struct { - Total int64 `json:"total"` - List []TxStat `json:"list"` + Total int64 `json:"total"` // The total number of stat returned + List []TxStat `json:"list"` // Stat list } +// FeeStatList model info +// @Description Storage fee list type FeeStatList struct { - Total int64 `json:"total"` - List []FeeStat `json:"list"` + Total int64 `json:"total"` // The total number of stat returned + List []FeeStat `json:"list"` // Stat list } +// DataStat model info +// @Description Storage data information type DataStat struct { - StatTime time.Time `json:"statTime"` - FileCount uint64 `json:"fileCount"` - FileTotal uint64 `json:"fileTotal"` - DataSize uint64 `json:"dataSize"` - DataTotal uint64 `json:"dataTotal"` + StatTime time.Time `json:"statTime"` // Statistics time + FileCount uint64 `json:"fileCount"` // Number of files in a specific time interval + FileTotal uint64 `json:"fileTotal"` // Total number of files by a certain time + DataSize uint64 `json:"dataSize"` // Size of storage data in a specific time interval + DataTotal uint64 `json:"dataTotal"` // Total Size of storage data by a certain time } +// TxStat model info +// @Description Storage transaction information type TxStat struct { - StatTime time.Time `json:"statTime"` - TxCount uint64 `json:"txCount"` - TxTotal uint64 `json:"txTotal"` + StatTime time.Time `json:"statTime"` // Statistics time + TxCount uint64 `json:"txCount"` // Number of layer1 transaction in a specific time interval + TxTotal uint64 `json:"txTotal"` // Total number of layer1 transaction by a certain time } +// FeeStat model info +// @Description Storage fee information type FeeStat struct { - StatTime time.Time `json:"statTime"` - BaseFee decimal.Decimal `json:"baseFee"` - BaseFeeTotal decimal.Decimal `json:"baseFeeTotal"` + 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 } diff --git a/docs/docs.go b/docs/docs.go index 80785bb..f36ee48 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -522,290 +522,369 @@ const docTemplate = `{ } }, "api.CostInfo": { + "description": "Charge fee information", "type": "object", "properties": { "basicCost": { + "description": "Charge fee", "type": "number" }, "tokenInfo": { - "$ref": "#/definitions/api.TokenInfo" + "description": "Charge token info", + "allOf": [ + { + "$ref": "#/definitions/api.TokenInfo" + } + ] } } }, "api.Dashboard": { + "description": "Storage status information", "type": "object", "properties": { "logSyncInfo": { - "$ref": "#/definitions/stat.LogSyncInfo" + "description": "Synchronization information of submit event", + "allOf": [ + { + "$ref": "#/definitions/stat.LogSyncInfo" + } + ] }, "storageBasicCost": { - "$ref": "#/definitions/api.StorageBasicCost" + "description": "Storage fee information", + "allOf": [ + { + "$ref": "#/definitions/api.StorageBasicCost" + } + ] } } }, "api.DataStat": { + "description": "Storage data information", "type": "object", "properties": { "dataSize": { + "description": "Size of storage data in a specific time interval", "type": "integer" }, "dataTotal": { + "description": "Total Size of storage data by a certain time", "type": "integer" }, "fileCount": { + "description": "Number of files in a specific time interval", "type": "integer" }, "fileTotal": { + "description": "Total number of files by a certain time", "type": "integer" }, "statTime": { + "description": "Statistics time", "type": "string" } } }, "api.DataStatList": { + "description": "Storage data list", "type": "object", "properties": { "list": { + "description": "Stat list", "type": "array", "items": { "$ref": "#/definitions/api.DataStat" } }, "total": { + "description": "The total number of stat returned", "type": "integer" } } }, "api.FeeStat": { + "description": "Storage fee information", "type": "object", "properties": { "baseFee": { + "description": "The base fee for storage in a specific time interval", "type": "number" }, "baseFeeTotal": { + "description": "The total base fee for storage by a certain time", "type": "number" }, "statTime": { + "description": "Statistics time", "type": "string" } } }, "api.FeeStatList": { + "description": "Storage fee list", "type": "object", "properties": { "list": { + "description": "Stat list", "type": "array", "items": { "$ref": "#/definitions/api.FeeStat" } }, "total": { + "description": "The total number of stat returned", "type": "integer" } } }, "api.StorageBasicCost": { + "description": "Storage fee information", "type": "object", "properties": { "address": { + "description": "The address of the token contract", "type": "string" }, "basicCostTotal": { + "description": "Total storage fee", "type": "number" }, "decimals": { + "description": "Token decimals", "type": "integer" }, "name": { + "description": "Token name", "type": "string" }, "symbol": { + "description": "Token symbol", "type": "string" } } }, "api.StorageTx": { + "description": "Submission information", "type": "object", "properties": { "address": { + "description": "File uploader address", "type": "string" }, "baseFee": { + "description": "The token fee required to upload the file", "type": "number" }, "blockNum": { + "description": "The block where the submit event is emitted", "type": "integer" }, "dataSize": { + "description": "File size in bytes", "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" }, "status": { + "description": "File upload status, 0-not uploaded,1-uploading,2-uploaded", "type": "integer" }, "timestamp": { + "description": "The block time when submit event emits", + "type": "integer" + }, + "totalSegNum": { + "description": "The total number of segments the file is split into", "type": "integer" }, "txHash": { + "description": "The transaction where the submit event is emitted", "type": "string" }, "txSeq": { + "description": "Submission index in submit event", "type": "integer" - } - } - }, - "api.SubmissionNode": { - "type": "object", - "properties": { - "height": { - "$ref": "#/definitions/big.Int" }, - "root": { - "type": "string" + "uploadedSegNum": { + "description": "The number of segments the file has been uploaded", + "type": "integer" } } }, "api.TokenInfo": { + "description": "Charge token information", "type": "object", "properties": { "address": { + "description": "The address of the token contract", "type": "string" }, "decimals": { + "description": "Token decimals", "type": "integer" }, "name": { + "description": "Token name", "type": "string" }, "symbol": { + "description": "Token symbol", "type": "string" } } }, "api.TxBrief": { + "description": "Submission brief information", "type": "object", "properties": { "blockNumber": { + "description": "The block where the submit event is emitted", "type": "integer" }, "costInfo": { - "$ref": "#/definitions/api.CostInfo" + "description": "Charge fee information", + "allOf": [ + { + "$ref": "#/definitions/api.CostInfo" + } + ] }, "dataSize": { + "description": "File size in bytes", "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" }, "status": { + "description": "The status of the transaction on layer1", "type": "integer" }, "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.TxDetail": { + "description": "Submission detail information", "type": "object", "properties": { "endPos": { + "description": "The ending position of the file stored in the storage node", "type": "integer" }, "pieceCounts": { + "description": "The total number of segments the file is split into", "type": "integer" }, - "pieces": { - "type": "array", - "items": { - "$ref": "#/definitions/api.SubmissionNode" - } - }, "rootHash": { + "description": "Merkle root of the file to upload", "type": "string" }, "startPos": { + "description": "The starting position of the file stored in the storage node", "type": "integer" }, "txSeq": { + "description": "Submission index in submit event", "type": "string" } } }, "api.TxList": { + "description": "Submission information list", "type": "object", "properties": { "list": { + "description": "Submission list", "type": "array", "items": { "$ref": "#/definitions/api.StorageTx" } }, "total": { + "description": "The total number of submission returned", "type": "integer" } } }, "api.TxStat": { + "description": "Storage transaction information", "type": "object", "properties": { "statTime": { + "description": "Statistics time", "type": "string" }, "txCount": { + "description": "Number of layer1 transaction in a specific time interval", "type": "integer" }, "txTotal": { + "description": "Total number of layer1 transaction by a certain time", "type": "integer" } } }, "api.TxStatList": { + "description": "Storage transaction list", "type": "object", "properties": { "list": { + "description": "Stat list", "type": "array", "items": { "$ref": "#/definitions/api.TxStat" } }, "total": { + "description": "The total number of stat returned", "type": "integer" } } }, - "big.Int": { - "type": "object" - }, "stat.LogSyncInfo": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index a800f89..8054296 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -514,290 +514,369 @@ } }, "api.CostInfo": { + "description": "Charge fee information", "type": "object", "properties": { "basicCost": { + "description": "Charge fee", "type": "number" }, "tokenInfo": { - "$ref": "#/definitions/api.TokenInfo" + "description": "Charge token info", + "allOf": [ + { + "$ref": "#/definitions/api.TokenInfo" + } + ] } } }, "api.Dashboard": { + "description": "Storage status information", "type": "object", "properties": { "logSyncInfo": { - "$ref": "#/definitions/stat.LogSyncInfo" + "description": "Synchronization information of submit event", + "allOf": [ + { + "$ref": "#/definitions/stat.LogSyncInfo" + } + ] }, "storageBasicCost": { - "$ref": "#/definitions/api.StorageBasicCost" + "description": "Storage fee information", + "allOf": [ + { + "$ref": "#/definitions/api.StorageBasicCost" + } + ] } } }, "api.DataStat": { + "description": "Storage data information", "type": "object", "properties": { "dataSize": { + "description": "Size of storage data in a specific time interval", "type": "integer" }, "dataTotal": { + "description": "Total Size of storage data by a certain time", "type": "integer" }, "fileCount": { + "description": "Number of files in a specific time interval", "type": "integer" }, "fileTotal": { + "description": "Total number of files by a certain time", "type": "integer" }, "statTime": { + "description": "Statistics time", "type": "string" } } }, "api.DataStatList": { + "description": "Storage data list", "type": "object", "properties": { "list": { + "description": "Stat list", "type": "array", "items": { "$ref": "#/definitions/api.DataStat" } }, "total": { + "description": "The total number of stat returned", "type": "integer" } } }, "api.FeeStat": { + "description": "Storage fee information", "type": "object", "properties": { "baseFee": { + "description": "The base fee for storage in a specific time interval", "type": "number" }, "baseFeeTotal": { + "description": "The total base fee for storage by a certain time", "type": "number" }, "statTime": { + "description": "Statistics time", "type": "string" } } }, "api.FeeStatList": { + "description": "Storage fee list", "type": "object", "properties": { "list": { + "description": "Stat list", "type": "array", "items": { "$ref": "#/definitions/api.FeeStat" } }, "total": { + "description": "The total number of stat returned", "type": "integer" } } }, "api.StorageBasicCost": { + "description": "Storage fee information", "type": "object", "properties": { "address": { + "description": "The address of the token contract", "type": "string" }, "basicCostTotal": { + "description": "Total storage fee", "type": "number" }, "decimals": { + "description": "Token decimals", "type": "integer" }, "name": { + "description": "Token name", "type": "string" }, "symbol": { + "description": "Token symbol", "type": "string" } } }, "api.StorageTx": { + "description": "Submission information", "type": "object", "properties": { "address": { + "description": "File uploader address", "type": "string" }, "baseFee": { + "description": "The token fee required to upload the file", "type": "number" }, "blockNum": { + "description": "The block where the submit event is emitted", "type": "integer" }, "dataSize": { + "description": "File size in bytes", "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" }, "status": { + "description": "File upload status, 0-not uploaded,1-uploading,2-uploaded", "type": "integer" }, "timestamp": { + "description": "The block time when submit event emits", + "type": "integer" + }, + "totalSegNum": { + "description": "The total number of segments the file is split into", "type": "integer" }, "txHash": { + "description": "The transaction where the submit event is emitted", "type": "string" }, "txSeq": { + "description": "Submission index in submit event", "type": "integer" - } - } - }, - "api.SubmissionNode": { - "type": "object", - "properties": { - "height": { - "$ref": "#/definitions/big.Int" }, - "root": { - "type": "string" + "uploadedSegNum": { + "description": "The number of segments the file has been uploaded", + "type": "integer" } } }, "api.TokenInfo": { + "description": "Charge token information", "type": "object", "properties": { "address": { + "description": "The address of the token contract", "type": "string" }, "decimals": { + "description": "Token decimals", "type": "integer" }, "name": { + "description": "Token name", "type": "string" }, "symbol": { + "description": "Token symbol", "type": "string" } } }, "api.TxBrief": { + "description": "Submission brief information", "type": "object", "properties": { "blockNumber": { + "description": "The block where the submit event is emitted", "type": "integer" }, "costInfo": { - "$ref": "#/definitions/api.CostInfo" + "description": "Charge fee information", + "allOf": [ + { + "$ref": "#/definitions/api.CostInfo" + } + ] }, "dataSize": { + "description": "File size in bytes", "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" }, "status": { + "description": "The status of the transaction on layer1", "type": "integer" }, "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.TxDetail": { + "description": "Submission detail information", "type": "object", "properties": { "endPos": { + "description": "The ending position of the file stored in the storage node", "type": "integer" }, "pieceCounts": { + "description": "The total number of segments the file is split into", "type": "integer" }, - "pieces": { - "type": "array", - "items": { - "$ref": "#/definitions/api.SubmissionNode" - } - }, "rootHash": { + "description": "Merkle root of the file to upload", "type": "string" }, "startPos": { + "description": "The starting position of the file stored in the storage node", "type": "integer" }, "txSeq": { + "description": "Submission index in submit event", "type": "string" } } }, "api.TxList": { + "description": "Submission information list", "type": "object", "properties": { "list": { + "description": "Submission list", "type": "array", "items": { "$ref": "#/definitions/api.StorageTx" } }, "total": { + "description": "The total number of submission returned", "type": "integer" } } }, "api.TxStat": { + "description": "Storage transaction information", "type": "object", "properties": { "statTime": { + "description": "Statistics time", "type": "string" }, "txCount": { + "description": "Number of layer1 transaction in a specific time interval", "type": "integer" }, "txTotal": { + "description": "Total number of layer1 transaction by a certain time", "type": "integer" } } }, "api.TxStatList": { + "description": "Storage transaction list", "type": "object", "properties": { "list": { + "description": "Stat list", "type": "array", "items": { "$ref": "#/definitions/api.TxStat" } }, "total": { + "description": "The total number of stat returned", "type": "integer" } } }, - "big.Int": { - "type": "object" - }, "stat.LogSyncInfo": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index ff6d795..ff52114 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -8,190 +8,262 @@ definitions: type: string type: object api.CostInfo: + description: Charge fee information properties: basicCost: + description: Charge fee type: number tokenInfo: - $ref: '#/definitions/api.TokenInfo' + allOf: + - $ref: '#/definitions/api.TokenInfo' + description: Charge token info type: object api.Dashboard: + description: Storage status information properties: logSyncInfo: - $ref: '#/definitions/stat.LogSyncInfo' + allOf: + - $ref: '#/definitions/stat.LogSyncInfo' + description: Synchronization information of submit event storageBasicCost: - $ref: '#/definitions/api.StorageBasicCost' + allOf: + - $ref: '#/definitions/api.StorageBasicCost' + description: Storage fee information type: object api.DataStat: + description: Storage data information properties: dataSize: + description: Size of storage data in a specific time interval type: integer dataTotal: + description: Total Size of storage data by a certain time type: integer fileCount: + description: Number of files in a specific time interval type: integer fileTotal: + description: Total number of files by a certain time type: integer statTime: + description: Statistics time type: string type: object api.DataStatList: + description: Storage data list properties: list: + description: Stat list items: $ref: '#/definitions/api.DataStat' type: array total: + description: The total number of stat returned type: integer type: object api.FeeStat: + description: Storage fee information properties: baseFee: + description: The base fee for storage in a specific time interval type: number baseFeeTotal: + 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 properties: list: + description: Stat list items: $ref: '#/definitions/api.FeeStat' type: array total: + description: The total number of stat returned type: integer type: object api.StorageBasicCost: + description: Storage fee information properties: address: + description: The address of the token contract type: string basicCostTotal: + description: Total storage fee type: number decimals: + description: Token decimals type: integer name: + description: Token name type: string symbol: + description: Token symbol type: string type: object api.StorageTx: + description: Submission information properties: address: + description: File uploader address type: string baseFee: + description: The token fee required to upload the file type: number blockNum: + description: The block where the submit event is emitted type: integer dataSize: + description: File size in bytes 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 status: + description: File upload status, 0-not uploaded,1-uploading,2-uploaded type: integer timestamp: + description: The block time when submit event emits + type: integer + totalSegNum: + description: The total number of segments the file is split into type: integer txHash: + description: The transaction where the submit event is emitted type: string txSeq: + description: Submission index in submit event + type: integer + uploadedSegNum: + description: The number of segments the file has been uploaded type: integer - type: object - api.SubmissionNode: - properties: - height: - $ref: '#/definitions/big.Int' - root: - type: string type: object api.TokenInfo: + description: Charge token information properties: address: + description: The address of the token contract type: string decimals: + description: Token decimals type: integer name: + description: Token name type: string symbol: + description: Token symbol type: string type: object api.TxBrief: + description: Submission brief information properties: blockNumber: + description: The block where the submit event is emitted type: integer costInfo: - $ref: '#/definitions/api.CostInfo' + allOf: + - $ref: '#/definitions/api.CostInfo' + description: Charge fee information dataSize: + description: File size in bytes 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 status: + description: The status of the transaction on layer1 type: integer 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.TxDetail: + description: Submission detail information properties: endPos: + description: The ending position of the file stored in the storage node type: integer pieceCounts: + description: The total number of segments the file is split into type: integer - pieces: - items: - $ref: '#/definitions/api.SubmissionNode' - type: array rootHash: + description: Merkle root of the file to upload type: string startPos: + description: The starting position of the file stored in the storage node type: integer txSeq: + description: Submission index in submit event type: string type: object api.TxList: + description: Submission information list properties: list: + description: Submission list items: $ref: '#/definitions/api.StorageTx' type: array total: + description: The total number of submission returned type: integer type: object api.TxStat: + description: Storage transaction information properties: statTime: + description: Statistics time type: string txCount: + description: Number of layer1 transaction in a specific time interval type: integer txTotal: + description: Total number of layer1 transaction by a certain time type: integer type: object api.TxStatList: + description: Storage transaction list properties: list: + description: Stat list items: $ref: '#/definitions/api.TxStat' type: array total: + description: The total number of stat returned type: integer type: object - big.Int: - type: object stat.LogSyncInfo: properties: l2LogSyncHeight: diff --git a/store/store.go b/store/store.go index 8d45626..337f24d 100644 --- a/store/store.go +++ b/store/store.go @@ -35,6 +35,24 @@ func MustNewStore(db *gorm.DB) *MysqlStore { } func (ms *MysqlStore) Push(block *Block, submits []*Submit) error { + addressSubmits := make([]AddressSubmit, 0) + if len(submits) > 0 { + for _, submit := range submits { + addressSubmit := AddressSubmit{ + SenderID: submit.SenderID, + SubmissionIndex: submit.SubmissionIndex, + RootHash: submit.RootHash, + Length: submit.Length, + BlockNumber: submit.BlockNumber, + BlockTime: submit.BlockTime, + TxHash: submit.TxHash, + Fee: submit.Fee, + TotalSegNum: submit.TotalSegNum, + } + addressSubmits = append(addressSubmits, addressSubmit) + } + } + return ms.Store.DB.Transaction(func(dbTx *gorm.DB) error { // save blocks if err := ms.BlockStore.Add(dbTx, block); err != nil { @@ -46,6 +64,9 @@ func (ms *MysqlStore) Push(block *Block, submits []*Submit) error { if err := ms.SubmitStore.Add(dbTx, submits); err != nil { return errors.WithMessage(err, "failed to save flow submits") } + if err := ms.AddressSubmitStore.Add(dbTx, addressSubmits); err != nil { + return errors.WithMessage(err, "failed to save address flow submits") + } } return nil diff --git a/store/store_address_submit.go b/store/store_address_submit.go index 5530803..302e618 100644 --- a/store/store_address_submit.go +++ b/store/store_address_submit.go @@ -18,8 +18,10 @@ type AddressSubmit struct { BlockTime time.Time `gorm:"not null"` TxHash string `gorm:"size:66;not null"` - Status uint64 `gorm:"not null;default:0"` - Fee decimal.Decimal `gorm:"type:decimal(65);not null"` + TotalSegNum uint64 `gorm:"not null;default:0"` + UploadedSegNum uint64 `gorm:"not null;default:0"` + Status uint8 `gorm:"not null;default:0"` + Fee decimal.Decimal `gorm:"type:decimal(65);not null"` } func (AddressSubmit) TableName() string { @@ -36,6 +38,10 @@ func newAddressSubmitStore(db *gorm.DB) *AddressSubmitStore { } } +func (ass *AddressSubmitStore) Add(dbTx *gorm.DB, addressSubmits []AddressSubmit) error { + return dbTx.CreateInBatches(addressSubmits, batchSizeInsert).Error +} + func (ass *AddressSubmitStore) UpdateByPrimaryKey(dbTx *gorm.DB, s *AddressSubmit) error { db := ass.DB if dbTx != nil { diff --git a/store/store_submit.go b/store/store_submit.go index 4adbdcd..bc0f788 100644 --- a/store/store_submit.go +++ b/store/store_submit.go @@ -6,6 +6,7 @@ import ( "time" "github.com/0glabs/0g-storage-client/contract" + "github.com/0glabs/0g-storage-client/core" "github.com/Conflux-Chain/go-conflux-util/store/mysql" "github.com/ethereum/go-ethereum/common" "github.com/openweb3/web3go/types" @@ -13,11 +14,12 @@ import ( "gorm.io/gorm" ) -type Status int +type Status uint8 const ( - NotFinalized Status = iota - Finalized + NotUploaded Status = iota + Uploading + Uploaded ) type Submit struct { @@ -31,8 +33,10 @@ type Submit struct { BlockTime time.Time `gorm:"not null"` TxHash string `gorm:"size:66;not null"` - Status uint64 `gorm:"not null;default:0"` - Fee decimal.Decimal `gorm:"type:decimal(65);not null"` + TotalSegNum uint64 `gorm:"not null;default:0"` + UploadedSegNum uint64 `gorm:"not null;default:0"` + Status uint8 `gorm:"not null;default:0"` + Fee decimal.Decimal `gorm:"type:decimal(65);not null"` Extra []byte `gorm:"type:mediumText"` // json field } @@ -58,15 +62,17 @@ func NewSubmit(blockTime time.Time, log types.Log, filter *contract.FlowFilterer return nil, err } + length := flowSubmit.Submission.Length.Uint64() submit := &Submit{ SubmissionIndex: flowSubmit.SubmissionIndex.Uint64(), RootHash: flowSubmit.Submission.Root().String(), Sender: flowSubmit.Sender.String(), - Length: flowSubmit.Submission.Length.Uint64(), + Length: length, BlockNumber: log.BlockNumber, BlockTime: blockTime, TxHash: log.TxHash.String(), Fee: decimal.NewFromBigInt(big.NewInt(0), 0), + TotalSegNum: (length-1)/core.DefaultSegmentSize + 1, Extra: extra, } @@ -88,27 +94,7 @@ func newSubmitStore(db *gorm.DB) *SubmitStore { } func (ss *SubmitStore) Add(dbTx *gorm.DB, submits []*Submit) error { - addressSubmits := make([]AddressSubmit, 0) - for _, submit := range submits { - addressSubmit := AddressSubmit{ - SenderID: submit.SenderID, - SubmissionIndex: submit.SubmissionIndex, - RootHash: submit.RootHash, - Length: submit.Length, - BlockNumber: submit.BlockNumber, - BlockTime: submit.BlockTime, - TxHash: submit.TxHash, - Fee: submit.Fee, - Status: submit.Status, - } - addressSubmits = append(addressSubmits, addressSubmit) - } - - if err := dbTx.CreateInBatches(submits, batchSizeInsert).Error; err != nil { - return err - } - - return dbTx.CreateInBatches(addressSubmits, batchSizeInsert).Error + return dbTx.CreateInBatches(submits, batchSizeInsert).Error } func (ss *SubmitStore) Pop(dbTx *gorm.DB, block uint64) error { @@ -167,8 +153,8 @@ func (ss *SubmitStore) List(rootHash *string, idDesc bool, skip, limit int) (int func (ss *SubmitStore) BatchGetNotFinalized(batch int) ([]Submit, error) { submits := new([]Submit) - if err := ss.DB.Raw("select submission_index, sender_id from submits where status = ? limit ?", - NotFinalized, batch).Scan(submits).Error; err != nil { + if err := ss.DB.Raw("select submission_index, sender_id from submits where status < ? limit ?", + Uploaded, batch).Scan(submits).Error; err != nil { return nil, err } diff --git a/sync/storage.go b/sync/storage.go index 480116c..fa0a021 100644 --- a/sync/storage.go +++ b/sync/storage.go @@ -65,14 +65,22 @@ func (ss *StorageSyncer) syncFileInfo() error { submit := store.Submit{ SubmissionIndex: s.SubmissionIndex, + UploadedSegNum: info.UploadedSegNum, } - if info.Finalized { - submit.Status = uint64(store.Finalized) + if !info.Finalized { + if info.UploadedSegNum == 0 { + submit.Status = uint8(store.NotUploaded) + } else { + submit.Status = uint8(store.Uploading) + } + } else { + submit.Status = uint8(store.Uploaded) } addressSubmit := store.AddressSubmit{ SenderID: s.SenderID, SubmissionIndex: s.SubmissionIndex, + UploadedSegNum: info.UploadedSegNum, Status: submit.Status, }