Skip to content

Commit

Permalink
General improvements
Browse files Browse the repository at this point in the history
See PR forbole#67
  • Loading branch information
RiccardoM authored Jan 4, 2021
1 parent 7f03e4b commit f4b1e0b
Show file tree
Hide file tree
Showing 76 changed files with 877 additions and 1,524 deletions.
10 changes: 0 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,6 @@ jobs:
- uses: actions/checkout@v2
- name: Test & Coverage report creation
run: make install test-unit stop-docker-test
- name: Filter out DONTCOVER
run: |
excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')"
excludelist+=" $(find ./ -type f -name '*.pb.go')"
excludelist+=" $(find ./ -type f -path './tests/mocks/*.go')"
for filename in ${excludelist}; do
filename=$(echo $filename | sed 's/^./github.com\/forbole\/bdjuno/g')
echo "Excluding ${filename} from coverage report..."
sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt
done
- uses: codecov/[email protected]
with:
file: ./coverage.txt
98 changes: 4 additions & 94 deletions database/auth.go
Original file line number Diff line number Diff line change
@@ -1,105 +1,20 @@
package database

import (
"fmt"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/lib/pq"

dbtypes "github.com/forbole/bdjuno/database/types"
)

// SaveAccount saves the given account information for the given block height and timestamp
func (db *BigDipperDb) SaveAccount(account exported.Account, height int64, timestamp time.Time) error {
func (db *BigDipperDb) SaveAccount(account exported.Account) error {
stmt := `INSERT INTO account (address) VALUES ($1) ON CONFLICT DO NOTHING`
_, err := db.Sql.Exec(stmt, account.GetAddress().String())
if err != nil {
return err
}

coins := pq.Array(dbtypes.NewDbCoins(account.GetCoins()))

stmt = `
INSERT INTO account_balance (address, coins)
VALUES ($1, $2)
ON CONFLICT (address) DO UPDATE SET coins = excluded.coins`
_, err = db.Sql.Exec(stmt, account.GetAddress().String(), coins)
if err != nil {
return err
}

stmt = `
INSERT INTO account_balance_history (address, coins, height, timestamp)
VALUES ($1, $2::coin[], $3, $4) ON CONFLICT DO NOTHING`
_, err = db.Sql.Exec(stmt, account.GetAddress().String(), coins, height, timestamp)
return err
}

// SaveAccount saves the given accounts information for the given block height and timestamp
func (db *BigDipperDb) SaveAccounts(accounts []exported.Account, height int64, timestamp time.Time) error {
// Do nothing with empty accounts
if len(accounts) == 0 {
return nil
}

accQry := `INSERT INTO account (address) VALUES `
var accParams []interface{}

balQry := `INSERT INTO account_balance (address, coins) VALUES `
var balParams []interface{}

balHisQry := `INSERT INTO account_balance_history (address, coins, height, timestamp) VALUES `
var bHisParams []interface{}

for i, account := range accounts {
ai := i * 1
accQry += fmt.Sprintf("($%d),", ai+1)
accParams = append(accParams, account.GetAddress().String())

coins := pq.Array(dbtypes.NewDbCoins(account.GetCoins()))

bi := i * 2
balQry += fmt.Sprintf("($%d, $%d),", bi+1, bi+2)
balParams = append(balParams, account.GetAddress().String(), coins)

bHi := i * 4
balHisQry += fmt.Sprintf("($%d,$%d,$%d,$%d),", bHi+1, bHi+2, bHi+3, bHi+4)
bHisParams = append(bHisParams, account.GetAddress().String(), coins, height, timestamp)
}

// Store the accounts
accQry = accQry[:len(accQry)-1] // Remove trailing ","
accQry += " ON CONFLICT (address) DO NOTHING"
_, err := db.Sql.Exec(accQry, accParams...)
if err != nil {
return err
}

// Remove all the existing balances
_, err = db.Sql.Exec(`DELETE FROM account_balance WHERE TRUE`)
if err != nil {
return err
}

// Insert the current balances
balQry = balQry[:len(balQry)-1] // Remove trailing ","
balQry += " ON CONFLICT (address) DO NOTHING"
_, err = db.Sql.Exec(balQry, balParams...)
if err != nil {
return err
}

// Store the balances histories
balHisQry = balHisQry[:len(balHisQry)-1] // Remove trailing ","
balHisQry += " ON CONFLICT (address, height) DO NOTHING"
_, err = db.Sql.Exec(balHisQry, bHisParams...)
return err
}

// GetAccounts returns all the accounts that are currently stored inside the database.
func (db *BigDipperDb) GetAccounts() ([]sdk.AccAddress, error) {
func (db *BigDipperDb) GetAccounts() ([]string, error) {
sqlStmt := `SELECT * FROM account`

var rows []dbtypes.AccountRow
Expand All @@ -108,14 +23,9 @@ func (db *BigDipperDb) GetAccounts() ([]sdk.AccAddress, error) {
return nil, err
}

addresses := make([]sdk.AccAddress, len(rows))
addresses := make([]string, len(rows))
for index, row := range rows {
address, err := sdk.AccAddressFromBech32(row.Address)
if err != nil {
return nil, err
}

addresses[index] = address
addresses[index] = row.Address
}

return addresses, nil
Expand Down
144 changes: 3 additions & 141 deletions database/auth_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package database_test

import (
"time"

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

dbtypes "github.com/forbole/bdjuno/database/types"
)
Expand All @@ -14,27 +11,16 @@ func (suite *DbTestSuite) TestSaveAccount() {
address, err := sdk.AccAddressFromBech32("cosmos140xsjjg6pwkjp0xjz8zru7ytha60l5aee9nlf7")
suite.Require().NoError(err)

height := int64(100)

timestamp, err := time.Parse(time.RFC3339, "2020-02-02T15:00:00Z")
suite.Require().NoError(err)

coins := sdk.NewCoins(
sdk.NewCoin("desmos", sdk.NewInt(10000)),
sdk.NewCoin("uatom", sdk.NewInt(15)),
)

account := auth.NewBaseAccountWithAddress(address)
suite.Require().NoError(account.SetCoins(coins))

// ------------------------------
// --- Save the data
// ------------------------------

err = suite.database.SaveAccount(&account, height, timestamp)
err = suite.database.SaveAccount(&account)
suite.Require().NoError(err)

err = suite.database.SaveAccount(&account, height, timestamp)
err = suite.database.SaveAccount(&account)
suite.Require().NoError(err, "double account insertion should not insert and returns no error")

// ------------------------------
Expand All @@ -49,130 +35,6 @@ func (suite *DbTestSuite) TestSaveAccount() {

expectedAccountRow := dbtypes.NewAccountRow("cosmos140xsjjg6pwkjp0xjz8zru7ytha60l5aee9nlf7")
suite.Require().True(expectedAccountRow.Equal(accountRows[0]))

// Current balances
var balRows []dbtypes.AccountBalanceRow
err = suite.database.Sqlx.Select(&balRows, `SELECT * FROM account_balance ORDER BY address`)
suite.Require().NoError(err)

expectedBalRows := []dbtypes.AccountBalanceRow{
dbtypes.NewAccountBalanceRow(
"cosmos140xsjjg6pwkjp0xjz8zru7ytha60l5aee9nlf7",
dbtypes.NewDbCoins(coins),
),
}
suite.Require().Len(balRows, len(expectedBalRows))
for index, expected := range expectedBalRows {
suite.Require().True(expected.Equal(balRows[index]))
}

// Balance histories
var balHisRows []dbtypes.AccountBalanceHistoryRow
err = suite.database.Sqlx.Select(&balHisRows, `SELECT * FROM account_balance_history ORDER BY address`)
suite.Require().NoError(err)

expectedBalHisRows := []dbtypes.AccountBalanceHistoryRow{
dbtypes.NewAccountBalanceHistoryRow(
"cosmos140xsjjg6pwkjp0xjz8zru7ytha60l5aee9nlf7",
dbtypes.NewDbCoins(coins),
height,
timestamp,
),
}
suite.Require().Len(balHisRows, len(expectedBalHisRows))
for index, expected := range expectedBalHisRows {
suite.Require().True(expected.Equal(balHisRows[index]))
}
}

func (suite *DbTestSuite) TestSaveAccounts() {
firstAddr, err := sdk.AccAddressFromBech32("cosmos150zkt7g7kf3ymnzl28dksqvhjuxs9newc9uaq4")
suite.Require().NoError(err)

secondAddr, err := sdk.AccAddressFromBech32("cosmos1ngpsastyerhhpj72lvy38kn56cmuspfdwu7lg2")
suite.Require().NoError(err)

firstAcc := auth.NewBaseAccountWithAddress(firstAddr)
suite.Require().NoError(firstAcc.SetCoins(sdk.NewCoins(sdk.NewCoin("desmos", sdk.NewInt(10000)))))

secondAcc := auth.NewBaseAccountWithAddress(secondAddr)
suite.Require().NoError(secondAcc.SetCoins(sdk.NewCoins(sdk.NewCoin("uatom", sdk.NewInt(50000)))))

accounts := []exported.Account{&firstAcc, &secondAcc}

height := int64(100)

timestamp, err := time.Parse(time.RFC3339, "2020-02-02T15:00:00Z")
suite.Require().NoError(err)

// ------------------------------
// --- Save the data
// ------------------------------

err = suite.database.SaveAccounts(accounts, height, timestamp)
suite.Require().NoError(err, "storing accounts should return no error")

// ------------------------------
// --- Verify the data
// ------------------------------

// Accounts data
var accountsRows []dbtypes.AccountRow
err = suite.database.Sqlx.Select(&accountsRows, `SELECT * FROM account ORDER BY address`)
suite.Require().NoError(err)

expAccRows := []dbtypes.AccountRow{
dbtypes.NewAccountRow("cosmos150zkt7g7kf3ymnzl28dksqvhjuxs9newc9uaq4"),
dbtypes.NewAccountRow("cosmos1ngpsastyerhhpj72lvy38kn56cmuspfdwu7lg2"),
}
suite.Require().Len(accountsRows, len(expAccRows))
for index, expected := range expAccRows {
suite.Require().True(expected.Equal(accountsRows[index]))
}

// Current balances
var balRows []dbtypes.AccountBalanceRow
err = suite.database.Sqlx.Select(&balRows, `SELECT * FROM account_balance ORDER BY address`)
suite.Require().NoError(err)

expectedBalRows := []dbtypes.AccountBalanceRow{
dbtypes.NewAccountBalanceRow(
"cosmos150zkt7g7kf3ymnzl28dksqvhjuxs9newc9uaq4",
dbtypes.NewDbCoins(sdk.NewCoins(sdk.NewCoin("desmos", sdk.NewInt(10000)))),
),
dbtypes.NewAccountBalanceRow(
"cosmos1ngpsastyerhhpj72lvy38kn56cmuspfdwu7lg2",
dbtypes.NewDbCoins(sdk.NewCoins(sdk.NewCoin("uatom", sdk.NewInt(50000)))),
),
}
suite.Require().Len(balRows, len(expectedBalRows))
for index, expected := range expectedBalRows {
suite.Require().True(expected.Equal(balRows[index]))
}

// Balance histories
var balHisRows []dbtypes.AccountBalanceHistoryRow
err = suite.database.Sqlx.Select(&balHisRows, `SELECT * FROM account_balance_history ORDER BY address`)
suite.Require().NoError(err)

expectedBalHisRows := []dbtypes.AccountBalanceHistoryRow{
dbtypes.NewAccountBalanceHistoryRow(
"cosmos150zkt7g7kf3ymnzl28dksqvhjuxs9newc9uaq4",
dbtypes.NewDbCoins(sdk.NewCoins(sdk.NewCoin("desmos", sdk.NewInt(10000)))),
height,
timestamp,
),
dbtypes.NewAccountBalanceHistoryRow(
"cosmos1ngpsastyerhhpj72lvy38kn56cmuspfdwu7lg2",
dbtypes.NewDbCoins(sdk.NewCoins(sdk.NewCoin("uatom", sdk.NewInt(50000)))),
height,
timestamp,
),
}
suite.Require().Len(balHisRows, len(expectedBalHisRows))
for index, expected := range expectedBalHisRows {
suite.Require().True(expected.Equal(balHisRows[index]))
}
}

func (suite *DbTestSuite) TestBigDipperDb_GetAccounts() {
Expand Down Expand Up @@ -204,6 +66,6 @@ func (suite *DbTestSuite) TestBigDipperDb_GetAccounts() {
}

for index, acc := range expectedAccs {
suite.Require().Equal(acc, accounts[index].String())
suite.Require().Equal(acc, accounts[index])
}
}
26 changes: 26 additions & 0 deletions database/bank.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package database

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/lib/pq"

dbtypes "github.com/forbole/bdjuno/database/types"
)

// SaveAccountBalance allows to store the balance for the given account associating it to the given height
func (db *BigDipperDb) SaveAccountBalance(address string, balance sdk.Coins, height int64) error {
coins := pq.Array(dbtypes.NewDbCoins(balance))

stmt := `
INSERT INTO account_balance (address, coins)
VALUES ($1, $2) ON CONFLICT (address) DO UPDATE
SET coins = excluded.coins`
_, err := db.Sql.Exec(stmt, address, coins)
if err != nil {
return err
}

stmt = `INSERT INTO account_balance_history (address, coins, height) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING`
_, err = db.Sql.Exec(stmt, address, coins, height)
return err
}
41 changes: 41 additions & 0 deletions database/bank_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package database_test

import (
sdk "github.com/cosmos/cosmos-sdk/types"

dbtypes "github.com/forbole/bdjuno/database/types"
)

func (suite *DbTestSuite) TestSaveAccountBalance() {
address := suite.getAccount("cosmos140xsjjg6pwkjp0xjz8zru7ytha60l5aee9nlf7")
height := int64(100)
coins := sdk.NewCoins(
sdk.NewCoin("desmos", sdk.NewInt(10000)),
sdk.NewCoin("uatom", sdk.NewInt(15)),
)

// Save the balance
err := suite.database.SaveAccountBalance(address.String(), coins, height)
suite.Require().NoError(err)

// Current balances
var balRows []dbtypes.AccountBalanceRow
err = suite.database.Sqlx.Select(&balRows, `SELECT * FROM account_balance ORDER BY address`)
suite.Require().NoError(err)
suite.Require().Len(balRows, 1)
suite.Require().True(balRows[0].Equal(dbtypes.NewAccountBalanceRow(
"cosmos140xsjjg6pwkjp0xjz8zru7ytha60l5aee9nlf7",
dbtypes.NewDbCoins(coins),
)))

// Balance histories
var balHisRows []dbtypes.AccountBalanceHistoryRow
err = suite.database.Sqlx.Select(&balHisRows, `SELECT * FROM account_balance_history ORDER BY address`)
suite.Require().NoError(err)
suite.Require().Len(balHisRows, 1)
suite.Require().True(balHisRows[0].Equal(dbtypes.NewAccountBalanceHistoryRow(
"cosmos140xsjjg6pwkjp0xjz8zru7ytha60l5aee9nlf7",
dbtypes.NewDbCoins(coins),
height,
)))
}
Loading

0 comments on commit f4b1e0b

Please sign in to comment.