Skip to content

Commit

Permalink
Merge pull request #738 from oasisprotocol/andrew7234/total-delegators
Browse files Browse the repository at this point in the history
api: add validator agg stats
  • Loading branch information
Andrew7234 authored Aug 27, 2024
2 parents e89e7b3 + 676be05 commit 1112d33
Show file tree
Hide file tree
Showing 10 changed files with 528 additions and 812 deletions.
1 change: 1 addition & 0 deletions .changelog/738.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
api: add total delegators to /validators
45 changes: 36 additions & 9 deletions api/spec/v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,8 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/ValidatorList'
$ref: '#/components/schemas/ValidatorList'

<<: *common_error_responses

/consensus/validators/{address}:
Expand All @@ -517,7 +518,7 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/Validator'
$ref: '#/components/schemas/ValidatorList'
<<: *common_error_responses

/consensus/validators/{address}/history:
Expand Down Expand Up @@ -1843,18 +1844,48 @@ components:
description: |
An entity registered at the consensus layer.
ValidatorsResponse:
type: object
required: [validator_list, stats]
properties:
validator_list:
allOf: [$ref: '#/components/schemas/ValidatorList']
stats:
allOf: [$ref: '#/components/schemas/ValidatorAggStats']
description: Summary statistics across all consensus validators.

ValidatorList:
allOf:
- $ref: '#/components/schemas/List'
- type: object
required: [validators]
required: [validators, stats]
properties:
validators:
type: array
items:
allOf: [$ref: '#/components/schemas/Validator']
stats:
allOf: [$ref: '#/components/schemas/ValidatorAggStats']
description: Summary statistics across all consensus validators.
description: |
A list of validators registered at the consensus layer.
A list of validators registered at the consensus layer, plus summary
statistics across all consensus validators.
ValidatorAggStats:
type: object
required: [total_voting_power, total_delegators, total_staked_balance]
properties:
total_voting_power:
type: integer
format: int64
description: The total voting power across all validators.
total_delegators:
type: integer
format: uint64
description: The total number of delegators in the network.
total_staked_balance:
allOf: [$ref: '#/components/schemas/TextBigInt']
description: The total amount of token staked to validators.

ValidatorCommissionBound:
type: object
Expand Down Expand Up @@ -1899,7 +1930,7 @@ components:

Validator:
type: object
required: [entity_address, entity_id, escrow, voting_power, voting_power_total, active, start_date, rank, in_validator_set, current_rate, current_commission_bound]
required: [entity_address, entity_id, escrow, voting_power, active, start_date, rank, in_validator_set, current_rate, current_commission_bound]
properties:
entity_address:
type: string
Expand All @@ -1922,10 +1953,6 @@ components:
type: integer
format: int64
description: The voting power of this validator.
voting_power_total:
type: integer
format: int64
description: The total voting power across all validators.
active:
type: boolean
description: Whether the entity has a node that is registered for being a validator, node is up to date, and has successfully registered itself. It may or may not be part of validator set.
Expand Down
6 changes: 5 additions & 1 deletion api/v1/strict_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,11 @@ func (srv *StrictServerImpl) GetConsensusValidatorsAddress(ctx context.Context,
if len(validators.Validators) == 0 {
return apiTypes.GetConsensusValidatorsAddress404JSONResponse{}, nil
}
return apiTypes.GetConsensusValidatorsAddress200JSONResponse(validators.Validators[0]), nil
// Truncate ValidatorList to only include the top matching validator.
if len(validators.Validators) > 1 {
validators.Validators = validators.Validators[:1]
}
return apiTypes.GetConsensusValidatorsAddress200JSONResponse(*validators), nil
}

