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.

305 lines
8.1 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
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/account"
  4. . "github.com/tendermint/tendermint/binary"
  5. . "github.com/tendermint/tendermint/block"
  6. . "github.com/tendermint/tendermint/config"
  7. "bytes"
  8. "testing"
  9. "time"
  10. )
  11. func TestCopyState(t *testing.T) {
  12. // Generate a random state
  13. s0, privAccounts, _ := RandGenesisState(10, true, 1000, 5, true, 1000)
  14. s0Hash := s0.Hash()
  15. if len(s0Hash) == 0 {
  16. t.Error("Expected state hash")
  17. }
  18. // Check hash of copy
  19. s0Copy := s0.Copy()
  20. if !bytes.Equal(s0Hash, s0Copy.Hash()) {
  21. t.Error("Expected state copy hash to be the same")
  22. }
  23. // Mutate the original; hash should change.
  24. acc0Address := privAccounts[0].PubKey.Address()
  25. acc := s0.GetAccount(acc0Address)
  26. acc.Balance += 1
  27. // The account balance shouldn't have changed yet.
  28. if s0.GetAccount(acc0Address).Balance == acc.Balance {
  29. t.Error("Account balance changed unexpectedly")
  30. }
  31. // Setting, however, should change the balance.
  32. s0.SetAccount(acc)
  33. if s0.GetAccount(acc0Address).Balance != acc.Balance {
  34. t.Error("Account balance wasn't set")
  35. }
  36. // Now that the state changed, the hash should change too.
  37. if bytes.Equal(s0Hash, s0.Hash()) {
  38. t.Error("Expected state hash to have changed")
  39. }
  40. // The s0Copy shouldn't have changed though.
  41. if !bytes.Equal(s0Hash, s0Copy.Hash()) {
  42. t.Error("Expected state copy hash to have not changed")
  43. }
  44. }
  45. func TestGenesisSaveLoad(t *testing.T) {
  46. // Generate a state, save & load it.
  47. s0, _, _ := RandGenesisState(10, true, 1000, 5, true, 1000)
  48. // Mutate the state to append one empty block.
  49. block := &Block{
  50. Header: &Header{
  51. Network: Config.Network,
  52. Height: 1,
  53. Time: s0.LastBlockTime.Add(time.Minute),
  54. Fees: 0,
  55. NumTxs: 0,
  56. LastBlockHash: s0.LastBlockHash,
  57. LastBlockParts: s0.LastBlockParts,
  58. StateHash: nil,
  59. },
  60. Validation: &Validation{},
  61. Data: &Data{
  62. Txs: []Tx{},
  63. },
  64. }
  65. blockParts := NewPartSetFromData(BinaryBytes(block))
  66. // The last argument to AppendBlock() is `false`,
  67. // which sets Block.Header.StateHash.
  68. err := s0.Copy().AppendBlock(block, blockParts.Header(), false)
  69. if err != nil {
  70. t.Error("Error appending initial block:", err)
  71. }
  72. if len(block.Header.StateHash) == 0 {
  73. t.Error("Expected StateHash but got nothing.")
  74. }
  75. // Now append the block to s0.
  76. // This time we also check the StateHash (as computed above).
  77. err = s0.AppendBlock(block, blockParts.Header(), true)
  78. if err != nil {
  79. t.Error("Error appending initial block:", err)
  80. }
  81. // Save s0
  82. s0.Save()
  83. // Sanity check s0
  84. //s0.DB.(*db_.MemDB).Print()
  85. if s0.BondedValidators.TotalVotingPower() == 0 {
  86. t.Error("s0 BondedValidators TotalVotingPower should not be 0")
  87. }
  88. if s0.LastBlockHeight != 1 {
  89. t.Error("s0 LastBlockHeight should be 1, got", s0.LastBlockHeight)
  90. }
  91. // Load s1
  92. s1 := LoadState(s0.DB)
  93. // Compare height & blockHash
  94. if s0.LastBlockHeight != s1.LastBlockHeight {
  95. t.Error("LastBlockHeight mismatch")
  96. }
  97. if !bytes.Equal(s0.LastBlockHash, s1.LastBlockHash) {
  98. t.Error("LastBlockHash mismatch")
  99. }
  100. // Compare state merkle trees
  101. if s0.BondedValidators.Size() != s1.BondedValidators.Size() {
  102. t.Error("BondedValidators Size mismatch")
  103. }
  104. if s0.BondedValidators.TotalVotingPower() != s1.BondedValidators.TotalVotingPower() {
  105. t.Error("BondedValidators TotalVotingPower mismatch")
  106. }
  107. if !bytes.Equal(s0.BondedValidators.Hash(), s1.BondedValidators.Hash()) {
  108. t.Error("BondedValidators hash mismatch")
  109. }
  110. if s0.UnbondingValidators.Size() != s1.UnbondingValidators.Size() {
  111. t.Error("UnbondingValidators Size mismatch")
  112. }
  113. if s0.UnbondingValidators.TotalVotingPower() != s1.UnbondingValidators.TotalVotingPower() {
  114. t.Error("UnbondingValidators TotalVotingPower mismatch")
  115. }
  116. if !bytes.Equal(s0.UnbondingValidators.Hash(), s1.UnbondingValidators.Hash()) {
  117. t.Error("UnbondingValidators hash mismatch")
  118. }
  119. if !bytes.Equal(s0.accounts.Hash(), s1.accounts.Hash()) {
  120. t.Error("Accounts mismatch")
  121. }
  122. if !bytes.Equal(s0.validatorInfos.Hash(), s1.validatorInfos.Hash()) {
  123. t.Error("Accounts mismatch")
  124. }
  125. }
  126. func TestTxSequence(t *testing.T) {
  127. state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000)
  128. acc0 := state.GetAccount(privAccounts[0].PubKey.Address())
  129. acc0PubKey := privAccounts[0].PubKey
  130. acc1 := state.GetAccount(privAccounts[1].PubKey.Address())
  131. // Try executing a SendTx with various sequence numbers.
  132. makeSendTx := func(sequence uint) *SendTx {
  133. return &SendTx{
  134. Inputs: []*TxInput{
  135. &TxInput{
  136. Address: acc0.Address,
  137. Amount: 1,
  138. Sequence: sequence,
  139. PubKey: acc0PubKey,
  140. },
  141. },
  142. Outputs: []*TxOutput{
  143. &TxOutput{
  144. Address: acc1.Address,
  145. Amount: 1,
  146. },
  147. },
  148. }
  149. }
  150. // Test a variety of sequence numbers for the tx.
  151. // The tx should only pass when i == 1.
  152. for i := -1; i < 3; i++ {
  153. sequence := acc0.Sequence + uint(i)
  154. tx := makeSendTx(sequence)
  155. tx.Inputs[0].Signature = privAccounts[0].Sign(tx)
  156. stateCopy := state.Copy()
  157. err := stateCopy.ExecTx(tx)
  158. if i == 1 {
  159. // Sequence is good.
  160. if err != nil {
  161. t.Errorf("Expected good sequence to pass: %v", err)
  162. }
  163. // Check acc.Sequence.
  164. newAcc0 := stateCopy.GetAccount(acc0.Address)
  165. if newAcc0.Sequence != sequence {
  166. t.Errorf("Expected account sequence to change to %v, got %v",
  167. sequence, newAcc0.Sequence)
  168. }
  169. } else {
  170. // Sequence is bad.
  171. if err == nil {
  172. t.Errorf("Expected bad sequence to fail")
  173. }
  174. // Check acc.Sequence. (shouldn't have changed)
  175. newAcc0 := stateCopy.GetAccount(acc0.Address)
  176. if newAcc0.Sequence != acc0.Sequence {
  177. t.Errorf("Expected account sequence to not change from %v, got %v",
  178. acc0.Sequence, newAcc0.Sequence)
  179. }
  180. }
  181. }
  182. }
  183. // TODO: test overflows.
  184. // TODO: test for unbonding validators.
  185. func TestTxs(t *testing.T) {
  186. state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000)
  187. //val0 := state.GetValidatorInfo(privValidators[0].Address)
  188. acc0 := state.GetAccount(privAccounts[0].PubKey.Address())
  189. acc0PubKey := privAccounts[0].PubKey
  190. acc1 := state.GetAccount(privAccounts[1].PubKey.Address())
  191. // SendTx.
  192. {
  193. state := state.Copy()
  194. tx := &SendTx{
  195. Inputs: []*TxInput{
  196. &TxInput{
  197. Address: acc0.Address,
  198. Amount: 1,
  199. Sequence: acc0.Sequence + 1,
  200. PubKey: acc0PubKey,
  201. },
  202. },
  203. Outputs: []*TxOutput{
  204. &TxOutput{
  205. Address: acc1.Address,
  206. Amount: 1,
  207. },
  208. },
  209. }
  210. tx.Inputs[0].Signature = privAccounts[0].Sign(tx)
  211. err := state.ExecTx(tx)
  212. if err != nil {
  213. t.Errorf("Got error in executing send transaction, %v", err)
  214. }
  215. newAcc0 := state.GetAccount(acc0.Address)
  216. if acc0.Balance-1 != newAcc0.Balance {
  217. t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v",
  218. acc0.Balance-1, newAcc0.Balance)
  219. }
  220. newAcc1 := state.GetAccount(acc1.Address)
  221. if acc1.Balance+1 != newAcc1.Balance {
  222. t.Errorf("Unexpected newAcc1 balance. Expected %v, got %v",
  223. acc1.Balance+1, newAcc1.Balance)
  224. }
  225. }
  226. // BondTx.
  227. {
  228. state := state.Copy()
  229. tx := &BondTx{
  230. PubKey: acc0PubKey.(PubKeyEd25519),
  231. Inputs: []*TxInput{
  232. &TxInput{
  233. Address: acc0.Address,
  234. Amount: 1,
  235. Sequence: acc0.Sequence + 1,
  236. PubKey: acc0PubKey,
  237. },
  238. },
  239. UnbondTo: []*TxOutput{
  240. &TxOutput{
  241. Address: acc0.Address,
  242. Amount: 1,
  243. },
  244. },
  245. }
  246. tx.Inputs[0].Signature = privAccounts[0].Sign(tx)
  247. err := state.ExecTx(tx)
  248. if err != nil {
  249. t.Errorf("Got error in executing bond transaction, %v", err)
  250. }
  251. newAcc0 := state.GetAccount(acc0.Address)
  252. if newAcc0.Balance != acc0.Balance-1 {
  253. t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v",
  254. acc0.Balance-1, newAcc0.Balance)
  255. }
  256. _, acc0Val := state.BondedValidators.GetByAddress(acc0.Address)
  257. if acc0Val == nil {
  258. t.Errorf("acc0Val not present")
  259. }
  260. if acc0Val.BondHeight != state.LastBlockHeight+1 {
  261. t.Errorf("Unexpected bond height. Expected %v, got %v",
  262. state.LastBlockHeight, acc0Val.BondHeight)
  263. }
  264. if acc0Val.VotingPower != 1 {
  265. t.Errorf("Unexpected voting power. Expected %v, got %v",
  266. acc0Val.VotingPower, acc0.Balance)
  267. }
  268. if acc0Val.Accum != 0 {
  269. t.Errorf("Unexpected accum. Expected 0, got %v",
  270. acc0Val.Accum)
  271. }
  272. }
  273. // TODO UnbondTx.
  274. }