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.

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