Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add open api for account info. #21

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions api/account_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package api

import (
"github.com/ethereum/go-ethereum/common"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/shopspring/decimal"
"github.com/sirupsen/logrus"
)

func getAccountInfo(c *gin.Context) (interface{}, error) {
addressInfo, err := getAddressInfo(c)
if err != nil {
return nil, err
}

addr := common.HexToAddress(addressInfo.address)
balance, err := sdk.Eth.Balance(addr, nil)
if err != nil {
logrus.WithError(err).WithField("address", addressInfo.address).Error("Failed to get balance")
return nil, errors.Errorf("Get balance error, address %v", addressInfo.address)
}

submitStat, err := db.AddressSubmitStore.Count(&addressInfo.addressId)
if err != nil {
return nil, err
}

rewardStat, err := db.AddressRewardStore.Count(&addressInfo.addressId)
if err != nil {
return nil, err
}

accountInfo := AccountInfo{
Balance: decimal.NewFromBigInt(balance, 0),
FileCount: submitStat.FileCount,
TxCount: submitStat.TxCount,
DataSize: submitStat.DataSize,
StorageFee: submitStat.BaseFee,
RewardCount: rewardStat.RewardCount,
}

return accountInfo, nil
}
36 changes: 36 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"github.com/0glabs/0g-storage-scan/docs"
"github.com/0glabs/0g-storage-scan/store"
"github.com/Conflux-Chain/go-conflux-util/api"
commonApi "github.com/Conflux-Chain/go-conflux-util/api"
viperUtil "github.com/Conflux-Chain/go-conflux-util/viper"
"github.com/gin-gonic/gin"
"github.com/openweb3/web3go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
Expand Down Expand Up @@ -82,6 +84,7 @@ func RegisterRouter(router *gin.Engine) {
rewardsRoute.GET("", listRewardsHandler)

accountsRoute := apiRoute.Group("/accounts")
accountsRoute.GET(":address", getAccountInfoHandler)
accountsRoute.GET(":address/txs", listAddressTxsHandler)
accountsRoute.GET(":address/rewards", listAddressRewardsHandler)

Expand Down Expand Up @@ -208,6 +211,21 @@ func listRewardsHandler(c *gin.Context) {
api.Wrap(listStorageRewards)(c)
}

// getAccountInfoHandler godoc
//
// @Summary Account's information
// @Description Query account information for specified account
// @Tags account
// @Accept json
// @Produce json
// @Param address path string false "The account address"
// @Success 200 {object} api.BusinessError{Data=AccountInfo}
// @Failure 600 {object} api.BusinessError
// @Router /accounts/{address} [get]
func getAccountInfoHandler(c *gin.Context) {
api.Wrap(getAccountInfo)(c)
}

// listAddressTxsHandler godoc
//
// @Summary Account's storage transaction list
Expand Down Expand Up @@ -242,3 +260,21 @@ func listAddressTxsHandler(c *gin.Context) {
func listAddressRewardsHandler(c *gin.Context) {
api.Wrap(listAddressStorageRewards)(c)
}

func getAddressInfo(c *gin.Context) (*AddressInfo, error) {
address := c.Param("address")
if address == "" {
logrus.Error("Failed to parse nil address")
return nil, errors.Errorf("Biz error, nil address %v", address)
}

addressInfo, exist, err := db.AddressStore.Get(address)
if err != nil {
return nil, commonApi.ErrInternal(err)
}
if !exist {
return nil, ErrAddressNotFound
}

return &AddressInfo{address, addressInfo.ID}, nil
}
18 changes: 3 additions & 15 deletions api/reward_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ package api

import (
"github.com/0glabs/0g-storage-scan/store"
commonApi "github.com/Conflux-Chain/go-conflux-util/api"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

func listStorageRewards(c *gin.Context) (interface{}, error) {
Expand All @@ -22,19 +19,11 @@ func listStorageRewards(c *gin.Context) (interface{}, error) {
return convertStorageRewards(total, rewards)
}
func listAddressStorageRewards(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)
addressInfo, err := getAddressInfo(c)
if err != nil {
return nil, commonApi.ErrInternal(err)
}
if !exist {
return RewardList{}, nil
return nil, err
}
addrIDPtr := &addr.ID
addrIDPtr := &addressInfo.addressId

var param PageParam
if err := c.ShouldBind(&param); err != nil {
Expand Down Expand Up @@ -87,7 +76,6 @@ func convertStorageRewards(total int64, rewards []store.Reward) (*RewardList, er
storageRewards := make([]Reward, 0)
for _, r := range rewards {
storageReward := Reward{
RewardSeq: r.PricingIndex,
Miner: addrMap[r.MinerID].Address,
Amount: r.Amount,
BlockNumber: r.BlockNumber,
Expand Down
17 changes: 3 additions & 14 deletions api/tx_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import (
"strconv"

"github.com/0glabs/0g-storage-client/core"

commonApi "github.com/Conflux-Chain/go-conflux-util/api"

"github.com/0glabs/0g-storage-scan/store"
"github.com/ethereum/go-ethereum/common"
"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -96,19 +93,11 @@ func getStorageTx(c *gin.Context) (interface{}, error) {
}

func listAddressStorageTxs(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)
addressInfo, err := getAddressInfo(c)
if err != nil {
return nil, commonApi.ErrInternal(err)
}
if !exist {
return StorageTxList{}, nil
return nil, err
}
addrIDPtr := &addr.ID
addrIDPtr := &addressInfo.addressId

var param listAddressStorageTxParam
if err := c.ShouldBind(&param); err != nil {
Expand Down
18 changes: 16 additions & 2 deletions api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"time"

"github.com/0glabs/0g-storage-scan/stat"

"github.com/shopspring/decimal"
)

Expand Down Expand Up @@ -166,10 +165,25 @@ type RewardList struct {
// Reward model info
// @Description Reward information
type Reward struct {
RewardSeq uint64 `json:"rewardSeq"` // Pricing index for reward
Miner string `json:"miner"` // Miner address
Amount decimal.Decimal `json:"amount"` // The reward amount
BlockNumber uint64 `json:"blockNumber"` // The block where the reward event is emitted
TxHash string `json:"txHash"` // The transaction where the reward event is emitted
Timestamp int64 `json:"timestamp"` // The block time when reward event emits
}

type AddressInfo struct {
address string
addressId uint64
}

type AccountInfo struct {
Balance decimal.Decimal `json:"balance"` // The balance in layer 1

FileCount uint64 `json:"fileCount"` // Total number of files
TxCount uint64 `json:"txCount"` // Total number of layer1 transaction
DataSize uint64 `json:"dataTotal"` // Total Size of storage data
StorageFee decimal.Decimal `json:"storageFeeTotal"` // Total storage fee

RewardCount uint64 `json:"rewardCount"` // Total number of distributed reward recodes
}
37 changes: 31 additions & 6 deletions store/store_address_reward.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import (
"time"

"github.com/Conflux-Chain/go-conflux-util/store/mysql"
"github.com/pkg/errors"
"github.com/shopspring/decimal"
"gorm.io/gorm"
)

type AddressReward struct {
MinerID uint64 `gorm:"primaryKey;autoIncrement:false"`
PricingIndex uint64 `gorm:"primaryKey;autoIncrement:false"`
Amount decimal.Decimal `gorm:"type:decimal(65);not null"`
BlockNumber uint64 `gorm:"not null;index:idx_bn"`
BlockNumber uint64 `gorm:"primaryKey;autoIncrement:false;index:idx_bn"`
BlockTime time.Time `gorm:"not null"`
TxHash string `gorm:"size:66;not null"`
PricingIndex uint64 `gorm:"not null"`
Amount decimal.Decimal `gorm:"type:decimal(65);not null"`
}

func (AddressReward) TableName() string {
Expand All @@ -40,11 +41,13 @@ func (ars *AddressRewardStore) Pop(dbTx *gorm.DB, block uint64) error {
}

func (ars *AddressRewardStore) List(addressID *uint64, idDesc bool, skip, limit int) (int64, []AddressReward, error) {
if addressID == nil {
return 0, nil, errors.New("nil addressID")
}

dbRaw := ars.DB.Model(&AddressReward{})
var conds []func(db *gorm.DB) *gorm.DB
if addressID != nil {
conds = append(conds, MinerID(*addressID))
}
conds = append(conds, MinerID(*addressID))
dbRaw.Scopes(conds...)

var orderBy string
Expand All @@ -62,3 +65,25 @@ func (ars *AddressRewardStore) List(addressID *uint64, idDesc bool, skip, limit

return total, *list, nil
}

type RewardStatResult struct {
RewardCount uint64
RewardAmount decimal.Decimal
}

func (ars *AddressRewardStore) Count(addressID *uint64) (*RewardStatResult, error) {
if addressID == nil {
return nil, errors.New("nil addressID")
}

var result RewardStatResult
err := ars.DB.Model(&AddressReward{}).
Select(`count(*) as reward_count,IFNULL(sum(amount), 0) as reward_amount`).
Where("miner_id = ?", addressID).
Find(&result).Error
if err != nil {
return nil, err
}

return &result, nil
}
26 changes: 22 additions & 4 deletions store/store_address_submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"time"

"github.com/Conflux-Chain/go-conflux-util/store/mysql"
"github.com/pkg/errors"
"github.com/shopspring/decimal"
"gorm.io/gorm"
)
Expand Down Expand Up @@ -62,12 +63,13 @@ func (ass *AddressSubmitStore) UpdateByPrimaryKey(dbTx *gorm.DB, s *AddressSubmi

func (ass *AddressSubmitStore) List(addressID *uint64, rootHash *string, idDesc bool, skip, limit int) (int64,
[]AddressSubmit, error) {
dbRaw := ass.DB.Model(&AddressSubmit{})
if addressID == nil {
return 0, nil, errors.New("nil addressID")
}

dbRaw := ass.DB.Model(&AddressSubmit{})
var conds []func(db *gorm.DB) *gorm.DB
if addressID != nil {
conds = append(conds, SenderID(*addressID))
}
conds = append(conds, SenderID(*addressID))
if rootHash != nil {
conds = append(conds, RootHash(*rootHash))
}
Expand All @@ -88,3 +90,19 @@ func (ass *AddressSubmitStore) List(addressID *uint64, rootHash *string, idDesc

return total, *list, nil
}

func (ass *AddressSubmitStore) Count(addressID *uint64) (*SubmitStatResult, error) {
if addressID == nil {
return nil, errors.New("nil addressID")
}

var result SubmitStatResult
err := ass.DB.Model(&AddressSubmit{}).Select(`count(submission_index) as file_count,
IFNULL(sum(length), 0) as data_size, IFNULL(sum(fee), 0) as base_fee, count(distinct tx_hash) as tx_count`).
Where("sender_id = ?", addressID).Find(&result).Error
if err != nil {
return nil, err
}

return &result, nil
}
12 changes: 6 additions & 6 deletions store/store_reward.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import (
)

type Reward struct {
PricingIndex uint64 `gorm:"primaryKey;autoIncrement:false"`
BlockNumber uint64 `gorm:"primaryKey;autoIncrement:false"`
BlockTime time.Time `gorm:"not null"`
TxHash string `gorm:"size:66;not null"`
Miner string `gorm:"-"`
MinerID uint64 `gorm:"not null"`
PricingIndex uint64 `gorm:"not null"`
Amount decimal.Decimal `gorm:"type:decimal(65);not null"`
BlockNumber uint64 `gorm:"not null;index:idx_bn"`
BlockTime time.Time `gorm:"not null"`
TxHash string `gorm:"size:66;not null"`
}

func NewReward(blockTime time.Time, log types.Log, filter *nhContract.OnePoolRewardFilterer) (*Reward, error) {
Expand Down Expand Up @@ -65,9 +65,9 @@ func (rs *RewardStore) List(idDesc bool, skip, limit int) (int64, []Reward, erro

var orderBy string
if idDesc {
orderBy = "pricing_index DESC"
orderBy = "block_number DESC"
} else {
orderBy = "pricing_index ASC"
orderBy = "block_number ASC"
}

list := new([]Reward)
Expand Down
Loading