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.

386 lines
10 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
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/config"
  5. "github.com/tendermint/tendermint/types"
  6. "bytes"
  7. "testing"
  8. "time"
  9. )
  10. func TestCopyState(t *testing.T) {
  11. // Generate a random state
  12. s0, privAccounts, _ := RandGenesisState(10, true, 1000, 5, true, 1000)
  13. s0Hash := s0.Hash()
  14. if len(s0Hash) == 0 {
  15. t.Error("Expected state hash")
  16. }
  17. // Check hash of copy
  18. s0Copy := s0.Copy()
  19. if !bytes.Equal(s0Hash, s0Copy.Hash()) {
  20. t.Error("Expected state copy hash to be the same")
  21. }
  22. // Mutate the original; hash should change.
  23. acc0Address := privAccounts[0].PubKey.Address()
  24. acc := s0.GetAccount(acc0Address)
  25. acc.Balance += 1
  26. // The account balance shouldn't have changed yet.
  27. if s0.GetAccount(acc0Address).Balance == acc.Balance {
  28. t.Error("Account balance changed unexpectedly")
  29. }
  30. // Setting, however, should change the balance.
  31. s0.UpdateAccount(acc)
  32. if s0.GetAccount(acc0Address).Balance != acc.Balance {
  33. t.Error("Account balance wasn't set")
  34. }
  35. // Now that the state changed, the hash should change too.
  36. if bytes.Equal(s0Hash, s0.Hash()) {
  37. t.Error("Expected state hash to have changed")
  38. }
  39. // The s0Copy shouldn't have changed though.
  40. if !bytes.Equal(s0Hash, s0Copy.Hash()) {
  41. t.Error("Expected state copy hash to have not changed")
  42. }
  43. }
  44. func makeBlock(t *testing.T, state *State, commits []types.Commit, txs []types.Tx) *types.Block {
  45. block := &types.Block{
  46. Header: &types.Header{
  47. Network: config.App().GetString("Network"),
  48. Height: state.LastBlockHeight + 1,
  49. Time: state.LastBlockTime.Add(time.Minute),
  50. Fees: 0,
  51. NumTxs: uint(len(txs)),
  52. LastBlockHash: state.LastBlockHash,
  53. LastBlockParts: state.LastBlockParts,
  54. StateHash: nil,
  55. },
  56. Validation: &types.Validation{
  57. Commits: commits,
  58. },
  59. Data: &types.Data{
  60. Txs: txs,
  61. },
  62. }
  63. // Fill in block StateHash
  64. err := state.SetBlockStateHash(block)
  65. if err != nil {
  66. t.Error("Error appending initial block:", err)
  67. }
  68. if len(block.Header.StateHash) == 0 {
  69. t.Error("Expected StateHash but got nothing.")
  70. }
  71. return block
  72. }
  73. func TestGenesisSaveLoad(t *testing.T) {
  74. // Generate a state, save & load it.
  75. s0, _, _ := RandGenesisState(10, true, 1000, 5, true, 1000)
  76. // Make complete block and blockParts
  77. block := makeBlock(t, s0, nil, nil)
  78. blockParts := block.MakePartSet()
  79. // Now append the block to s0.
  80. err := s0.AppendBlock(block, blockParts.Header())
  81. if err != nil {
  82. t.Error("Error appending initial block:", err)
  83. }
  84. // Save s0
  85. s0.Save()
  86. // Sanity check s0
  87. //s0.DB.(*dbm.MemDB).Print()
  88. if s0.BondedValidators.TotalVotingPower() == 0 {
  89. t.Error("s0 BondedValidators TotalVotingPower should not be 0")
  90. }
  91. if s0.LastBlockHeight != 1 {
  92. t.Error("s0 LastBlockHeight should be 1, got", s0.LastBlockHeight)
  93. }
  94. // Load s1
  95. s1 := LoadState(s0.DB)
  96. // Compare height & blockHash
  97. if s0.LastBlockHeight != s1.LastBlockHeight {
  98. t.Error("LastBlockHeight mismatch")
  99. }
  100. if !bytes.Equal(s0.LastBlockHash, s1.LastBlockHash) {
  101. t.Error("LastBlockHash mismatch")
  102. }
  103. // Compare state merkle trees
  104. if s0.BondedValidators.Size() != s1.BondedValidators.Size() {
  105. t.Error("BondedValidators Size mismatch")
  106. }
  107. if s0.BondedValidators.TotalVotingPower() != s1.BondedValidators.TotalVotingPower() {
  108. t.Error("BondedValidators TotalVotingPower mismatch")
  109. }
  110. if !bytes.Equal(s0.BondedValidators.Hash(), s1.BondedValidators.Hash()) {
  111. t.Error("BondedValidators hash mismatch")
  112. }
  113. if s0.UnbondingValidators.Size() != s1.UnbondingValidators.Size() {
  114. t.Error("UnbondingValidators Size mismatch")
  115. }
  116. if s0.UnbondingValidators.TotalVotingPower() != s1.UnbondingValidators.TotalVotingPower() {
  117. t.Error("UnbondingValidators TotalVotingPower mismatch")
  118. }
  119. if !bytes.Equal(s0.UnbondingValidators.Hash(), s1.UnbondingValidators.Hash()) {
  120. t.Error("UnbondingValidators hash mismatch")
  121. }
  122. if !bytes.Equal(s0.accounts.Hash(), s1.accounts.Hash()) {
  123. t.Error("Accounts mismatch")
  124. }
  125. if !bytes.Equal(s0.validatorInfos.Hash(), s1.validatorInfos.Hash()) {
  126. t.Error("Accounts mismatch")
  127. }
  128. }
  129. func TestTxSequence(t *testing.T) {
  130. state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000)
  131. acc0 := state.GetAccount(privAccounts[0].PubKey.Address())
  132. acc0PubKey := privAccounts[0].PubKey
  133. acc1 := state.GetAccount(privAccounts[1].PubKey.Address())
  134. // Try executing a SendTx with various sequence numbers.
  135. makeSendTx := func(sequence uint) *types.SendTx {
  136. return &types.SendTx{
  137. Inputs: []*types.TxInput{
  138. &types.TxInput{
  139. Address: acc0.Address,
  140. Amount: 1,
  141. Sequence: sequence,
  142. PubKey: acc0PubKey,
  143. },
  144. },
  145. Outputs: []*types.TxOutput{
  146. &types.TxOutput{
  147. Address: acc1.Address,
  148. Amount: 1,
  149. },
  150. },
  151. }
  152. }
  153. // Test a variety of sequence numbers for the tx.
  154. // The tx should only pass when i == 1.
  155. for i := -1; i < 3; i++ {
  156. sequence := acc0.Sequence + uint(i)
  157. tx := makeSendTx(sequence)
  158. tx.Inputs[0].Signature = privAccounts[0].Sign(tx)
  159. stateCopy := state.Copy()
  160. err := stateCopy.ExecTx(tx, true)
  161. if i == 1 {
  162. // Sequence is good.
  163. if err != nil {
  164. t.Errorf("Expected good sequence to pass: %v", err)
  165. }
  166. // Check acc.Sequence.
  167. newAcc0 := stateCopy.GetAccount(acc0.Address)
  168. if newAcc0.Sequence != sequence {
  169. t.Errorf("Expected account sequence to change to %v, got %v",
  170. sequence, newAcc0.Sequence)
  171. }
  172. } else {
  173. // Sequence is bad.
  174. if err == nil {
  175. t.Errorf("Expected bad sequence to fail")
  176. }
  177. // Check acc.Sequence. (shouldn't have changed)
  178. newAcc0 := stateCopy.GetAccount(acc0.Address)
  179. if newAcc0.Sequence != acc0.Sequence {
  180. t.Errorf("Expected account sequence to not change from %v, got %v",
  181. acc0.Sequence, newAcc0.Sequence)
  182. }
  183. }
  184. }
  185. }
  186. // TODO: test overflows.
  187. // TODO: test for unbonding validators.
  188. func TestTxs(t *testing.T) {
  189. state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000)
  190. //val0 := state.GetValidatorInfo(privValidators[0].Address)
  191. acc0 := state.GetAccount(privAccounts[0].PubKey.Address())
  192. acc0PubKey := privAccounts[0].PubKey
  193. acc1 := state.GetAccount(privAccounts[1].PubKey.Address())
  194. // SendTx.
  195. {
  196. state := state.Copy()
  197. tx := &types.SendTx{
  198. Inputs: []*types.TxInput{
  199. &types.TxInput{
  200. Address: acc0.Address,
  201. Amount: 1,
  202. Sequence: acc0.Sequence + 1,
  203. PubKey: acc0PubKey,
  204. },
  205. },
  206. Outputs: []*types.TxOutput{
  207. &types.TxOutput{
  208. Address: acc1.Address,
  209. Amount: 1,
  210. },
  211. },
  212. }
  213. tx.Inputs[0].Signature = privAccounts[0].Sign(tx)
  214. err := state.ExecTx(tx, true)
  215. if err != nil {
  216. t.Errorf("Got error in executing send transaction, %v", err)
  217. }
  218. newAcc0 := state.GetAccount(acc0.Address)
  219. if acc0.Balance-1 != newAcc0.Balance {
  220. t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v",
  221. acc0.Balance-1, newAcc0.Balance)
  222. }
  223. newAcc1 := state.GetAccount(acc1.Address)
  224. if acc1.Balance+1 != newAcc1.Balance {
  225. t.Errorf("Unexpected newAcc1 balance. Expected %v, got %v",
  226. acc1.Balance+1, newAcc1.Balance)
  227. }
  228. }
  229. // BondTx.
  230. {
  231. state := state.Copy()
  232. tx := &types.BondTx{
  233. PubKey: acc0PubKey.(account.PubKeyEd25519),
  234. Inputs: []*types.TxInput{
  235. &types.TxInput{
  236. Address: acc0.Address,
  237. Amount: 1,
  238. Sequence: acc0.Sequence + 1,
  239. PubKey: acc0PubKey,
  240. },
  241. },
  242. UnbondTo: []*types.TxOutput{
  243. &types.TxOutput{
  244. Address: acc0.Address,
  245. Amount: 1,
  246. },
  247. },
  248. }
  249. tx.Inputs[0].Signature = privAccounts[0].Sign(tx)
  250. err := state.ExecTx(tx, true)
  251. if err != nil {
  252. t.Errorf("Got error in executing bond transaction, %v", err)
  253. }
  254. newAcc0 := state.GetAccount(acc0.Address)
  255. if newAcc0.Balance != acc0.Balance-1 {
  256. t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v",
  257. acc0.Balance-1, newAcc0.Balance)
  258. }
  259. _, acc0Val := state.BondedValidators.GetByAddress(acc0.Address)
  260. if acc0Val == nil {
  261. t.Errorf("acc0Val not present")
  262. }
  263. if acc0Val.BondHeight != state.LastBlockHeight+1 {
  264. t.Errorf("Unexpected bond height. Expected %v, got %v",
  265. state.LastBlockHeight, acc0Val.BondHeight)
  266. }
  267. if acc0Val.VotingPower != 1 {
  268. t.Errorf("Unexpected voting power. Expected %v, got %v",
  269. acc0Val.VotingPower, acc0.Balance)
  270. }
  271. if acc0Val.Accum != 0 {
  272. t.Errorf("Unexpected accum. Expected 0, got %v",
  273. acc0Val.Accum)
  274. }
  275. }
  276. // TODO UnbondTx.
  277. }
  278. func TestAddValidator(t *testing.T) {
  279. // Generate a state, save & load it.
  280. s0, privAccounts, privValidators := RandGenesisState(10, false, 1000, 1, false, 1000)
  281. // The first privAccount will become a validator
  282. acc0 := privAccounts[0]
  283. bondTx := &types.BondTx{
  284. PubKey: acc0.PubKey.(account.PubKeyEd25519),
  285. Inputs: []*types.TxInput{
  286. &types.TxInput{
  287. Address: acc0.Address,
  288. Amount: 1000,
  289. Sequence: 1,
  290. PubKey: acc0.PubKey,
  291. },
  292. },
  293. UnbondTo: []*types.TxOutput{
  294. &types.TxOutput{
  295. Address: acc0.Address,
  296. Amount: 1000,
  297. },
  298. },
  299. }
  300. bondTx.Inputs[0].Signature = acc0.Sign(bondTx)
  301. // Make complete block and blockParts
  302. block0 := makeBlock(t, s0, nil, []types.Tx{bondTx})
  303. block0Parts := block0.MakePartSet()
  304. // Sanity check
  305. if s0.BondedValidators.Size() != 1 {
  306. t.Error("Expected there to be 1 validators before bondTx")
  307. }
  308. // Now append the block to s0.
  309. err := s0.AppendBlock(block0, block0Parts.Header())
  310. if err != nil {
  311. t.Error("Error appending initial block:", err)
  312. }
  313. // Must save before further modification
  314. s0.Save()
  315. // Test new validator set
  316. if s0.BondedValidators.Size() != 2 {
  317. t.Error("Expected there to be 2 validators after bondTx")
  318. }
  319. // The validation for the next block should only require 1 signature
  320. // (the new validator wasn't active for block0)
  321. commit0 := &types.Vote{
  322. Height: 1,
  323. Round: 0,
  324. Type: types.VoteTypeCommit,
  325. BlockHash: block0.Hash(),
  326. BlockParts: block0Parts.Header(),
  327. }
  328. privValidators[0].SignVote(commit0)
  329. block1 := makeBlock(t, s0,
  330. []types.Commit{
  331. types.Commit{
  332. Address: privValidators[0].Address,
  333. Round: 0,
  334. Signature: commit0.Signature,
  335. },
  336. }, nil,
  337. )
  338. block1Parts := block1.MakePartSet()
  339. err = s0.AppendBlock(block1, block1Parts.Header())
  340. if err != nil {
  341. t.Error("Error appending secondary block:", err)
  342. }
  343. }