Skip to content

Commit

Permalink
Add bank module tests (#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
dadamu authored Apr 25, 2022
1 parent a413d6d commit cb7fd10
Show file tree
Hide file tree
Showing 14 changed files with 220 additions and 39 deletions.
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

0 comments on commit cb7fd10

Please sign in to comment.