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.

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