From b34988332f9692ff337b84d0ba43c8d92f81b897 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 14 Oct 2014 01:18:06 -0700 Subject: [PATCH] test bondTx. State.accountDetails unexported. --- state/state.go | 20 +++---- state/state_test.go | 131 +++++++++++++++++++++++++++++++++----------- 2 files changed, 108 insertions(+), 43 deletions(-) diff --git a/state/state.go b/state/state.go index 94aa4c641..0d5d8ebfe 100644 --- a/state/state.go +++ b/state/state.go @@ -46,7 +46,7 @@ type State struct { Height uint32 // Last known block height BlockHash []byte // Last known block hash CommitTime time.Time - AccountDetails merkle.Tree + accountDetails merkle.Tree // Shouldn't be accessed directly. BondedValidators *ValidatorSet UnbondingValidators *ValidatorSet } @@ -78,7 +78,7 @@ func GenesisState(db DB, genesisTime time.Time, accDets []*AccountDetail) *State Height: 0, BlockHash: nil, CommitTime: genesisTime, - AccountDetails: accountDetails, + accountDetails: accountDetails, BondedValidators: NewValidatorSet(validators), UnbondingValidators: NewValidatorSet(nil), } @@ -97,8 +97,8 @@ func LoadState(db DB) *State { s.CommitTime = ReadTime(reader, &n, &err) s.BlockHash = ReadByteSlice(reader, &n, &err) accountDetailsHash := ReadByteSlice(reader, &n, &err) - s.AccountDetails = merkle.NewIAVLTree(BasicCodec, AccountDetailCodec, defaultAccountDetailsCacheCapacity, db) - s.AccountDetails.Load(accountDetailsHash) + s.accountDetails = merkle.NewIAVLTree(BasicCodec, AccountDetailCodec, defaultAccountDetailsCacheCapacity, db) + s.accountDetails.Load(accountDetailsHash) s.BondedValidators = ReadValidatorSet(reader, &n, &err) s.UnbondingValidators = ReadValidatorSet(reader, &n, &err) if err != nil { @@ -114,14 +114,14 @@ func LoadState(db DB) *State { // is saved here. func (s *State) Save(commitTime time.Time) { s.CommitTime = commitTime - s.AccountDetails.Save() + s.accountDetails.Save() var buf bytes.Buffer var n int64 var err error WriteUInt32(&buf, s.Height, &n, &err) WriteTime(&buf, commitTime, &n, &err) WriteByteSlice(&buf, s.BlockHash, &n, &err) - WriteByteSlice(&buf, s.AccountDetails.Hash(), &n, &err) + WriteByteSlice(&buf, s.accountDetails.Hash(), &n, &err) WriteBinary(&buf, s.BondedValidators, &n, &err) WriteBinary(&buf, s.UnbondingValidators, &n, &err) if err != nil { @@ -136,7 +136,7 @@ func (s *State) Copy() *State { Height: s.Height, CommitTime: s.CommitTime, BlockHash: s.BlockHash, - AccountDetails: s.AccountDetails.Copy(), + accountDetails: s.accountDetails.Copy(), BondedValidators: s.BondedValidators.Copy(), UnbondingValidators: s.UnbondingValidators.Copy(), } @@ -403,7 +403,7 @@ func (s *State) AppendBlock(b *Block, checkStateHash bool) error { // The returned AccountDetail is a copy, so mutating it // has no side effects. func (s *State) GetAccountDetail(accountId uint64) *AccountDetail { - _, accDet := s.AccountDetails.Get(accountId) + _, accDet := s.accountDetails.Get(accountId) if accDet == nil { return nil } @@ -414,14 +414,14 @@ func (s *State) GetAccountDetail(accountId uint64) *AccountDetail { // The accDet is copied before setting, so mutating it // afterwards has no side effects. func (s *State) SetAccountDetail(accDet *AccountDetail) (updated bool) { - return s.AccountDetails.Set(accDet.Id, accDet.Copy()) + return s.accountDetails.Set(accDet.Id, accDet.Copy()) } // Returns a hash that represents the state data, // excluding Height, BlockHash, and CommitTime. func (s *State) Hash() []byte { hashables := []merkle.Hashable{ - s.AccountDetails, + s.accountDetails, s.BondedValidators, s.UnbondingValidators, } diff --git a/state/state_test.go b/state/state_test.go index ee7c0654f..71ac217cb 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -56,17 +56,23 @@ func TestCopyState(t *testing.T) { t.Error("Expected state copy hash to be the same") } - // Mutate the original. - _, accDet_ := s0.AccountDetails.GetByIndex(0) - accDet := accDet_.(*AccountDetail) - if accDet == nil { - t.Error("Expected state to have an account") - } + // Mutate the original; hash should change. + accDet := s0.GetAccountDetail(0) accDet.Balance += 1 - s0.AccountDetails.Set(accDet.Id, accDet) + // The account balance shouldn't have changed yet. + if s0.GetAccountDetail(0).Balance == accDet.Balance { + t.Error("Account balance changed unexpectedly") + } + // Setting, however, should change the balance. + s0.SetAccountDetail(accDet) + if s0.GetAccountDetail(0).Balance != accDet.Balance { + t.Error("Account balance wasn't set") + } + // How that the state changed, the hash should change too. if bytes.Equal(s0Hash, s0.Hash()) { t.Error("Expected state hash to have changed") } + // The s0Copy shouldn't have changed though. if !bytes.Equal(s0Hash, s0Copy.Hash()) { t.Error("Expected state copy hash to have not changed") } @@ -152,7 +158,7 @@ func TestGenesisSaveLoad(t *testing.T) { if !bytes.Equal(s0.UnbondingValidators.Hash(), s1.UnbondingValidators.Hash()) { t.Error("UnbondingValidators hash mismatch") } - if !bytes.Equal(s0.AccountDetails.Hash(), s1.AccountDetails.Hash()) { + if !bytes.Equal(s0.accountDetails.Hash(), s1.accountDetails.Hash()) { t.Error("AccountDetail mismatch") } } @@ -207,38 +213,97 @@ func TestTxs(t *testing.T) { state, privAccounts := randGenesisState(3, 1) acc0 := state.GetAccountDetail(0) // Validator - //_, acc0Val := state.BondedValidators.GetById(0) - if acc0.Status != AccountStatusBonded { - t.Fatal("Expected acc0 to be bonded validator") - } acc1 := state.GetAccountDetail(1) // Non-validator acc2 := state.GetAccountDetail(2) // Non-validator // SendTx. - stx := &SendTx{ - BaseTx: BaseTx{ - Sequence: acc1.Sequence + 1, - Fee: 0}, - To: 2, - Amount: 1, - } - privAccounts[1].Sign(stx) - err := state.ExecTx(stx) - if err != nil { - t.Errorf("Got error in executing send transaction, %v", err) - } - newAcc1 := state.GetAccountDetail(1) - if acc1.Balance-1 != newAcc1.Balance { - t.Errorf("Unexpected newAcc1 balance. Expected %v, got %v", - acc1.Balance-1, newAcc1.Balance) + { + state := state.Copy() + stx := &SendTx{ + BaseTx: BaseTx{ + Sequence: acc1.Sequence + 1, + Fee: 0}, + To: 2, + Amount: 1, + } + privAccounts[1].Sign(stx) + err := state.ExecTx(stx) + if err != nil { + t.Errorf("Got error in executing send transaction, %v", err) + } + newAcc1 := state.GetAccountDetail(1) + if acc1.Balance-1 != newAcc1.Balance { + t.Errorf("Unexpected newAcc1 balance. Expected %v, got %v", + acc1.Balance-1, newAcc1.Balance) + } + newAcc2 := state.GetAccountDetail(2) + if acc2.Balance+1 != newAcc2.Balance { + t.Errorf("Unexpected newAcc2 balance. Expected %v, got %v", + acc2.Balance+1, newAcc2.Balance) + } } - newAcc2 := state.GetAccountDetail(2) - if acc2.Balance+1 != newAcc2.Balance { - t.Errorf("Unexpected newAcc2 balance. Expected %v, got %v", - acc2.Balance+1, newAcc2.Balance) + + // TODO: test overflows. + + // SendTx should fail for bonded validators. + { + state := state.Copy() + stx := &SendTx{ + BaseTx: BaseTx{ + Sequence: acc0.Sequence + 1, + Fee: 0}, + To: 2, + Amount: 1, + } + privAccounts[0].Sign(stx) + err := state.ExecTx(stx) + if err == nil { + t.Errorf("Expected error, SendTx should fail for bonded validators") + } } + // TODO: test for unbonding validators. + // BondTx. - // XXX more tests for other transactions. + { + state := state.Copy() + btx := &BondTx{ + BaseTx: BaseTx{ + Sequence: acc1.Sequence + 1, + Fee: 0}, + } + privAccounts[1].Sign(btx) + err := state.ExecTx(btx) + if err != nil { + t.Errorf("Got error in executing bond transaction, %v", err) + } + newAcc1 := state.GetAccountDetail(1) + if acc1.Balance != newAcc1.Balance { + t.Errorf("Unexpected newAcc1 balance. Expected %v, got %v", + acc1.Balance, newAcc1.Balance) + } + if newAcc1.Status != AccountStatusBonded { + t.Errorf("Unexpected newAcc1 status.") + } + _, acc1Val := state.BondedValidators.GetById(acc1.Id) + if acc1Val == nil { + t.Errorf("acc1Val not present") + } + if acc1Val.BondHeight != state.Height { + t.Errorf("Unexpected bond height. Expected %v, got %v", + state.Height, acc1Val.BondHeight) + } + if acc1Val.VotingPower != acc1.Balance { + t.Errorf("Unexpected voting power. Expected %v, got %v", + acc1Val.VotingPower, acc1.Balance) + } + if acc1Val.Accum != 0 { + t.Errorf("Unexpected accum. Expected 0, got %v", + acc1Val.Accum) + } + } + + // TODO UnbondTx. + // TODO NameTx. }