func (srv *StrictServerImpl) GetConsensusValidatorsAddressHistory(ctx context.Context, request apiTypes.GetConsensusValidatorsAddressHistoryRequestObject) (apiTypes.GetConsensusValidatorsAddressHistoryResponseObject, error) {
Expand Down
16 changes: 14 additions & 2 deletions storage/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1230,11 +1230,23 @@ func (c *StorageClient) Validators(ctx context.Context, p apiTypes.GetConsensusV
var epoch Epoch
if err := c.db.QueryRow(
ctx,
queries.Validators,
queries.LatestEpochStart,
).Scan(&epoch.ID, &epoch.StartHeight); err != nil {
return nil, wrapError(err)
}

var stats ValidatorAggStats
if err := c.db.QueryRow(
ctx,
queries.ValidatorsAggStats,
).Scan(
&stats.TotalVotingPower,
&stats.TotalDelegators,
&stats.TotalStakedBalance,
); err != nil {
return nil, wrapError(err)
}

res, err := c.withTotalCount(
ctx,
queries.ValidatorsData,
Expand All @@ -1250,6 +1262,7 @@ func (c *StorageClient) Validators(ctx context.Context, p apiTypes.GetConsensusV

vs := ValidatorList{
Validators: []Validator{},
Stats: stats,
TotalCount: res.totalCount,
IsTotalCountClipped: res.isTotalCountClipped,
}
Expand All @@ -1272,7 +1285,6 @@ func (c *StorageClient) Validators(ctx context.Context, p apiTypes.GetConsensusV
&v.Escrow.ActiveBalance24,
&v.Escrow.NumDelegators,
&v.VotingPower,
&v.VotingPowerTotal,
&schedule,
&v.StartDate,
&v.Rank,
Expand Down
22 changes: 17 additions & 5 deletions storage/client/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,27 @@ const (
LIMIT $2::bigint
OFFSET $3::bigint`

Validators = `
LatestEpochStart = `
SELECT id, start_height
FROM chain.epochs
ORDER BY id DESC`

ValidatorsAggStats = `
SELECT
COALESCE (
(SELECT SUM(voting_power)
FROM chain.nodes)
, 0) AS total_voting_power,
COALESCE (
(SELECT COUNT(*)
FROM (SELECT DISTINCT delegator FROM chain.delegations) AS _)
, 0) AS total_delegators,
COALESCE (
(SELECT SUM(accts.escrow_balance_active)
FROM chain.entities AS entities
JOIN chain.accounts AS accts ON entities.address = accts.address)
, 0) AS total_staked_balance`

ValidatorsData = `
WITH
-- Find all self-delegations for all accounts with active delegations.
Expand Down Expand Up @@ -342,10 +358,6 @@ const (
COALESCE (
validator_nodes.voting_power
, 0) AS voting_power,
COALESCE (
(SELECT SUM(voting_power)
FROM validator_nodes)
, 0) AS total_voting_power,
COALESCE(chain.commissions.schedule, '{}'::JSONB) AS commissions_schedule,
chain.blocks.time AS start_date,
validator_rank.rank AS rank,
Expand Down
5 changes: 4 additions & 1 deletion storage/client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,12 @@ type ProposalVotes = api.ProposalVotes

type ProposalVote = api.ProposalVote

// ValidatorList is the storage response for GetValidators.
// ValidatorList is the list of consensus validators.
type ValidatorList = api.ValidatorList

// ValidatorAggStats holds summary statistics for network validators.
type ValidatorAggStats = api.ValidatorAggStats

// Validator is the storage response for GetValidator.
type Validator = api.Validator

Expand Down
58 changes: 34 additions & 24 deletions tests/e2e_regression/damask/expected/validator.body
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
{
"active": true,
"current_commission_bound": {
"epoch_end": 0,
"epoch_start": 2310,
"lower": 0,
"upper": 25000
"is_total_count_clipped": false,
"stats": {
"total_delegators": 35414,
"total_staked_balance": "5708092468704383083",
"total_voting_power": 307554773957760060
},
"current_rate": 20000,
"entity_address": "oasis1qr3w66akc8ud9a4zsgyjw2muvcfjgfszn5ycgc0a",
"entity_id": "HPeLbzc88IoYEP0TC4nqSxfxdPCPjduLeJqFvmxFye8=",
"escrow": {
"active_balance": "557356819483297",
"active_shares": "506789203787843",
"debonding_balance": "0",
"debonding_shares": "0",
"num_delegators": 13,
"self_delegation_balance": "9263128275881",
"self_delegation_shares": "8422707392134"
},
"in_validator_set": true,
"node_id": "wqd9Yy3n7TWKfYRn2bI9Hd6/623CfC7NCUoRbQ5UkR8=",
"rank": 92,
"start_date": "2022-04-11T09:30:00Z",
"voting_power": 34834350461211,
"voting_power_total": 307554773957760060
"total_count": 1,
"validators": [
{
"active": true,
"current_commission_bound": {
"epoch_end": 0,
"epoch_start": 2310,
"lower": 0,
"upper": 25000
},
"current_rate": 20000,
"entity_address": "oasis1qr3w66akc8ud9a4zsgyjw2muvcfjgfszn5ycgc0a",
"entity_id": "HPeLbzc88IoYEP0TC4nqSxfxdPCPjduLeJqFvmxFye8=",
"escrow": {
"active_balance": "557356819483297",
"active_shares": "506789203787843",
"debonding_balance": "0",
"debonding_shares": "0",
"num_delegators": 13,
"self_delegation_balance": "9263128275881",
"self_delegation_shares": "8422707392134"
},
"in_validator_set": true,
"node_id": "wqd9Yy3n7TWKfYRn2bI9Hd6/623CfC7NCUoRbQ5UkR8=",
"rank": 92,
"start_date": "2022-04-11T09:30:00Z",
"voting_power": 34834350461211
}
]
}
Loading

0 comments on commit 1112d33

Please sign in to comment.