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

Add bank module tests #219

Merged
merged 1 commit into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 41 additions & 0 deletions modules/bank/commen_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package bank_test

import (
"testing"
"time"

"github.com/stretchr/testify/suite"

"github.com/forbole/soljuno/db"
"github.com/forbole/soljuno/modules/bank"
)

type ModuleTestSuite struct {
suite.Suite
module *bank.Module
}

type MockDb struct{}

var _ db.BankDb = &MockDb{}

func (db MockDb) SaveAccountBalances(slot uint64, accounts []string, balances []uint64) error {
return nil
}
func (db MockDb) SaveAccountTokenBalances(slot uint64, accounts []string, balances []uint64) error {
return nil
}
func (db MockDb) SaveAccountHistoryBalances(time time.Time, accounts []string, balances []uint64) error {
return nil
}
func (db MockDb) SaveAccountHistoryTokenBalances(time time.Time, accounts []string, balances []uint64) error {
return nil
}

func TestModuleTestSuitee(t *testing.T) {
suite.Run(t, new(ModuleTestSuite))
}

func (suite *ModuleTestSuite) SetupTest() {
suite.module = bank.NewModule(MockDb{})
}
24 changes: 14 additions & 10 deletions modules/bank/handle_periodic_operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,26 @@ import (
func (m *Module) RegisterPeriodicOperations(scheduler *gocron.Scheduler) error {
log.Debug().Str("module", m.Name()).Msg("setting up periodic tasks")
if _, err := scheduler.Every(10).Second().Do(func() {
m.mtx.Lock()
defer m.mtx.Unlock()
balances := m.balanceEntries
tokenBalances := m.tokenBalanceEntries
m.balanceEntries = nil
m.tokenBalanceEntries = nil
err := m.updateBalances(balances, tokenBalances)
if err != nil {
log.Error().Str("module", m.Name()).Err(err).Send()
}
m.HandlePeriodicOperations()
}); err != nil {
return fmt.Errorf("error while setting up bank periodic operation: %s", err)
}
return nil
}

func (m *Module) HandlePeriodicOperations() {
m.mtx.Lock()
defer m.mtx.Unlock()
balances := m.BalanceEntries
tokenBalances := m.TokenBalanceEntries
m.BalanceEntries = nil
m.TokenBalanceEntries = nil
err := m.updateBalances(balances, tokenBalances)
if err != nil {
log.Error().Str("module", m.Name()).Err(err).Send()
}
}

func (m *Module) updateBalances(balances []AccountBalanceEntry, tokenBalances []TokenAccountBalanceEntry) error {
errChan := make(chan error, 2)
go func() {
Expand Down
16 changes: 16 additions & 0 deletions modules/bank/handle_periodic_operations_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package bank_test

import "github.com/forbole/soljuno/modules/bank"

func (suite *ModuleTestSuite) TestModule_HandlePeriodicOperations() {
suite.module.BalanceEntries = []bank.AccountBalanceEntry{
bank.NewAccountBalanceEntry(0, "address", 10),
}
suite.module.TokenBalanceEntries = []bank.TokenAccountBalanceEntry{
bank.NewTokenAccountBalanceEntry(0, "address", 10),
}

suite.module.HandlePeriodicOperations()
suite.Require().Empty(suite.module.BalanceEntries)
suite.Require().Empty(suite.module.TokenBalanceEntries)
}
18 changes: 11 additions & 7 deletions modules/bank/history_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,7 @@ import (
var _ history.HistroyService = &Module{}

func (m *Module) ExecHistory() error {
m.mtx.Lock()
balanceEntries := m.historyBalancesEntries
tokenBalanceEntries := m.historyTokenBalancesEntries
m.historyBalancesEntries = nil
m.historyTokenBalancesEntries = nil
m.mtx.Unlock()

balanceEntries, tokenBalanceEntries := m.getHistoryEntries()
errChan := make(chan error)
go func() {
timestamp := time.Now()
Expand All @@ -37,5 +31,15 @@ func (m *Module) ExecHistory() error {
return nil
}

func (m *Module) getHistoryEntries() ([]AccountBalanceEntry, []TokenAccountBalanceEntry) {
m.mtx.Lock()
defer m.mtx.Unlock()
balanceEntries := m.HistoryBalanceEntries
tokenBalanceEntries := m.HistoryTokenBalanceEntries
m.HistoryBalanceEntries = nil
m.HistoryTokenBalanceEntries = nil
return balanceEntries, tokenBalanceEntries
}

// update very 30 minutes
func (m *Module) Cron() string { return "*/30 * * * *" }
18 changes: 18 additions & 0 deletions modules/bank/history_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package bank_test

import "github.com/forbole/soljuno/modules/bank"

func (suite *ModuleTestSuite) TestModule_ExecHistory() {
suite.module.HistoryBalanceEntries = []bank.AccountBalanceEntry{
bank.NewAccountBalanceEntry(0, "address", 10),
}
suite.module.HistoryTokenBalanceEntries = []bank.TokenAccountBalanceEntry{
bank.NewTokenAccountBalanceEntry(0, "address", 10),
}

err := suite.module.ExecHistory()
suite.Require().NoError(err)
suite.Require().Empty(suite.module.HistoryBalanceEntries)
suite.Require().Empty(suite.module.HistoryTokenBalanceEntries)

}
24 changes: 12 additions & 12 deletions modules/bank/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ var (
)

type Module struct {
db db.Database
db db.BankDb
tasks chan func()
balanceEntries []AccountBalanceEntry
tokenBalanceEntries []TokenAccountBalanceEntry
BalanceEntries []AccountBalanceEntry
TokenBalanceEntries []TokenAccountBalanceEntry

historyBalancesEntries []AccountBalanceEntry
historyTokenBalancesEntries []TokenAccountBalanceEntry
HistoryBalanceEntries []AccountBalanceEntry
HistoryTokenBalanceEntries []TokenAccountBalanceEntry

mtx sync.Mutex
}

func NewModule(db db.Database) *Module {
func NewModule(db db.BankDb) *Module {
return &Module{
db: db,
tasks: make(chan func()),
Expand All @@ -43,13 +43,13 @@ func (m *Module) HandleBlock(block types.Block) error {
m.mtx.Lock()
defer m.mtx.Unlock()

balanceEntries := GetAccountBalaceEntries(block)
m.balanceEntries = MergeAccountBalanceEntries(m.balanceEntries, GetAccountBalaceEntries(block))
m.historyBalancesEntries = MergeAccountBalanceEntries(m.historyBalancesEntries, balanceEntries)
balanceEntries := getAccountBalaceEntries(block)
m.BalanceEntries = MergeAccountBalanceEntries(m.BalanceEntries, getAccountBalaceEntries(block))
m.HistoryBalanceEntries = MergeAccountBalanceEntries(m.HistoryBalanceEntries, balanceEntries)

tokenBalanceEntries := GetTokenAccountBalaceEntries(block)
m.tokenBalanceEntries = MergeTokenAccountBalanceEntries(m.tokenBalanceEntries, tokenBalanceEntries)
m.historyTokenBalancesEntries = MergeTokenAccountBalanceEntries(m.historyTokenBalancesEntries, tokenBalanceEntries)
tokenBalanceEntries := getTokenAccountBalaceEntries(block)
m.TokenBalanceEntries = MergeTokenAccountBalanceEntries(m.TokenBalanceEntries, tokenBalanceEntries)
m.HistoryTokenBalanceEntries = MergeTokenAccountBalanceEntries(m.HistoryTokenBalanceEntries, tokenBalanceEntries)
log.Debug().Str("module", m.Name()).Uint64("slot", block.Slot).Msg("handled block")
return nil
}
87 changes: 87 additions & 0 deletions modules/bank/module_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package bank_test

import (
"time"

"github.com/forbole/soljuno/modules/bank"
clienttypes "github.com/forbole/soljuno/solana/client/types"
"github.com/forbole/soljuno/types"
)

func (suite *ModuleTestSuite) TestModule_Name() {
suite.Require().Equal("bank", suite.module.Name())
}

func (suite *ModuleTestSuite) TestModule_HandleBlock() {
block := types.NewBlock(
0,
0,
"hash",
"leader",
[]clienttypes.Reward{clienttypes.NewReward("address", 1, 1, clienttypes.RewardStaking, 0)},
time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC),
[]types.Tx{
types.NewTx(
"sig",
0,
nil,
0,
nil,
nil,
[]string{"address"},
[]uint64{2},
[]clienttypes.TransactionTokenBalance{
{
AccountIndex: 0,
Mint: "mint",
UiTokenAmount: clienttypes.UiTokenAmount{Amount: "1"},
}},
),
types.NewTx(
"sig",
0,
nil,
0,
nil,
nil,
[]string{"address"},
[]uint64{3},
[]clienttypes.TransactionTokenBalance{
{
AccountIndex: 0,
Mint: "mint",
UiTokenAmount: clienttypes.UiTokenAmount{Amount: "2"},
}},
),
},
)
err := suite.module.HandleBlock(block)
suite.Require().NoError(err)
suite.Require().Equal(bank.NewAccountBalanceEntries(0, []string{"address"}, []uint64{3}), suite.module.BalanceEntries)
suite.Require().Equal(bank.NewAccountBalanceEntries(0, []string{"address"}, []uint64{3}), suite.module.HistoryBalanceEntries)

suite.Require().Equal(
bank.NewTokenAccountBalanceEntries(
0,
[]string{"address"},
[]clienttypes.TransactionTokenBalance{
{
AccountIndex: 0,
Mint: "mint",
UiTokenAmount: clienttypes.UiTokenAmount{Amount: "2"},
},
},
), suite.module.TokenBalanceEntries)
suite.Require().Equal(
bank.NewTokenAccountBalanceEntries(
0,
[]string{"address"},
[]clienttypes.TransactionTokenBalance{
{
AccountIndex: 0,
Mint: "mint",
UiTokenAmount: clienttypes.UiTokenAmount{Amount: "2"},
},
},
), suite.module.HistoryTokenBalanceEntries)
}
4 changes: 2 additions & 2 deletions modules/bank/handle_bank.go → modules/bank/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"github.com/forbole/soljuno/types"
)

func GetAccountBalaceEntries(block types.Block) []AccountBalanceEntry {
func getAccountBalaceEntries(block types.Block) []AccountBalanceEntry {
var accounts []string
var balances []uint64
accountMap := make(map[string]int)
Expand Down Expand Up @@ -38,7 +38,7 @@ func GetAccountBalaceEntries(block types.Block) []AccountBalanceEntry {
return NewAccountBalanceEntries(block.Slot, accounts, balances)
}

func GetTokenAccountBalaceEntries(block types.Block) []TokenAccountBalanceEntry {
func getTokenAccountBalaceEntries(block types.Block) []TokenAccountBalanceEntry {
var tokenAccounts []string
var tokenBalances []clienttypes.TransactionTokenBalance
tokenAccountMap := make(map[string]int)
Expand Down
2 changes: 1 addition & 1 deletion modules/blocks/modeul_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ func (suite *ModuleTestSuite) TestName() {
}

func (suite *ModuleTestSuite) HandleBlock() {
err := suite.module.HandleBlock(types.NewBlock(0, 0, "hash", "leader", time.Now(), []types.Tx{}))
err := suite.module.HandleBlock(types.NewBlock(0, 0, "hash", "leader", nil, time.Now(), []types.Tx{}))
suite.Require().NoError(err)
}
2 changes: 1 addition & 1 deletion modules/instructions/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func (suite *ModuleTestSuite) TestName() {
}

func (suite *ModuleTestSuite) TestHandleBlock() {
err := suite.module.HandleBlock(types.NewBlock(0, 0, "hash", "leader", time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}))
err := suite.module.HandleBlock(types.NewBlock(0, 0, "hash", "leader", nil, time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}))
suite.Require().NoError(err)
}

Expand Down
6 changes: 3 additions & 3 deletions modules/txs/handle_async_operations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
func (suite *ModuleTestSuite) TestHandleBuffer() {
buffer := make(chan types.Block, 1)
suite.module.WithBuffer(buffer)
buffer <- types.NewBlock(0, 0, "hash", "leader", time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{})
buffer <- types.NewBlock(0, 0, "hash", "leader", nil, time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{})
suite.Require().Len(buffer, 1)
suite.module.HandleBuffer()
suite.Require().Len(buffer, 0)
Expand All @@ -21,8 +21,8 @@ func (suite *ModuleTestSuite) TestHandleAsyncError() {
suite.module.WithBuffer(buffer)
suite.module.HandleAsyncError(
fmt.Errorf("error"),
types.NewBlock(0, 0, "hash", "leader", time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}),
types.NewBlock(0, 0, "hash", "leader", nil, time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}),
)
suite.Require().Len(buffer, 1)
suite.Require().Equal(types.NewBlock(0, 0, "hash", "leader", time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}), <-buffer)
suite.Require().Equal(types.NewBlock(0, 0, "hash", "leader", nil, time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}), <-buffer)
}
4 changes: 2 additions & 2 deletions modules/txs/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ func (suite *ModuleTestSuite) TestName() {
func (suite *ModuleTestSuite) TestHandleBlock() {
buffer := make(chan types.Block, 1)
suite.module.WithBuffer(buffer)
err := suite.module.HandleBlock(types.NewBlock(0, 0, "hash", "leader", time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}))
err := suite.module.HandleBlock(types.NewBlock(0, 0, "hash", "leader", nil, time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}))
suite.Require().Len(buffer, 1)
suite.Require().Equal(types.NewBlock(0, 0, "hash", "leader", time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}), <-buffer)
suite.Require().Equal(types.NewBlock(0, 0, "hash", "leader", nil, time.Date(2022, 04, 14, 0, 0, 0, 0, time.UTC), []types.Tx{}), <-buffer)
suite.Require().NoError(err)
}

Expand Down
10 changes: 10 additions & 0 deletions solana/client/types/reward.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,13 @@ const (
RewardStaking RewardType = "Staking"
RewardVoting RewardType = "Voting"
)

func NewReward(pubkey string, lamports int64, postBalance uint64, rewardType RewardType, commission uint8) Reward {
return Reward{
Pubkey: pubkey,
Lamports: lamports,
PostBalance: postBalance,
RewardType: rewardType,
Commission: commission,
}
}
3 changes: 2 additions & 1 deletion types/solana.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ type Block struct {
}

// NewBlock allows to build a new Block instance
func NewBlock(slot, height uint64, hash, leader string, timestamp time.Time, txs []Tx) Block {
func NewBlock(slot, height uint64, hash, leader string, rewards []clienttypes.Reward, timestamp time.Time, txs []Tx) Block {
return Block{
Slot: slot,
Height: height,
Hash: hash,
Leader: leader,
Rewards: rewards,
Timestamp: timestamp,
Txs: txs,
}
Expand Down