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

feat: add vesting account handling #232

Merged
merged 41 commits into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
97698d5
x/ditr handleMsg add go routines for refreching rewards and commision
huichiaotsou Oct 7, 2021
9a5283e
Merge branch 'v2/cosmos/stargate' into v2/aaron/update_rewards_commis…
huichiaotsou Oct 7, 2021
8e43f3f
merge
huichiaotsou Oct 8, 2021
91176e8
Merge branch 'v2/aaron/update_rewards_commission' of https://github.c…
huichiaotsou Oct 8, 2021
cece5af
move interval check to handle_block
huichiaotsou Oct 9, 2021
371b1a9
update comment
huichiaotsou Oct 9, 2021
4e6ff33
make shouldUpdateDelegatorRewardsAmounts a function
huichiaotsou Oct 12, 2021
ba35512
remove uneccessary update/refresh in handle msg
huichiaotsou Oct 12, 2021
8758b7f
fix no return value for shouldUpdateDelegatorRewardsAmounts
huichiaotsou Oct 12, 2021
30f23c5
add schema vesting_account
huichiaotsou Oct 13, 2021
c1a3588
schema
huichiaotsou Oct 15, 2021
6354fab
Merge branch 'v2/cosmos/stargate' into v2/aaron/vesting_account
huichiaotsou Oct 15, 2021
d600690
add structure in auth/handle_genesis.go
huichiaotsou Oct 15, 2021
e85ecf0
add types for JSON handling and for auth types/auth
huichiaotsou Oct 15, 2021
73719ad
add get genesis vesting accounts method in auth_accounts.go
huichiaotsou Oct 15, 2021
0616f38
add db.SaveVestingAccounts
huichiaotsou Oct 15, 2021
1f9f209
fix schema
huichiaotsou Oct 15, 2021
cc055ba
add schema(move create type COIN to auth.sql)
huichiaotsou Oct 19, 2021
e0e4f64
implement GetGenesisVestingAccounts and use in HandleGenesis
huichiaotsou Oct 19, 2021
6a53241
implement SaveVestingAccounts and the storing of 3 diff. vesting acco…
huichiaotsou Oct 19, 2021
91bdf17
add structs in types/auth.go: ContinuousVestingAccount/ DelayedVestin…
huichiaotsou Oct 19, 2021
563f8ea
modify sql comments
huichiaotsou Oct 19, 2021
7a5d81a
Merge remote-tracking branch 'remotes/origin/v2/aaron/vesting_account…
huichiaotsou Oct 19, 2021
31efda6
delete GetGenesisVestingAccounts from auth_accounts.go
huichiaotsou Oct 19, 2021
918ba27
modif comments GetGenesisVestingAccounts
huichiaotsou Oct 19, 2021
6fcac22
comment modif: Build vestingAccounts Array
huichiaotsou Oct 19, 2021
1b31894
linter issue: vestingAccountId -> vestingAccountID
huichiaotsou Oct 19, 2021
c006195
add unit test
huichiaotsou Oct 19, 2021
d655091
linter: Id -> ID
huichiaotsou Oct 19, 2021
71eb9f2
lint
MonikaCat Oct 19, 2021
600230c
remove fmt.Println
huichiaotsou Oct 20, 2021
39fc74d
fix comments, remove redundant store-to-db methods
huichiaotsou Oct 20, 2021
9be3448
rm unit test for save vesting account ftm
huichiaotsou Oct 20, 2021
234f23b
schema: length TEXT -> BIGINT
huichiaotsou Oct 20, 2021
4df7892
fix go.mod
huichiaotsou Oct 20, 2021
ace57db
rm custom row types from database/types/auth.go
huichiaotsou Oct 20, 2021
2dcdeaf
merge 2 cases(continuous and deleyed vesting account; move storeVesti…
huichiaotsou Oct 20, 2021
decd364
correctly merge 2 cases
huichiaotsou Oct 20, 2021
4d7e1ec
revert DBG to prev. version
huichiaotsou Oct 20, 2021
83c661a
Updated SaveVestingAccounts
MonikaCat Oct 20, 2021
2d39fd4
Merge branch 'v2/cosmos/stargate' into v2/aaron/vesting_account
mergify[bot] Oct 20, 2021
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
147 changes: 146 additions & 1 deletion database/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ package database

import (
"fmt"
"time"

"github.com/cosmos/cosmos-sdk/x/auth/vesting/exported"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
dbtypes "github.com/forbole/bdjuno/v2/database/types"
dbutils "github.com/forbole/bdjuno/v2/database/utils"
"github.com/lib/pq"

"github.com/forbole/bdjuno/v2/types"
)

// SaveAccounts saves the given accounts inside the database
// SaveAccounts saves the given account addresses inside the database
RiccardoM marked this conversation as resolved.
Show resolved Hide resolved
func (db *Db) SaveAccounts(accounts []types.Account) error {
paramsNumber := 1
slices := dbutils.SplitAccounts(accounts, paramsNumber)
Expand Down Expand Up @@ -52,6 +57,146 @@ func (db *Db) saveAccounts(paramsNumber int, accounts []types.Account) error {
return nil
}

// SaveVestingAccounts saves the given vesting account details inside the database, including:
// type, address, original vesting, endTime, startTime, and vesting periods
RiccardoM marked this conversation as resolved.
Show resolved Hide resolved
func (db *Db) SaveVestingAccounts(vestingAccounts []exported.VestingAccount) error {
if len(vestingAccounts) == 0 {
return nil
}

for _, account := range vestingAccounts {
switch vestingAccount := account.(type) {
case *vestingtypes.ContinuousVestingAccount:
ContinuousVestingAccount := types.NewContinuousVestingAccount(*vestingAccount)
err := db.storeContinuousVestingAccount(ContinuousVestingAccount)
if err != nil {
return fmt.Errorf("error while storing Continuous Vesting Account: %s", err)
}
RiccardoM marked this conversation as resolved.
Show resolved Hide resolved

case *vestingtypes.DelayedVestingAccount:
DelayedVestingAccount := types.NewDelayedVestingAccount(*vestingAccount)
err := db.storeDelayedVestingAccount(DelayedVestingAccount)
if err != nil {
return fmt.Errorf("error while storing Delayed Vesting Account: %s", err)
}

case *vestingtypes.PeriodicVestingAccount:
PeriodicVestingAccount := types.NewPeriodicVestingAccount(*vestingAccount)
err := db.storePeriodicVestingAccount(PeriodicVestingAccount)
if err != nil {
return fmt.Errorf("error while storing Periodic Vesting Account: %s", err)
}
}
}

return nil
}

//storeContinuousVestingAccount stores the vesting account details of type ContinuousVestingAccount into the database
func (db *Db) storeContinuousVestingAccount(account types.ContinuousVestingAccount) error {
stmt := `
INSERT INTO vesting_account (type, address, original_vesting, end_time, start_time)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (address) DO UPDATE
SET original_vesting = excluded.original_vesting,
end_time = excluded.end_time,
start_time = excluded.start_time`

_, err := db.Sql.Exec(stmt,
account.Type,
account.Address,
pq.Array(dbtypes.NewDbCoins(account.OriginalVesting)),
time.Unix(account.EndTime, 0).Format(time.RFC3339),
time.Unix(account.StartTime, 0).Format(time.RFC3339),
)
if err != nil {
return err
}
return nil
}

//storeDelayedVestingAccount stores the vesting account details of type DelayedVestingAccount into the database
func (db *Db) storeDelayedVestingAccount(account types.DelayedVestingAccount) error {
stmt := `
INSERT INTO vesting_account (type, address, original_vesting, end_time)
VALUES ($1, $2, $3, $4)
ON CONFLICT (address) DO UPDATE
SET original_vesting = excluded.original_vesting,
end_time = excluded.end_time`

_, err := db.Sql.Exec(
stmt,
account.Type,
account.Address,
pq.Array(dbtypes.NewDbCoins(account.OriginalVesting)),
time.Unix(account.EndTime, 0).Format(time.RFC3339),
)
if err != nil {
return err
}

return nil
}

//storePeriodicVestingAccount stores the vesting account details of type PeriodicVestingAccount into the database
func (db *Db) storePeriodicVestingAccount(account types.PeriodicVestingAccount) error {
stmt := `
INSERT INTO vesting_account (type, address, original_vesting, end_time, start_time)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (address) DO UPDATE
SET type = excluded.type,
original_vesting = excluded.original_vesting,
end_time = excluded.end_time,
start_time = excluded.start_time
RETURNING id `

var vestingAccountID int
err := db.Sql.QueryRow(
stmt,
account.Type,
account.Address,
pq.Array(dbtypes.NewDbCoins(account.OriginalVesting)),
time.Unix(account.EndTime, 0).Format(time.RFC3339),
time.Unix(account.StartTime, 0).Format(time.RFC3339),
).Scan(&vestingAccountID)

if err != nil {
return fmt.Errorf("error while saving Periodic Vesting Account: %s", err)
}

err = db.storeVestingPeriods(vestingAccountID, account.VestingPeriods)
if err != nil {
return fmt.Errorf("error while storing vesting periods: %s", err)
}

return nil
}

//storePeriodicVestingAccount stores the vesting periods of type PeriodicVestingAccount into the database
func (db *Db) storeVestingPeriods(vestingAccountID int, vestingPeriods []vestingtypes.Period) error {
stmt := `
INSERT INTO vesting_period (vesting_account_id, period_order, length, amount)
VALUES `

var params []interface{}
for i, period := range vestingPeriods {
ai := i * 4
stmt += fmt.Sprintf("($%d,$%d,$%d,$%d),", ai+1, ai+2, ai+3, ai+4)

order := i
amount := pq.Array(dbtypes.NewDbCoins(period.Amount))
params = append(params, vestingAccountID, order, period.Length, amount)
}
stmt = stmt[:len(stmt)-1]

_, err := db.Sql.Exec(stmt, params...)
huichiaotsou marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}

return nil
}

// GetAccounts returns all the accounts that are currently stored inside the database.
func (db *Db) GetAccounts() ([]string, error) {
var rows []string
Expand Down
131 changes: 131 additions & 0 deletions database/auth_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package database_test

import (
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
authttypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/vesting/exported"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"

"github.com/forbole/bdjuno/v2/types"

Expand Down Expand Up @@ -71,3 +75,130 @@ func (suite *DbTestSuite) TestBigDipperDb_GetAccounts() {
suite.Require().Equal(acc, accounts[index])
}
}

func (suite *DbTestSuite) Test_SaveVestingAccounts() {
// --- Save account addresses for foreign key contraint ---
queries := []string{
`INSERT INTO account (address) VALUES ('cosmos1ltzt0z992ke6qgmtjxtygwzn36km4cy6cqdknt')`,
`INSERT INTO account (address) VALUES ('cosmos1re6zjpyczs0w7flrl6uacl0r4teqtyg62crjsn')`,
`INSERT INTO account (address) VALUES ('cosmos1eg47ue0l85lzkfgc4leske6hcah8cz3qajpjy2')`,
}
for _, query := range queries {
_, err := suite.database.Sql.Exec(query)
suite.Require().NoError(err)
}
var accountRows []dbtypes.AccountRow
suite.database.Sqlx.Select(&accountRows, `SELECT * FROM account`)

// --- Prepare VestingAccounts for saving into DB ---
sdkCoins := sdk.NewCoins(sdk.NewCoin("desmos", sdk.NewInt(10)))
// ContinuousVestingAccount
address1, err := sdk.AccAddressFromBech32("cosmos1ltzt0z992ke6qgmtjxtygwzn36km4cy6cqdknt")
suite.Require().NoError(err)
ContinuousVestingAccount := vestingtypes.NewContinuousVestingAccount(
authttypes.NewBaseAccountWithAddress(address1),
sdkCoins,
time.Date(1990, 9, 9, 00, 00, 00, 000, time.UTC).Unix(), // Start Time
time.Date(2020, 9, 9, 00, 00, 00, 000, time.UTC).Unix(), // End Time
)

// DelayedVestingAccount
address2, _ := sdk.AccAddressFromBech32("cosmos1re6zjpyczs0w7flrl6uacl0r4teqtyg62crjsn")
DelayedVestingAccount := vestingtypes.NewDelayedVestingAccount(
authttypes.NewBaseAccountWithAddress(address2),
sdkCoins,
time.Date(2020, 9, 9, 00, 00, 00, 000, time.UTC).Unix(), // End Time
)

// PeriodicVestingAccount
address3, _ := sdk.AccAddressFromBech32("cosmos1eg47ue0l85lzkfgc4leske6hcah8cz3qajpjy2")
periods := []vestingtypes.Period{
{
Length: 2629743,
Amount: sdkCoins,
},
{
Length: 7889229,
Amount: sdkCoins,
},
}
PeriodicVestingAccount := vestingtypes.NewPeriodicVestingAccount(
authttypes.NewBaseAccountWithAddress(address3),
sdkCoins,
time.Date(1990, 9, 9, 00, 00, 00, 000, time.UTC).Unix(), // Start Time
periods,
)

// VestingAccounts
vestingAccounts := []exported.VestingAccount{
ContinuousVestingAccount,
DelayedVestingAccount,
PeriodicVestingAccount,
}

// --- Save the data into DB ---
err = suite.database.SaveVestingAccounts(vestingAccounts)
suite.Require().NoError(err)

// --- Verify Continuous Vesting Account ---
var continuousVestingAccountRow []dbtypes.ContinuousVestingAccountRow
err = suite.database.Sqlx.Select(&continuousVestingAccountRow, `SELECT * FROM vesting_account WHERE type = 'ContinuousVestingAccount'`)
suite.Require().NoError(err)
suite.Require().Len(continuousVestingAccountRow, 1, "ContinuousVestingAccount type should contain only one row")

expectedContinuousVestingAccountRow := dbtypes.NewContinuousVestingAccountRow(
1,
"ContinuousVestingAccount",
"cosmos1ltzt0z992ke6qgmtjxtygwzn36km4cy6cqdknt",
dbtypes.NewDbCoins(sdkCoins),
time.Date(2020, 9, 9, 00, 00, 00, 000, time.UTC), // EndTime
time.Date(1990, 9, 9, 00, 00, 00, 000, time.UTC), // StartTime
)
suite.Require().True(expectedContinuousVestingAccountRow.Equal(continuousVestingAccountRow[0]))

// --- Verify Delayed Vesting Account ---
var delayedVestingAccountRow []dbtypes.DelayedVestingAccountRow
err = suite.database.Sqlx.Select(&delayedVestingAccountRow, `SELECT id, type, address, original_vesting, end_time FROM vesting_account WHERE type = 'DelayedVestingAccount'`)
suite.Require().NoError(err)
suite.Require().Len(delayedVestingAccountRow, 1, "DelayedVestingAccountRow type should contain only one row")

expectedDelayedVestingAccountRow := dbtypes.NewDelayedVestingAccountRow(
2,
"DelayedVestingAccount",
"cosmos1re6zjpyczs0w7flrl6uacl0r4teqtyg62crjsn",
dbtypes.NewDbCoins(sdkCoins),
time.Date(2020, 9, 9, 00, 00, 00, 000, time.UTC), // EndTime
)
suite.Require().True(expectedDelayedVestingAccountRow.Equal(delayedVestingAccountRow[0]))

// --- Verify Periodic Vesting Account ---
var periodicVestingAccountRow []dbtypes.PeriodicVestingAccountRow
err = suite.database.Sqlx.Select(&periodicVestingAccountRow, `SELECT * FROM vesting_account WHERE type = 'PeriodicVestingAccount'`)
suite.Require().NoError(err)
suite.Require().Len(delayedVestingAccountRow, 1, "DelayedVestingAccountRow type should contain only one row")

expectedPeriodicVestingAccountRow := dbtypes.NewPeriodicVestingAccountRow(
3,
"PeriodicVestingAccount",
"cosmos1eg47ue0l85lzkfgc4leske6hcah8cz3qajpjy2",
dbtypes.NewDbCoins(sdkCoins),
time.Date(2020, 9, 9, 00, 00, 00, 000, time.UTC), // EndTime
time.Date(1990, 9, 9, 00, 00, 00, 000, time.UTC), // StartTime
)
suite.Require().True(expectedPeriodicVestingAccountRow.Equal(periodicVestingAccountRow[0]))

// --- Verify vesting periods ---
var vestingPeriodRows []dbtypes.VestingPeriodRow
err = suite.database.Sqlx.Select(&vestingPeriodRows, `SELECT * FROM vesting_period`)
suite.Require().NoError(err)
suite.Require().Len(vestingPeriodRows, 2, "vestingPeriodRows should contain only 2 rows")

expectedVestingPeriods := []dbtypes.VestingPeriodRow{
dbtypes.NewVestingPeriodRow(3, 0, "2629743", dbtypes.NewDbCoins(sdkCoins)),
dbtypes.NewVestingPeriodRow(3, 1, "7889229", dbtypes.NewDbCoins(sdkCoins)),
}
for index, vestingPeriod := range expectedVestingPeriods {
suite.Require().True(vestingPeriod.Equal(vestingPeriodRows[index]))
}

}
30 changes: 30 additions & 0 deletions database/schema/01-auth.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,34 @@
CREATE TABLE account
(
address TEXT NOT NULL PRIMARY KEY
);

/* ---- Moved from bank.sql for vesting account usage ---- */
CREATE TYPE COIN AS
(
denom TEXT,
amount TEXT
);

/* ---- AUTH/ VESTING ACCOUNT ---- */
CREATE TABLE vesting_account
(
id SERIAL PRIMARY KEY NOT NULL,
type TEXT NOT NULL,
address TEXT NOT NULL REFERENCES account (address),
original_vesting COIN[] NOT NULL DEFAULT '{}',
end_time TIMESTAMP WITHOUT TIME ZONE NOT NULL,
start_time TIMESTAMP WITHOUT TIME ZONE
);
/* ---- start_time can be empty on DelayedVestingAccount ---- */

CREATE UNIQUE INDEX vesting_account_address_idx ON vesting_account (address);


CREATE TABLE vesting_period
(
vesting_account_id INT NOT NULL REFERENCES vesting_account (id),
period_order INT NOT NULL,
length TEXT NOT NULL,
RiccardoM marked this conversation as resolved.
Show resolved Hide resolved
amount COIN[] NOT NULL DEFAULT '{}'
);
6 changes: 0 additions & 6 deletions database/schema/02-bank.sql
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
CREATE TYPE COIN AS
(
denom TEXT,
amount TEXT
);

/* ---- SUPPLY ---- */

CREATE TABLE supply
Expand Down
Loading