You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
6.5 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package state
  2. import (
  3. . "github.com/tendermint/tendermint/blocks"
  4. . "github.com/tendermint/tendermint/common"
  5. . "github.com/tendermint/tendermint/config"
  6. . "github.com/tendermint/tendermint/db"
  7. "bytes"
  8. "testing"
  9. "time"
  10. )
  11. func randAccountDetail(id uint64, status byte) (*AccountDetail, *PrivAccount) {
  12. privAccount := GenPrivAccount()
  13. privAccount.Id = id
  14. account := privAccount.Account
  15. return &AccountDetail{
  16. Account: account,
  17. Sequence: RandUInt(),
  18. Balance: RandUInt64() + 1000, // At least 1000.
  19. Status: status,
  20. }, privAccount
  21. }
  22. // The first numValidators accounts are validators.
  23. func randGenesisState(numAccounts int, numValidators int) (*State, []*PrivAccount) {
  24. db := NewMemDB()
  25. accountDetails := make([]*AccountDetail, numAccounts)
  26. privAccounts := make([]*PrivAccount, numAccounts)
  27. for i := 0; i < numAccounts; i++ {
  28. if i < numValidators {
  29. accountDetails[i], privAccounts[i] =
  30. randAccountDetail(uint64(i), AccountStatusBonded)
  31. } else {
  32. accountDetails[i], privAccounts[i] =
  33. randAccountDetail(uint64(i), AccountStatusNominal)
  34. }
  35. }
  36. s0 := GenesisState(db, time.Now(), accountDetails)
  37. s0.Save(time.Now())
  38. return s0, privAccounts
  39. }
  40. func TestCopyState(t *testing.T) {
  41. // Generate a state
  42. s0, _ := randGenesisState(10, 5)
  43. s0Hash := s0.Hash()
  44. if len(s0Hash) == 0 {
  45. t.Error("Expected state hash")
  46. }
  47. // Check hash of copy
  48. s0Copy := s0.Copy()
  49. if !bytes.Equal(s0Hash, s0Copy.Hash()) {
  50. t.Error("Expected state copy hash to be the same")
  51. }
  52. // Mutate the original.
  53. _, accDet_ := s0.AccountDetails.GetByIndex(0)
  54. accDet := accDet_.(*AccountDetail)
  55. if accDet == nil {
  56. t.Error("Expected state to have an account")
  57. }
  58. accDet.Balance += 1
  59. s0.AccountDetails.Set(accDet.Id, accDet)
  60. if bytes.Equal(s0Hash, s0.Hash()) {
  61. t.Error("Expected state hash to have changed")
  62. }
  63. if !bytes.Equal(s0Hash, s0Copy.Hash()) {
  64. t.Error("Expected state copy hash to have not changed")
  65. }
  66. }
  67. func TestGenesisSaveLoad(t *testing.T) {
  68. // Generate a state, save & load it.
  69. s0, _ := randGenesisState(10, 5)
  70. // Mutate the state to append one empty block.
  71. block := &Block{
  72. Header: Header{
  73. Network: Config.Network,
  74. Height: 1,
  75. StateHash: nil,
  76. },
  77. Data: Data{
  78. Txs: []Tx{},
  79. },
  80. }
  81. // The second argument to AppendBlock() is false,
  82. // which sets Block.Header.StateHash.
  83. err := s0.Copy().AppendBlock(block, false)
  84. if err != nil {
  85. t.Error("Error appending initial block:", err)
  86. }
  87. if len(block.Header.StateHash) == 0 {
  88. t.Error("Expected StateHash but got nothing.")
  89. }
  90. // Now append the block to s0.
  91. // This time we also check the StateHash (as computed above).
  92. err = s0.AppendBlock(block, true)
  93. if err != nil {
  94. t.Error("Error appending initial block:", err)
  95. }
  96. // Save s0
  97. commitTime := time.Now()
  98. s0.Save(commitTime)
  99. // Sanity check s0
  100. //s0.DB.(*MemDB).Print()
  101. if s0.BondedValidators.TotalVotingPower() == 0 {
  102. t.Error("s0 BondedValidators TotalVotingPower should not be 0")
  103. }
  104. if s0.Height != 1 {
  105. t.Error("s0 Height should be 1, got", s0.Height)
  106. }
  107. // Load s1
  108. s1 := LoadState(s0.DB)
  109. // Compare CommitTime
  110. if !s0.CommitTime.Equal(s1.CommitTime) {
  111. t.Error("CommitTime was not the same", s0.CommitTime, s1.CommitTime)
  112. }
  113. // Compare height & blockHash
  114. if s0.Height != s1.Height {
  115. t.Error("Height mismatch")
  116. }
  117. if !bytes.Equal(s0.BlockHash, s1.BlockHash) {
  118. t.Error("BlockHash mismatch")
  119. }
  120. // Compare state merkle trees
  121. if s0.BondedValidators.Size() != s1.BondedValidators.Size() {
  122. t.Error("BondedValidators Size mismatch")
  123. }
  124. if s0.BondedValidators.TotalVotingPower() != s1.BondedValidators.TotalVotingPower() {
  125. t.Error("BondedValidators TotalVotingPower mismatch")
  126. }
  127. if bytes.Equal(s0.BondedValidators.Hash(), s1.BondedValidators.Hash()) {
  128. // The BondedValidators hash should have changed because
  129. // each AppendBlock() calls IncrementAccum(),
  130. // changing each validator's Accum.
  131. t.Error("BondedValidators hash should have changed")
  132. }
  133. if s0.UnbondingValidators.Size() != s1.UnbondingValidators.Size() {
  134. t.Error("UnbondingValidators Size mismatch")
  135. }
  136. if s0.UnbondingValidators.TotalVotingPower() != s1.UnbondingValidators.TotalVotingPower() {
  137. t.Error("UnbondingValidators TotalVotingPower mismatch")
  138. }
  139. if !bytes.Equal(s0.UnbondingValidators.Hash(), s1.UnbondingValidators.Hash()) {
  140. t.Error("UnbondingValidators hash mismatch")
  141. }
  142. if !bytes.Equal(s0.AccountDetails.Hash(), s1.AccountDetails.Hash()) {
  143. t.Error("AccountDetail mismatch")
  144. }
  145. }
  146. func TestTxSequence(t *testing.T) {
  147. state, privAccounts := randGenesisState(3, 1)
  148. acc1 := state.GetAccountDetail(1) // Non-validator
  149. // Try executing a SendTx with various sequence numbers.
  150. stx := &SendTx{
  151. BaseTx: BaseTx{
  152. Sequence: acc1.Sequence + 1,
  153. Fee: 0},
  154. To: 2,
  155. Amount: 1,
  156. }
  157. // Test a variety of sequence numbers for the tx.
  158. // The tx should only pass when i == 1.
  159. for i := -1; i < 3; i++ {
  160. stx.Sequence = uint(int(acc1.Sequence) + i)
  161. privAccounts[1].Sign(stx)
  162. stateCopy := state.Copy()
  163. err := stateCopy.ExecTx(stx)
  164. if i >= 1 {
  165. // Sequence is good.
  166. if err != nil {
  167. t.Errorf("Expected good sequence to pass")
  168. }
  169. // Check accDet.Sequence.
  170. newAcc1 := stateCopy.GetAccountDetail(1)
  171. if newAcc1.Sequence != stx.Sequence {
  172. t.Errorf("Expected account sequence to change")
  173. }
  174. } else {
  175. // Sequence is bad.
  176. if err == nil {
  177. t.Errorf("Expected bad sequence to fail")
  178. }
  179. // Check accDet.Sequence. (shouldn't have changed)
  180. newAcc1 := stateCopy.GetAccountDetail(1)
  181. if newAcc1.Sequence != acc1.Sequence {
  182. t.Errorf("Expected account sequence to not change")
  183. }
  184. }
  185. }
  186. }
  187. func TestTxs(t *testing.T) {
  188. state, privAccounts := randGenesisState(3, 1)
  189. acc0 := state.GetAccountDetail(0) // Validator
  190. //_, acc0Val := state.BondedValidators.GetById(0)
  191. if acc0.Status != AccountStatusBonded {
  192. t.Fatal("Expected acc0 to be bonded validator")
  193. }
  194. acc1 := state.GetAccountDetail(1) // Non-validator
  195. acc2 := state.GetAccountDetail(2) // Non-validator
  196. // SendTx.
  197. stx := &SendTx{
  198. BaseTx: BaseTx{
  199. Sequence: acc1.Sequence + 1,
  200. Fee: 0},
  201. To: 2,
  202. Amount: 1,
  203. }
  204. privAccounts[1].Sign(stx)
  205. err := state.ExecTx(stx)
  206. if err != nil {
  207. t.Errorf("Got error in executing send transaction, %v", err)
  208. }
  209. newAcc1 := state.GetAccountDetail(1)
  210. if acc1.Balance-1 != newAcc1.Balance {
  211. t.Errorf("Unexpected newAcc1 balance. Expected %v, got %v",
  212. acc1.Balance-1, newAcc1.Balance)
  213. }
  214. newAcc2 := state.GetAccountDetail(2)
  215. if acc2.Balance+1 != newAcc2.Balance {
  216. t.Errorf("Unexpected newAcc2 balance. Expected %v, got %v",
  217. acc2.Balance+1, newAcc2.Balance)
  218. }
  219. // BondTx.
  220. // XXX more tests for other transactions.
  221. }