Skip to content

Commit

Permalink
Validators uptime
Browse files Browse the repository at this point in the history
Implemented the storing of the validators uptime data over time (part of #3)
  • Loading branch information
RiccardoM committed Jun 12, 2020
1 parent 51a2b17 commit 62ceffe
Show file tree
Hide file tree
Showing 12 changed files with 240 additions and 123 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ To install the binary simply run `make install`.
Before running the parser, you need to:

1. Create a [PostgreSQL](https://www.postgresql.org/) database.
2. Run the SQL queries you find inside the [`schemes.sql` file](schema/schemes.sql) inside such database to create all the necessary tables.
2. Run the SQL queries you find inside the [`cosmos.sql` file](schema/cosmos.sql) inside such database to create all the necessary tables.

## Running the parser
To parse the chain state, you need to use the following command:
Expand Down
32 changes: 32 additions & 0 deletions database/cosmos_extensions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package database

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
)

// SaveValidators allows the bulk saving of a list of validators
func (db BigDipperDb) SaveValidators(validators []staking.Validator) error {
var insertParams []interface{}

queryInsert := "INSERT INTO validator (consensus_address, consensus_pubkey) VALUES "
for i, result := range validators {
p1 := i * 2 // starting position for insert params

queryInsert += fmt.Sprintf("($%d,$%d),", p1+1, p1+2)

key, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, result.ConsPubKey)
if err != nil {
return err
}

insertParams = append(insertParams, result.ConsAddress().String(), key)
}

queryInsert = queryInsert[:len(queryInsert)-1] // remove trailing ","
queryInsert += " ON CONFLICT DO NOTHING"
_, err := db.Sql.Exec(queryInsert, insertParams...)
return err
}
25 changes: 22 additions & 3 deletions database/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,36 @@ package database
import (
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/rs/zerolog/log"
)

type ValidatorUptime struct {
Height int64 `db:"height"`
ValidatorAddress sdk.ConsAddress `db:"validator_address"`
SignedBlocksWindow int64 `db:"signed_blocks_window"`
MissedBlocksCounter int64 `db:"missed_blocks_counter"`
}

// SaveStakingPool allows to save for the given height the given staking pool
func (db BigDipperDb) SaveStakingPool(height int64, pool staking.Pool) error {
log.Debug().Int64("height", height).Msg("updating staking pool")

statement := `INSERT INTO staking_pool (timestamp, height, bonded_tokens, not_bonded_tokens)
VALUES ($1, $2, $3, $4)`
_, err := db.Sql.Exec(statement,
time.Now().UTC(), height, pool.BondedTokens.Int64(), pool.NotBondedTokens.Int64())
return err
}

// SaveValidatorUptime stores into the database the given validator uptime information
func (db BigDipperDb) SaveValidatorUptime(uptime ValidatorUptime) error {
if found, _ := db.HasValidator(uptime.ValidatorAddress.String()); !found {
// Validator does not exist, return simply
return nil
}

statement := `INSERT INTO validator_uptime (height, validator_address, signed_blocks_window, missed_blocks_counter)
VALUES ($1, $2, $3, $4)`
_, err := db.Sql.Exec(statement,
uptime.Height, uptime.ValidatorAddress.String(), uptime.SignedBlocksWindow, uptime.MissedBlocksCounter)
return err
}
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ go 1.14

