diff --git a/modules/stake/commen_test.go b/modules/stake/commen_test.go new file mode 100644 index 00000000..96f233b9 --- /dev/null +++ b/modules/stake/commen_test.go @@ -0,0 +1,83 @@ +package stake_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/forbole/soljuno/db" + dbtypes "github.com/forbole/soljuno/db/types" + "github.com/forbole/soljuno/modules/stake" + clienttypes "github.com/forbole/soljuno/solana/client/types" +) + +var _ db.StakeDb = &MockDb{} + +type MockDb struct { + isLatest bool +} + +func NewDefaultMockDb() *MockDb { + return &MockDb{isLatest: true} +} + +func (db *MockDb) SaveStakeAccount(account dbtypes.StakeAccountRow) error { return nil } +func (db *MockDb) DeleteStakeAccount(address string) error { return nil } +func (db *MockDb) SaveStakeDelegation(delegation dbtypes.StakeDelegationRow) error { return nil } +func (db *MockDb) SaveStakeLockup(lockup dbtypes.StakeLockupRow) error { return nil } +func (db *MockDb) DeleteStakeDelegation(address string) error { return nil } + +func (db *MockDb) CheckStakeAccountLatest(address string, currentSlot uint64) bool { + return db.isLatest +} + +func (m MockDb) GetCached() MockDb { + return m +} + +func (m *MockDb) WithLatest(isLatest bool) { + m.isLatest = isLatest +} + +// ---------------------------------------------------------------- + +var _ stake.ClientProxy = &MockClient{} + +type MockClient struct { + account clienttypes.AccountInfo +} + +func NewDefaultMockClient() *MockClient { + return &MockClient{} +} + +func (m MockClient) GetCached() MockClient { + return m +} + +func (m *MockClient) WithAccount(account clienttypes.AccountInfo) { + m.account = account +} + +func (m *MockClient) GetAccountInfo(address string) (clienttypes.AccountInfo, error) { + return m.account, nil +} + +// ---------------------------------------------------------------- + +type ModuleTestSuite struct { + suite.Suite + module *stake.Module + db *MockDb + client *MockClient +} + +func TestModuleTestSuite(t *testing.T) { + suite.Run(t, new(ModuleTestSuite)) +} + +func (suite *ModuleTestSuite) SetupTest() { + suite.module = stake.NewModule(NewDefaultMockDb(), NewDefaultMockClient()) + suite.db = NewDefaultMockDb() + suite.client = NewDefaultMockClient() +} diff --git a/modules/stake/handle_instruction.go b/modules/stake/handle_instruction.go index fda79eeb..758b7483 100644 --- a/modules/stake/handle_instruction.go +++ b/modules/stake/handle_instruction.go @@ -5,46 +5,45 @@ import ( "github.com/forbole/soljuno/db" dbtypes "github.com/forbole/soljuno/db/types" - "github.com/forbole/soljuno/solana/client" "github.com/forbole/soljuno/solana/program/stake" "github.com/forbole/soljuno/types" ) // HandleInstruction allows to handle different instructions types for the stake module -func HandleInstruction(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func HandleInstruction(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { switch instruction.Parsed.Type { case "initialize": - return handleInitialize(instruction, tx, db) + return handleInitialize(instruction, db) case "authorize": - return handleAuthorize(instruction, tx, db, client) + return handleAuthorize(instruction, db, client) case "delegate": - return handleDelegate(instruction, tx, db, client) + return handleDelegate(instruction, db, client) case "split": - return handleSplit(instruction, tx, db, client) + return handleSplit(instruction, db, client) case "withdraw": - return handleWithdraw(instruction, tx, db, client) + return handleWithdraw(instruction, db, client) case "deactivate": - return handleDeactivate(instruction, tx, db, client) + return handleDeactivate(instruction, db, client) case "setLockup": - return handleSetLockup(instruction, tx, db, client) + return handleSetLockup(instruction, db, client) case "merge": - return handleMerge(instruction, tx, db, client) + return handleMerge(instruction, db, client) case "authorizeWithSeed": - return handleAuthorizeWithSeed(instruction, tx, db, client) + return handleAuthorizeWithSeed(instruction, db, client) case "initializeChecked": - return handleInitializeChecked(instruction, tx, db, client) + return handleInitializeChecked(instruction, db, client) case "authorizeChecked": - return handleAuthorizeChecked(instruction, tx, db, client) + return handleAuthorizeChecked(instruction, db, client) case "authorizeCheckedWithSeed": - return handleAuthorizeCheckedWithSeed(instruction, tx, db, client) + return handleAuthorizeCheckedWithSeed(instruction, db, client) case "setLockupChecked": - return handleSetLockupChecked(instruction, tx, db, client) + return handleSetLockupChecked(instruction, db, client) } return nil } // handleInitialize handles a instruction of Initialize -func handleInitialize(instruction types.Instruction, tx types.Tx, db db.StakeDb) error { +func handleInitialize(instruction types.Instruction, db db.StakeDb) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedInitialize) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "initialize", instruction.Parsed.Type) @@ -52,7 +51,7 @@ func handleInitialize(instruction types.Instruction, tx types.Tx, db db.StakeDb) } err := db.SaveStakeAccount( dbtypes.NewStakeAccountRow( - parsed.StakeAccount, tx.Slot, parsed.Authorized.Staker, parsed.Authorized.Withdrawer, + parsed.StakeAccount, instruction.Slot, parsed.Authorized.Staker, parsed.Authorized.Withdrawer, ), ) if err != nil { @@ -60,135 +59,135 @@ func handleInitialize(instruction types.Instruction, tx types.Tx, db db.StakeDb) } return db.SaveStakeLockup( dbtypes.NewStakeLockupRow( - parsed.StakeAccount, tx.Slot, parsed.Lockup.Custodian, parsed.Lockup.Epoch, parsed.Lockup.UnixTimestamp, + parsed.StakeAccount, instruction.Slot, parsed.Lockup.Custodian, parsed.Lockup.Epoch, parsed.Lockup.UnixTimestamp, ), ) } // handleAuthorize handles a instruction of Authorize -func handleAuthorize(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleAuthorize(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedAuthorize) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "authorize", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } // handleDelegate handles a instruction of Delegate -func handleDelegate(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleDelegate(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedDelegateStake) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "delegate", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } // handleSplit handles a instruction of Split -func handleSplit(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleSplit(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedSplit) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "split", instruction.Parsed.Type) } - err := updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + err := UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) if err != nil { return nil } - return updateStakeAccount(parsed.NewSplitAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.NewSplitAccount, instruction.Slot, db, client) } // handleWithdraw handles a instruction of Withdraw -func handleWithdraw(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleWithdraw(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedWithdraw) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "withdraw", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } // handleDeactivate handles a instruction of Deactivate -func handleDeactivate(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleDeactivate(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedDeactivate) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "deactivate", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } // handleSetLockup handles a instruction of SetLockup -func handleSetLockup(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleSetLockup(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedSetLockup) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "setLockup", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } // handleMerge handles a instruction of Merge -func handleMerge(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleMerge(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedMerge) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "merge", instruction.Parsed.Type) } - err := updateStakeAccount(parsed.Source, tx.Slot, db, client) + err := UpdateStakeAccount(parsed.Source, instruction.Slot, db, client) if err != nil { return err } - return updateStakeAccount(parsed.Destination, tx.Slot, db, client) + return UpdateStakeAccount(parsed.Destination, instruction.Slot, db, client) } // handleAuthorizeWithSeed handles a instruction of AuthorizeWithSeed -func handleAuthorizeWithSeed(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleAuthorizeWithSeed(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedAuthorizeWithSeed) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "authorizeWithSeed", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } // handleInitializeChecked handles a instruction of InitializeChecked -func handleInitializeChecked(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleInitializeChecked(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedInitializeChecked) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "initializeChecked", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } // handleAuthorizeChecked handles a instruction of AuthorizeChecked -func handleAuthorizeChecked(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleAuthorizeChecked(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedAuthorizeChecked) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "authorizeChecked", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } // handleAuthorizeCheckedWithSeed handles a instruction of AuthorizeCheckedWithSeed -func handleAuthorizeCheckedWithSeed(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleAuthorizeCheckedWithSeed(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedAuthorizeCheckedWithSeed) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "authorizeCheckedWithSeed", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } // handleSetLockupChecked handles a instruction of SetLockupChecked -func handleSetLockupChecked(instruction types.Instruction, tx types.Tx, db db.StakeDb, client client.ClientProxy) error { +func handleSetLockupChecked(instruction types.Instruction, db db.StakeDb, client ClientProxy) error { parsed, ok := instruction.Parsed.Value.(stake.ParsedSetLockupChecked) if !ok { return fmt.Errorf("instruction does not match %s type: %s", "setLockupChecked", instruction.Parsed.Type) } - return updateStakeAccount(parsed.StakeAccount, tx.Slot, db, client) + return UpdateStakeAccount(parsed.StakeAccount, instruction.Slot, db, client) } diff --git a/modules/stake/handle_instruction_test.go b/modules/stake/handle_instruction_test.go new file mode 100644 index 00000000..50bc7a5b --- /dev/null +++ b/modules/stake/handle_instruction_test.go @@ -0,0 +1,232 @@ +package stake_test + +import ( + "github.com/forbole/soljuno/modules/stake" + stakeProgram "github.com/forbole/soljuno/solana/program/stake" + solanatypes "github.com/forbole/soljuno/solana/types" + "github.com/forbole/soljuno/types" +) + +func (suite *ModuleTestSuite) Test_HandleInstruction() { + testCases := []struct { + name string + data types.Instruction + }{ + { + name: "initialize instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "initialize", + stakeProgram.ParsedInitialize{}, + ), + ), + }, + { + name: "authorize instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "authorize", + stakeProgram.ParsedAuthorize{}, + ), + ), + }, + { + name: "delegate instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "delegate", + stakeProgram.ParsedDelegateStake{}, + ), + ), + }, + { + name: "split instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "split", + stakeProgram.ParsedSplit{}, + ), + ), + }, + { + name: "withdraw instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "withdraw", + stakeProgram.ParsedWithdraw{}, + ), + ), + }, + { + name: "deactivate instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "deactivate", + stakeProgram.ParsedDeactivate{}, + ), + ), + }, + { + name: "setLockup instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "setLockup", + stakeProgram.ParsedSetLockup{}, + ), + ), + }, + { + name: "merge instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "merge", + stakeProgram.ParsedMerge{}, + ), + ), + }, + { + name: "authorizeWithSeed instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "authorizeWithSeed", + stakeProgram.ParsedAuthorizeWithSeed{}, + ), + ), + }, + { + name: "initializeChecked instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "initializeChecked", + stakeProgram.ParsedInitializeChecked{}, + ), + ), + }, + { + name: "authorizeChecked instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "authorizeChecked", + stakeProgram.ParsedAuthorizeChecked{}, + ), + ), + }, + { + name: "authorizeCheckedWithSeed instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "authorizeCheckedWithSeed", + stakeProgram.ParsedAuthorizeCheckedWithSeed{}, + ), + ), + }, + { + name: "setLockupChecked instruction works properly", + data: types.NewInstruction( + "sig", + 1, + 0, + 0, + "stake", + []string{}, + "", + solanatypes.NewParsedInstruction( + "setLockupChecked", + stakeProgram.ParsedSetLockupChecked{}, + ), + ), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + err := stake.HandleInstruction(tc.data, suite.db, suite.client) + suite.Require().NoError(err) + }) + } +} diff --git a/modules/stake/moduel_test.go b/modules/stake/moduel_test.go new file mode 100644 index 00000000..66fc9e4e --- /dev/null +++ b/modules/stake/moduel_test.go @@ -0,0 +1,90 @@ +package stake_test + +import ( + "fmt" + + stakeProgram "github.com/forbole/soljuno/solana/program/stake" + solanatypes "github.com/forbole/soljuno/solana/types" + "github.com/forbole/soljuno/types" +) + +func (suite *ModuleTestSuite) TestModule_Name() { + suite.Require().Equal("stake", suite.module.Name()) +} + +func (suite *ModuleTestSuite) TestModule_HandleInstruction() { + testCases := []struct { + name string + tx types.Tx + instruction types.Instruction + shouldErr bool + }{ + { + name: "failed tx skip properly", + tx: types.NewTx("sig", 0, fmt.Errorf("failed"), 0, nil, nil, nil, nil, nil), + }, + { + name: "non stake instruction skips properly", + instruction: types.NewInstruction( + "sig", + 1, + 0, + 0, + "unknown", + nil, + "", + solanatypes.NewParsedInstruction( + "initialize", + nil, + ), + ), + }, + { + name: "fail to handle instruction return error", + tx: types.NewTx("sig", 0, nil, 0, nil, nil, nil, nil, nil), + instruction: types.NewInstruction( + "sig", + 1, + 0, + 0, + stakeProgram.ProgramID, + []string{}, + "", + solanatypes.NewParsedInstruction( + "initialize", + nil, + ), + ), + shouldErr: true, + }, + { + name: "instruction works properly", + tx: types.NewTx("sig", 0, nil, 0, nil, nil, nil, nil, nil), + instruction: types.NewInstruction( + "sig", + 1, + 0, + 0, + stakeProgram.ProgramID, + []string{}, + "", + solanatypes.NewParsedInstruction( + "initialize", + stakeProgram.ParsedInitialize{}, + ), + ), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + err := suite.module.HandleInstruction(tc.instruction, tc.tx) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + } + }) + } +} diff --git a/modules/stake/module.go b/modules/stake/module.go index 4868b6c1..f805aa92 100644 --- a/modules/stake/module.go +++ b/modules/stake/module.go @@ -3,23 +3,27 @@ package stake import ( "github.com/forbole/soljuno/db" "github.com/forbole/soljuno/modules" - "github.com/forbole/soljuno/solana/client" + clienttypes "github.com/forbole/soljuno/solana/client/types" "github.com/forbole/soljuno/solana/program/stake" "github.com/forbole/soljuno/types" "github.com/rs/zerolog/log" ) +type ClientProxy interface { + GetAccountInfo(string) (clienttypes.AccountInfo, error) +} + var ( _ modules.Module = &Module{} _ modules.InstructionModule = &Module{} ) type Module struct { - db db.Database - client client.ClientProxy + db db.StakeDb + client ClientProxy } -func NewModule(db db.Database, client client.ClientProxy) *Module { +func NewModule(db db.StakeDb, client ClientProxy) *Module { return &Module{ db: db, client: client, @@ -40,11 +44,11 @@ func (m *Module) HandleInstruction(instruction types.Instruction, tx types.Tx) e return nil } - err := HandleInstruction(instruction, tx, m.db, m.client) + err := HandleInstruction(instruction, m.db, m.client) if err != nil { return err } - log.Debug().Str("module", m.Name()).Str("tx", tx.Signature).Uint64("slot", tx.Slot). + log.Debug().Str("module", m.Name()).Str("tx", instruction.TxSignature).Uint64("slot", tx.Slot). Msg("handled instruction") return nil } diff --git a/modules/stake/utils.go b/modules/stake/utils.go index 1f8978d7..3476751d 100644 --- a/modules/stake/utils.go +++ b/modules/stake/utils.go @@ -6,11 +6,10 @@ import ( "github.com/forbole/soljuno/db" dbtypes "github.com/forbole/soljuno/db/types" "github.com/forbole/soljuno/solana/account/parser" - "github.com/forbole/soljuno/solana/client" ) -// updateStakeAccount properly stores the statement of stake account inside the database -func updateStakeAccount(address string, currentSlot uint64, db db.StakeDb, client client.ClientProxy) error { +// UpdateStakeAccount properly stores the statement of stake account inside the database +func UpdateStakeAccount(address string, currentSlot uint64, db db.StakeDb, client ClientProxy) error { if db.CheckStakeAccountLatest(address, currentSlot) { return nil } diff --git a/modules/stake/utils_test.go b/modules/stake/utils_test.go new file mode 100644 index 00000000..723d241b --- /dev/null +++ b/modules/stake/utils_test.go @@ -0,0 +1,73 @@ +package stake_test + +import ( + "github.com/forbole/soljuno/modules/stake" + clienttypes "github.com/forbole/soljuno/solana/client/types" + stakeProgram "github.com/forbole/soljuno/solana/program/stake" +) + +func (suite *ModuleTestSuite) TestUpdateStakeAccount() { + testCases := []struct { + name string + isLatest bool + account clienttypes.AccountInfo + shouldErr bool + }{ + { + name: "skip updating returns no error", + isLatest: true, + }, + { + name: "receive empty account data and delete account properly", + isLatest: false, + }, + { + name: "fail to decode data returns error", + isLatest: false, + account: clienttypes.AccountInfo{ + Value: &clienttypes.AccountValue{ + Data: [2]string{"$invalid", "base64"}, + }, + }, + shouldErr: true, + }, + { + name: "receive non nonce account and delete account properly", + isLatest: false, + account: clienttypes.AccountInfo{ + Value: &clienttypes.AccountValue{ + Data: [2]string{"dW5rbm93bg==", "base64"}, + Owner: "unknown", + }, + }, + }, + { + name: "receive stake account and update account properly", + isLatest: false, + account: clienttypes.AccountInfo{ + Value: &clienttypes.AccountValue{ + Data: [2]string{"AgAAAIDVIgAAAAAAyBJA4ron1nIF2JkcS2ipPJPqFbMjSwcV5MaNxJd+RMPIEkDiuifWcgXYmRxLaKk8k+oVsyNLBxXkxo3El35EwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHzgaQ+C+2FHX+u9FgXvIMNGqRZ3BtgpzkaZQ1xMJ4CugJ4YpAsAAAAtAQAAAAAAAP//////////AAAAAAAA0D+PcUcGAAAAAAAAAAA=", "base64"}, + Owner: stakeProgram.ProgramID, + }, + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + db := suite.db.GetCached() + db.WithLatest(tc.isLatest) + + client := suite.client.GetCached() + client.WithAccount(tc.account) + + err := stake.UpdateStakeAccount("address", 1, &db, &client) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + } + }) + } +} diff --git a/modules/system/commen_test.go b/modules/system/commen_test.go index 9b2935c6..74ed62f9 100644 --- a/modules/system/commen_test.go +++ b/modules/system/commen_test.go @@ -15,7 +15,6 @@ var _ db.SystemDb = &MockDb{} type MockDb struct { isLatest bool - isBroken bool } func NewDefaultMockDb() *MockDb { @@ -36,10 +35,6 @@ func (m *MockDb) WithLatest(isLatest bool) { m.isLatest = isLatest } -func (m *MockDb) WithBroken(isBroken bool) { - m.isBroken = isBroken -} - // ---------------------------------------------------------------- var _ system.ClientProxy = &MockClient{} @@ -56,7 +51,7 @@ func (m MockClient) GetCached() MockClient { return m } -func (m *MockClient) WithNonceAccount(account clienttypes.AccountInfo) { +func (m *MockClient) WithAccount(account clienttypes.AccountInfo) { m.account = account } diff --git a/modules/system/utils_test.go b/modules/system/utils_test.go index 1dc17f3f..1c7e948b 100644 --- a/modules/system/utils_test.go +++ b/modules/system/utils_test.go @@ -3,6 +3,7 @@ package system_test import ( "github.com/forbole/soljuno/modules/system" clienttypes "github.com/forbole/soljuno/solana/client/types" + systemProgram "github.com/forbole/soljuno/solana/program/system" ) func (suite *ModuleTestSuite) TestUpdateNonceAccount() { @@ -46,7 +47,7 @@ func (suite *ModuleTestSuite) TestUpdateNonceAccount() { account: clienttypes.AccountInfo{ Value: &clienttypes.AccountValue{ Data: [2]string{"AAAAAAEAAADKFr/7JZLeKFJKIaGunqjtXggBBBad6ejlmbYPRoSyLJ+X5Y193+WHX7lT5pRYGWf4V70JP+EScclNbE1yU9T7iBMAAAAAAAA=", "base64"}, - Owner: "unknown", + Owner: systemProgram.ProgramID, }, }, }, @@ -59,7 +60,7 @@ func (suite *ModuleTestSuite) TestUpdateNonceAccount() { db.WithLatest(tc.isLatest) client := suite.client.GetCached() - client.WithNonceAccount(tc.account) + client.WithAccount(tc.account) err := system.UpdateNonceAccount("address", 1, &db, &client) if tc.shouldErr {