Skip to content

Commit

Permalink
EX-191: total and available balance sum
Browse files Browse the repository at this point in the history
  • Loading branch information
grkamil committed Sep 13, 2019
1 parent eabc8df commit fa35704
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 54 deletions.
64 changes: 36 additions & 28 deletions address/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,50 @@ import (
)

type Resource struct {
Address string `json:"address"`
BalanceSumInBaseCoin *string `json:"balanceSumInBaseCoin,omitempty"`
BalanceSumInUSD *string `json:"balanceSumInUSD,omitempty"`
Balances []resource.Interface `json:"balances"`
Address string `json:"address"`
Balances []resource.Interface `json:"balances"`
TotalBalanceSum *string `json:"total_balance_sum,omitempty"`
TotalBalanceSumUSD *string `json:"total_balance_sum_usd,omitempty"`
AvailableBalanceSum *string `json:"available_balance_sum,omitempty"`
AvailableBalanceSumUSD *string `json:"available_balance_sum_usd,omitempty"`
}

func (Resource) Transform(model resource.ItemInterface, params ...resource.ParamInterface) resource.Interface {
address := model.(models.Address)
balanceSumInBaseCoin, balanceSumInUSD := getBalanceSumParams(params...)
type Params struct {
AvailableBalanceSum *big.Float
AvailableBalanceSumUSD *big.Float
TotalBalanceSum *big.Float
TotalBalanceSumUSD *big.Float
}

return Resource{
Address: address.GetAddress(),
BalanceSumInBaseCoin: balanceSumInBaseCoin,
BalanceSumInUSD: balanceSumInUSD,
Balances: resource.TransformCollection(address.Balances, balance.Resource{}),
func (r Resource) Transform(model resource.ItemInterface, resourceParams ...resource.ParamInterface) resource.Interface {
address := model.(models.Address)
result := Resource{
Address: address.GetAddress(),
Balances: resource.TransformCollection(address.Balances, balance.Resource{}),
}
}

func getBalanceSumParams(params ...resource.ParamInterface) (*string, *string) {
if len(params) != 2 {
return nil, nil
if len(resourceParams) > 0 {
if params, ok := resourceParams[0].(Params); ok {
result.TotalBalanceSum, result.TotalBalanceSumUSD = r.getTotalBalanceParams(params)
result.AvailableBalanceSum, result.AvailableBalanceSumUSD = r.getAvailableBalanceParams(params)
}
}

var sumInUSD, sumInBaseCoin string
return result
}

if sum, ok := params[0].(*big.Float); ok && sum != nil {
sumInBaseCoin = helpers.PipStr2Bip(sum.String())
} else {
return nil, nil
}
// prepare available address balance
func (r Resource) getAvailableBalanceParams(params Params) (*string, *string) {
sum := helpers.PipStr2Bip(params.AvailableBalanceSum.String())
usd := helpers.PipStr2Bip(params.AvailableBalanceSumUSD.String())

if sum, ok := params[1].(*big.Float); ok && sum != nil {
sumInUSD = helpers.PipStr2Bip(sum.String())
} else {
return nil, nil
}
return &sum, &usd
}

// prepare total address balance
func (r Resource) getTotalBalanceParams(params Params) (*string, *string) {
sum := helpers.PipStr2Bip(params.TotalBalanceSum.String())
usd := helpers.PipStr2Bip(params.TotalBalanceSumUSD.String())

return &sumInBaseCoin, &sumInUSD
return &sum, &usd
}
29 changes: 23 additions & 6 deletions api/v1/addresses/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,33 @@ func GetAddress(c *gin.Context) {
}

// calculate overall address balance (with stakes) in base coin and fiat
var balanceSumInBaseCoin, balanceSumInUSD *big.Float
var availableBalanceSum, totalBalanceSum,
totalBalanceSumUSD, availableBalanceSumUSD *big.Float
if request.WithSum {
// get address stakes
addressStakes := explorer.StakeRepository.GetByAddress(*minterAddress)
balanceSumInBaseCoin = explorer.BalanceService.GetSumByBalancesAndStakes(model.Balances, addressStakes)
balanceSumInUSD = explorer.BalanceService.GetBalanceSumInUSDByBaseCoin(balanceSumInBaseCoin)

// compute available balance from address balances
availableBalanceSum = explorer.BalanceService.GetAvailableBalance(model.Balances)
availableBalanceSumUSD = explorer.BalanceService.GetBalanceSumInUSD(availableBalanceSum)

// compute total balance from address balances and stakes
totalBalanceSum = explorer.BalanceService.GetTotalBalance(model.Balances, addressStakes)
totalBalanceSumUSD = explorer.BalanceService.GetBalanceSumInUSD(totalBalanceSum)

c.JSON(http.StatusOK, gin.H{
"data": new(address.Resource).Transform(*model, address.Params{
AvailableBalanceSum: availableBalanceSum,
AvailableBalanceSumUSD: availableBalanceSumUSD,
TotalBalanceSum: totalBalanceSum,
TotalBalanceSumUSD: totalBalanceSumUSD,
}),
})

return
}

c.JSON(http.StatusOK, gin.H{
"data": new(address.Resource).Transform(*model, balanceSumInBaseCoin, balanceSumInUSD),
})
c.JSON(http.StatusOK, gin.H{"data": new(address.Resource).Transform(*model)})
}

// Get list of transactions by Minter address
Expand Down
39 changes: 30 additions & 9 deletions balance/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,18 @@ type CoinBalance struct {
Coin *models.Coin
}

func (s *Service) GetSumByBalancesAndStakes(addressBalances []*models.Balance, addressStakes []*models.Stake) *big.Float {
var balances []CoinBalance
func (s *Service) GetAvailableBalance(addressBalances []*models.Balance) *big.Float {
// fill coin balances slice from address balances
balances := s.transformAddressBalancesToCoinBalances(addressBalances)
// compute sum
sum := s.computeBalanceSum(balances)

// add to balances slice from address balances
for _, balance := range addressBalances {
balances = append(balances, CoinBalance{helpers.StringToBigInt(balance.Value), balance.Coin})
}
return new(big.Float).SetInt(sum)
}

func (s *Service) GetTotalBalance(addressBalances []*models.Balance, addressStakes []*models.Stake) *big.Float {
// fill coin balances slice from address balances
balances := s.transformAddressBalancesToCoinBalances(addressBalances)

// add or sum balances from address stakes
for _, stake := range addressStakes {
Expand All @@ -47,6 +52,16 @@ func (s *Service) GetSumByBalancesAndStakes(addressBalances []*models.Balance, a
}

// sum overall balances in base coin
sum := s.computeBalanceSum(balances)

return new(big.Float).SetInt(sum)
}

func (s *Service) GetBalanceSumInUSD(sumInBasecoin *big.Float) *big.Float {
return new(big.Float).Mul(sumInBasecoin, big.NewFloat(s.marketService.PriceChange.Price))
}

func (s *Service) computeBalanceSum(balances []CoinBalance) *big.Int {
sum := big.NewInt(0)
for _, balance := range balances {
// just add base coin to sum
Expand All @@ -64,9 +79,15 @@ func (s *Service) GetSumByBalancesAndStakes(addressBalances []*models.Balance, a
))
}

return new(big.Float).SetInt(sum)
return sum
}

func (s *Service) GetBalanceSumInUSDByBaseCoin(sumInBasecoin *big.Float) *big.Float {
return new(big.Float).Mul(sumInBasecoin, big.NewFloat(s.marketService.PriceChange.Price))
func (s *Service) transformAddressBalancesToCoinBalances(addressBalances []*models.Balance) []CoinBalance {
var balances []CoinBalance
// fill coin balances slice from address balances
for _, balance := range addressBalances {
balances = append(balances, CoinBalance{helpers.StringToBigInt(balance.Value), balance.Coin})
}

return balances
}
22 changes: 11 additions & 11 deletions validator/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ import (
)

type Resource struct {
PublicKey string `json:"public_key"`
Status *uint8 `json:"status"`
Meta resource.Interface `json:"meta"`
Stake *string `json:"stake"`
Part *string `json:"part"`
PublicKey string `json:"public_key"`
Status *uint8 `json:"status"`
Meta resource.Interface `json:"meta"`
Stake *string `json:"stake"`
Part *string `json:"part"`
DelegatorCount *int `json:"delegator_count,omitempty"`
DelegatorList *[]resource.Interface `json:"delegator_list,omitempty"`
}

type Params struct {
TotalStake string // total stake of current active validator ids (by last block)
TotalStake string // total stake of current active validator ids (by last block)
ActiveValidatorsIDs []uint64
IsDelegatorsRequired bool
}
Expand All @@ -31,11 +31,11 @@ func (r Resource) Transform(model resource.ItemInterface, values ...resource.Par
part, validatorStake := r.getValidatorPartAndStake(validator, params.TotalStake, params.ActiveValidatorsIDs)

result := Resource{
PublicKey: validator.GetPublicKey(),
Status: validator.Status,
Stake: validatorStake,
Part: part,
Meta: new(meta.Resource).Transform(validator),
PublicKey: validator.GetPublicKey(),
Status: validator.Status,
Stake: validatorStake,
Part: part,
Meta: new(meta.Resource).Transform(validator),
}

if params.IsDelegatorsRequired {
Expand Down

0 comments on commit fa35704

Please sign in to comment.