require (
github.com/cosmos/cosmos-sdk v0.38.4
github.com/desmos-labs/juno v0.0.0-20200612073324-1997d72bb88f
github.com/desmos-labs/juno v0.0.0-20200612123728-010ffd0b270b
github.com/go-co-op/gocron v0.2.0
github.com/jmoiron/sqlx v1.2.0
github.com/jmoiron/sqlx v1.2.1-0.20200324155115-ee514944af4b
github.com/rs/zerolog v1.18.0
github.com/stretchr/testify v1.5.1
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/desmos-labs/juno v0.0.0-20200612073324-1997d72bb88f h1:WmS1djDv9F2YhQQbVx5aw7QI1YvV4v5Esl4t+9zLXuk=
github.com/desmos-labs/juno v0.0.0-20200612073324-1997d72bb88f/go.mod h1:vO/rzafpCjazuhsTl/HN9z08pHdY8E/YxQnyizXbAr8=
github.com/desmos-labs/juno v0.0.0-20200612123728-010ffd0b270b h1:jjOlm+9MPVNwpKYiHWGUrQaQSUKOU1ANsLtx5geeHuQ=
github.com/desmos-labs/juno v0.0.0-20200612123728-010ffd0b270b/go.mod h1:vO/rzafpCjazuhsTl/HN9z08pHdY8E/YxQnyizXbAr8=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
Expand Down Expand Up @@ -248,8 +248,8 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jmoiron/sqlx v1.2.1-0.20200324155115-ee514944af4b h1:VPXoGvR9KOTliKv0uimGqr4kMGpIYaOlGNZ5L4W4S5Y=
github.com/jmoiron/sqlx v1.2.1-0.20200324155115-ee514944af4b/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
Expand Down
41 changes: 41 additions & 0 deletions schema/cosmos.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
CREATE TABLE validator
(
id SERIAL PRIMARY KEY,
consensus_address CHARACTER VARYING(52) NOT NULL UNIQUE, /* Validator consensus address */
consensus_pubkey CHARACTER VARYING(83) NOT NULL UNIQUE
);

CREATE TABLE pre_commit
(
id SERIAL PRIMARY KEY,
validator_address CHARACTER VARYING(52) NOT NULL REFERENCES validator (consensus_address),
timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL,
voting_power INTEGER NOT NULL,
proposer_priority INTEGER NOT NULL
);

CREATE TABLE block
(
id SERIAL PRIMARY KEY,
height INTEGER NOT NULL UNIQUE,
hash CHARACTER VARYING(64) NOT NULL UNIQUE,
num_txs INTEGER DEFAULT 0,
total_gas INTEGER DEFAULT 0,
proposer_address CHARACTER VARYING(52) NOT NULL REFERENCES validator (consensus_address),
pre_commits INTEGER NOT NULL,
timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL
);

CREATE TABLE transaction
(
id SERIAL PRIMARY KEY,
timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL,
gas_wanted INTEGER DEFAULT 0,
gas_used INTEGER DEFAULT 0,
height INTEGER NOT NULL REFERENCES block (height),
txhash CHARACTER VARYING(64) NOT NULL UNIQUE,
messages JSONB NOT NULL DEFAULT '[]'::JSONB,
fee JSONB NOT NULL DEFAULT '{}'::JSONB,
signatures JSONB NOT NULL DEFAULT '[]'::JSONB,
memo CHARACTER VARYING(256)
);
108 changes: 0 additions & 108 deletions schema/schemes.sql

This file was deleted.

22 changes: 22 additions & 0 deletions schema/staking.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
CREATE TABLE staking_pool
(
height BIGINT NOT NULL,
timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL,
bonded_tokens BIGINT NOT NULL,
not_bonded_tokens BIGINT NOT NULL
);

CREATE TABLE validator_uptime
(
height BIGINT NOT NULL,
validator_address CHARACTER VARYING(52) NOT NULL REFERENCES validator (consensus_address),
signed_blocks_window BIGINT NOT NULL,
missed_blocks_counter BIGINT NOT NULL
);

CREATE TABLE validator_info
(
consensus_address CHARACTER VARYING(52) NOT NULL references validator (consensus_address),
operator_address TEXT NOT NULL
);

32 changes: 32 additions & 0 deletions x/staking/address_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package staking

import (
"fmt"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
)

func TestAddress(t *testing.T) {
prefix := "desmos"

cfg := sdk.GetConfig()
cfg.SetBech32PrefixForAccount(
prefix,
prefix+sdk.PrefixPublic,
)
cfg.SetBech32PrefixForValidator(
prefix+sdk.PrefixValidator+sdk.PrefixOperator,
prefix+sdk.PrefixValidator+sdk.PrefixOperator+sdk.PrefixPublic,
)
cfg.SetBech32PrefixForConsensusNode(
prefix+sdk.PrefixValidator+sdk.PrefixConsensus,
prefix+sdk.PrefixValidator+sdk.PrefixConsensus+sdk.PrefixPublic,
)

consAddr, err := sdk.ConsAddressFromHex("0549E17DCCE2AA4BAB0640C70A692389FE081351")
require.NoError(t, err)

fmt.Printf(consAddr.String())
}
10 changes: 8 additions & 2 deletions x/staking/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,14 @@ func periodicStakingOperations(scheduler *gocron.Scheduler) parse.AdditionalOper
}

// Setup a cron job to run every 15 seconds
if _, err := scheduler.Every(15).Second().Do(func() {
go updateStakingPool(cp, bdDatabase)
if _, err := scheduler.Every(10).Second().Do(func() {
//go updateStakingPool(cp, bdDatabase)
go func() {
err := updateValidatorsUptime(cp, bdDatabase)
if err != nil {
log.Error().Err(err).Send()
}
}()
}); err != nil {
return err
}
Expand Down
8 changes: 5 additions & 3 deletions x/staking/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ import (
"github.com/rs/zerolog/log"
)

// updateStakingPool reads from the LCD the current staking pool and stores its value inside the database
// updateValidatorsUptime reads from the LCD the current staking pool and stores its value inside the database
func updateStakingPool(cp client.ClientProxy, db database.BigDipperDb) {
log.Debug().Msg("updating staking pool")

var pool staking.Pool
height, err := cp.QueryLCDWithHeight("/staking/pool", &pool)
if err != nil {
log.Error().Err(err)
log.Error().Err(err).Send()
}

if err := db.SaveStakingPool(height, pool); err != nil {
log.Error().Err(err)
log.Error().Err(err).Send()
}
}
Loading

0 comments on commit 62ceffe

Please sign in to comment.