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.

736 lines
21 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
  1. package state
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "time"
  7. "github.com/tendermint/tendermint/account"
  8. "github.com/tendermint/tendermint/binary"
  9. blk "github.com/tendermint/tendermint/block"
  10. . "github.com/tendermint/tendermint/common"
  11. dbm "github.com/tendermint/tendermint/db"
  12. "github.com/tendermint/tendermint/merkle"
  13. )
  14. var (
  15. stateKey = []byte("stateKey")
  16. minBondAmount = uint64(1) // TODO adjust
  17. defaultAccountsCacheCapacity = 1000 // TODO adjust
  18. unbondingPeriodBlocks = uint(60 * 24 * 365) // TODO probably better to make it time based.
  19. validatorTimeoutBlocks = uint(10) // TODO adjust
  20. )
  21. //-----------------------------------------------------------------------------
  22. type InvalidTxError struct {
  23. Tx blk.Tx
  24. Reason error
  25. }
  26. func (txErr InvalidTxError) Error() string {
  27. return fmt.Sprintf("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason)
  28. }
  29. //-----------------------------------------------------------------------------
  30. // NOTE: not goroutine-safe.
  31. type State struct {
  32. DB dbm.DB
  33. LastBlockHeight uint
  34. LastBlockHash []byte
  35. LastBlockParts blk.PartSetHeader
  36. LastBlockTime time.Time
  37. BondedValidators *ValidatorSet
  38. LastBondedValidators *ValidatorSet
  39. UnbondingValidators *ValidatorSet
  40. accounts merkle.Tree // Shouldn't be accessed directly.
  41. validatorInfos merkle.Tree // Shouldn't be accessed directly.
  42. }
  43. func LoadState(db dbm.DB) *State {
  44. s := &State{DB: db}
  45. buf := db.Get(stateKey)
  46. if len(buf) == 0 {
  47. return nil
  48. } else {
  49. r, n, err := bytes.NewReader(buf), new(int64), new(error)
  50. s.LastBlockHeight = binary.ReadUvarint(r, n, err)
  51. s.LastBlockHash = binary.ReadByteSlice(r, n, err)
  52. s.LastBlockParts = binary.ReadBinary(blk.PartSetHeader{}, r, n, err).(blk.PartSetHeader)
  53. s.LastBlockTime = binary.ReadTime(r, n, err)
  54. s.BondedValidators = binary.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet)
  55. s.LastBondedValidators = binary.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet)
  56. s.UnbondingValidators = binary.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet)
  57. accountsHash := binary.ReadByteSlice(r, n, err)
  58. s.accounts = merkle.NewIAVLTree(binary.BasicCodec, account.AccountCodec, defaultAccountsCacheCapacity, db)
  59. s.accounts.Load(accountsHash)
  60. validatorInfosHash := binary.ReadByteSlice(r, n, err)
  61. s.validatorInfos = merkle.NewIAVLTree(binary.BasicCodec, ValidatorInfoCodec, 0, db)
  62. s.validatorInfos.Load(validatorInfosHash)
  63. if *err != nil {
  64. panic(*err)
  65. }
  66. // TODO: ensure that buf is completely read.
  67. }
  68. return s
  69. }
  70. // Save this state into the db.
  71. func (s *State) Save() {
  72. s.accounts.Save()
  73. s.validatorInfos.Save()
  74. buf, n, err := new(bytes.Buffer), new(int64), new(error)
  75. binary.WriteUvarint(s.LastBlockHeight, buf, n, err)
  76. binary.WriteByteSlice(s.LastBlockHash, buf, n, err)
  77. binary.WriteBinary(s.LastBlockParts, buf, n, err)
  78. binary.WriteTime(s.LastBlockTime, buf, n, err)
  79. binary.WriteBinary(s.BondedValidators, buf, n, err)
  80. binary.WriteBinary(s.LastBondedValidators, buf, n, err)
  81. binary.WriteBinary(s.UnbondingValidators, buf, n, err)
  82. binary.WriteByteSlice(s.accounts.Hash(), buf, n, err)
  83. binary.WriteByteSlice(s.validatorInfos.Hash(), buf, n, err)
  84. if *err != nil {
  85. panic(*err)
  86. }
  87. s.DB.Set(stateKey, buf.Bytes())
  88. }
  89. func (s *State) Copy() *State {
  90. return &State{
  91. DB: s.DB,
  92. LastBlockHeight: s.LastBlockHeight,
  93. LastBlockHash: s.LastBlockHash,
  94. LastBlockParts: s.LastBlockParts,
  95. LastBlockTime: s.LastBlockTime,
  96. BondedValidators: s.BondedValidators.Copy(),
  97. LastBondedValidators: s.LastBondedValidators.Copy(),
  98. UnbondingValidators: s.UnbondingValidators.Copy(),
  99. accounts: s.accounts.Copy(),
  100. validatorInfos: s.validatorInfos.Copy(),
  101. }
  102. }
  103. // The accounts from the TxInputs must either already have
  104. // account.PubKey.(type) != PubKeyNil, (it must be known),
  105. // or it must be specified in the TxInput. If redeclared,
  106. // the TxInput is modified and input.PubKey set to PubKeyNil.
  107. func (s *State) GetOrMakeAccounts(ins []*blk.TxInput, outs []*blk.TxOutput) (map[string]*account.Account, error) {
  108. accounts := map[string]*account.Account{}
  109. for _, in := range ins {
  110. // Account shouldn't be duplicated
  111. if _, ok := accounts[string(in.Address)]; ok {
  112. return nil, blk.ErrTxDuplicateAddress
  113. }
  114. acc := s.GetAccount(in.Address)
  115. if acc == nil {
  116. return nil, blk.ErrTxInvalidAddress
  117. }
  118. // PubKey should be present in either "account" or "in"
  119. if err := checkInputPubKey(acc, in); err != nil {
  120. return nil, err
  121. }
  122. accounts[string(in.Address)] = acc
  123. }
  124. for _, out := range outs {
  125. // Account shouldn't be duplicated
  126. if _, ok := accounts[string(out.Address)]; ok {
  127. return nil, blk.ErrTxDuplicateAddress
  128. }
  129. acc := s.GetAccount(out.Address)
  130. // output account may be nil (new)
  131. if acc == nil {
  132. acc = &account.Account{
  133. Address: out.Address,
  134. PubKey: account.PubKeyNil{},
  135. Sequence: 0,
  136. Balance: 0,
  137. }
  138. }
  139. accounts[string(out.Address)] = acc
  140. }
  141. return accounts, nil
  142. }
  143. func checkInputPubKey(acc *account.Account, in *blk.TxInput) error {
  144. if _, isNil := acc.PubKey.(account.PubKeyNil); isNil {
  145. if _, isNil := in.PubKey.(account.PubKeyNil); isNil {
  146. return blk.ErrTxUnknownPubKey
  147. }
  148. if !bytes.Equal(in.PubKey.Address(), acc.Address) {
  149. return blk.ErrTxInvalidPubKey
  150. }
  151. acc.PubKey = in.PubKey
  152. } else {
  153. in.PubKey = account.PubKeyNil{}
  154. }
  155. return nil
  156. }
  157. func (s *State) ValidateInputs(accounts map[string]*account.Account, signBytes []byte, ins []*blk.TxInput) (total uint64, err error) {
  158. for _, in := range ins {
  159. acc := accounts[string(in.Address)]
  160. if acc == nil {
  161. panic("ValidateInputs() expects account in accounts")
  162. }
  163. // Check TxInput basic
  164. if err := in.ValidateBasic(); err != nil {
  165. return 0, err
  166. }
  167. // Check signatures
  168. if !acc.PubKey.VerifyBytes(signBytes, in.Signature) {
  169. return 0, blk.ErrTxInvalidSignature
  170. }
  171. // Check sequences
  172. if acc.Sequence+1 != in.Sequence {
  173. return 0, blk.ErrTxInvalidSequence
  174. }
  175. // Check amount
  176. if acc.Balance < in.Amount {
  177. return 0, blk.ErrTxInsufficientFunds
  178. }
  179. // Good. Add amount to total
  180. total += in.Amount
  181. }
  182. return total, nil
  183. }
  184. func (s *State) ValidateOutputs(outs []*blk.TxOutput) (total uint64, err error) {
  185. for _, out := range outs {
  186. // Check TxOutput basic
  187. if err := out.ValidateBasic(); err != nil {
  188. return 0, err
  189. }
  190. // Good. Add amount to total
  191. total += out.Amount
  192. }
  193. return total, nil
  194. }
  195. func (s *State) AdjustByInputs(accounts map[string]*account.Account, ins []*blk.TxInput) {
  196. for _, in := range ins {
  197. acc := accounts[string(in.Address)]
  198. if acc == nil {
  199. panic("AdjustByInputs() expects account in accounts")
  200. }
  201. if acc.Balance < in.Amount {
  202. panic("AdjustByInputs() expects sufficient funds")
  203. }
  204. acc.Balance -= in.Amount
  205. acc.Sequence += 1
  206. }
  207. }
  208. func (s *State) AdjustByOutputs(accounts map[string]*account.Account, outs []*blk.TxOutput) {
  209. for _, out := range outs {
  210. acc := accounts[string(out.Address)]
  211. if acc == nil {
  212. panic("AdjustByOutputs() expects account in accounts")
  213. }
  214. acc.Balance += out.Amount
  215. }
  216. }
  217. // If the tx is invalid, an error will be returned.
  218. // Unlike AppendBlock(), state will not be altered.
  219. func (s *State) ExecTx(tx_ blk.Tx, runCall bool) error {
  220. // TODO: do something with fees
  221. fees := uint64(0)
  222. // Exec tx
  223. switch tx := tx_.(type) {
  224. case *blk.SendTx:
  225. accounts, err := s.GetOrMakeAccounts(tx.Inputs, tx.Outputs)
  226. if err != nil {
  227. return err
  228. }
  229. signBytes := account.SignBytes(tx)
  230. inTotal, err := s.ValidateInputs(accounts, signBytes, tx.Inputs)
  231. if err != nil {
  232. return err
  233. }
  234. outTotal, err := s.ValidateOutputs(tx.Outputs)
  235. if err != nil {
  236. return err
  237. }
  238. if outTotal > inTotal {
  239. return blk.ErrTxInsufficientFunds
  240. }
  241. fee := inTotal - outTotal
  242. fees += fee
  243. // Good! Adjust accounts
  244. s.AdjustByInputs(accounts, tx.Inputs)
  245. s.AdjustByOutputs(accounts, tx.Outputs)
  246. s.UpdateAccounts(accounts)
  247. return nil
  248. case *blk.CallTx:
  249. accounts := map[string]*account.Account{}
  250. inAcc := s.GetAccount(tx.Input.Address)
  251. if inAcc == nil {
  252. return blk.ErrTxInvalidAddress
  253. }
  254. // PubKey should be present in either "inAcc" or "tx.Input"
  255. if err := checkInputPubKey(inAcc, tx.Input); err != nil {
  256. return err
  257. }
  258. accounts[string(tx.Input.Address)] = inAcc
  259. signBytes := account.SignBytes(tx)
  260. inTotal, err := s.ValidateInputs(accounts, signBytes, []*blk.TxInput{tx.Input})
  261. if err != nil {
  262. return err
  263. }
  264. // validate output address
  265. if len(tx.Address) != 20 {
  266. return blk.ErrTxInvalidAddress
  267. }
  268. outAcc := s.GetAccount(tx.Address)
  269. if outAcc == nil {
  270. return blk.ErrTxInvalidAddress
  271. }
  272. accounts[string(tx.Address)] = outAcc
  273. inTotal -= tx.Fee
  274. // Good! Adjust accounts
  275. s.AdjustByInputs(accounts, []*blk.TxInput{tx.Input})
  276. outAcc.Balance += inTotal
  277. s.UpdateAccounts(accounts)
  278. if runCall {
  279. // TODO: Run the contract call!
  280. // TODO: refund some gas
  281. }
  282. return nil
  283. case *blk.BondTx:
  284. valInfo := s.GetValidatorInfo(tx.PubKey.Address())
  285. if valInfo != nil {
  286. // TODO: In the future, check that the validator wasn't destroyed,
  287. // add funds, merge UnbondTo outputs, and unbond validator.
  288. return errors.New("Adding coins to existing validators not yet supported")
  289. }
  290. accounts, err := s.GetOrMakeAccounts(tx.Inputs, nil)
  291. if err != nil {
  292. return err
  293. }
  294. signBytes := account.SignBytes(tx)
  295. inTotal, err := s.ValidateInputs(accounts, signBytes, tx.Inputs)
  296. if err != nil {
  297. return err
  298. }
  299. if err := tx.PubKey.ValidateBasic(); err != nil {
  300. return err
  301. }
  302. outTotal, err := s.ValidateOutputs(tx.UnbondTo)
  303. if err != nil {
  304. return err
  305. }
  306. if outTotal > inTotal {
  307. return blk.ErrTxInsufficientFunds
  308. }
  309. fee := inTotal - outTotal
  310. fees += fee
  311. // Good! Adjust accounts
  312. s.AdjustByInputs(accounts, tx.Inputs)
  313. s.UpdateAccounts(accounts)
  314. // Add ValidatorInfo
  315. s.SetValidatorInfo(&ValidatorInfo{
  316. Address: tx.PubKey.Address(),
  317. PubKey: tx.PubKey,
  318. UnbondTo: tx.UnbondTo,
  319. FirstBondHeight: s.LastBlockHeight + 1,
  320. FirstBondAmount: outTotal,
  321. })
  322. // Add Validator
  323. added := s.BondedValidators.Add(&Validator{
  324. Address: tx.PubKey.Address(),
  325. PubKey: tx.PubKey,
  326. BondHeight: s.LastBlockHeight + 1,
  327. VotingPower: outTotal,
  328. Accum: 0,
  329. })
  330. if !added {
  331. panic("Failed to add validator")
  332. }
  333. return nil
  334. case *blk.UnbondTx:
  335. // The validator must be active
  336. _, val := s.BondedValidators.GetByAddress(tx.Address)
  337. if val == nil {
  338. return blk.ErrTxInvalidAddress
  339. }
  340. // Verify the signature
  341. signBytes := account.SignBytes(tx)
  342. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  343. return blk.ErrTxInvalidSignature
  344. }
  345. // tx.Height must be greater than val.LastCommitHeight
  346. if tx.Height <= val.LastCommitHeight {
  347. return errors.New("Invalid unbond height")
  348. }
  349. // Good!
  350. s.unbondValidator(val)
  351. return nil
  352. case *blk.RebondTx:
  353. // The validator must be inactive
  354. _, val := s.UnbondingValidators.GetByAddress(tx.Address)
  355. if val == nil {
  356. return blk.ErrTxInvalidAddress
  357. }
  358. // Verify the signature
  359. signBytes := account.SignBytes(tx)
  360. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  361. return blk.ErrTxInvalidSignature
  362. }
  363. // tx.Height must be equal to the next height
  364. if tx.Height != s.LastBlockHeight+1 {
  365. return errors.New(Fmt("Invalid rebond height. Expected %v, got %v", s.LastBlockHeight+1, tx.Height))
  366. }
  367. // Good!
  368. s.rebondValidator(val)
  369. return nil
  370. case *blk.DupeoutTx:
  371. // Verify the signatures
  372. _, accused := s.BondedValidators.GetByAddress(tx.Address)
  373. if accused == nil {
  374. _, accused = s.UnbondingValidators.GetByAddress(tx.Address)
  375. if accused == nil {
  376. return blk.ErrTxInvalidAddress
  377. }
  378. }
  379. voteASignBytes := account.SignBytes(&tx.VoteA)
  380. voteBSignBytes := account.SignBytes(&tx.VoteB)
  381. if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) ||
  382. !accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) {
  383. return blk.ErrTxInvalidSignature
  384. }
  385. // Verify equivocation
  386. // TODO: in the future, just require one vote from a previous height that
  387. // doesn't exist on this chain.
  388. if tx.VoteA.Height != tx.VoteB.Height {
  389. return errors.New("DupeoutTx heights don't match")
  390. }
  391. if tx.VoteA.Type == blk.VoteTypeCommit && tx.VoteA.Round < tx.VoteB.Round {
  392. // Check special case (not an error, validator must be slashed!)
  393. // Validators should not sign another vote after committing.
  394. } else if tx.VoteB.Type == blk.VoteTypeCommit && tx.VoteB.Round < tx.VoteA.Round {
  395. // We need to check both orderings of the votes
  396. } else {
  397. if tx.VoteA.Round != tx.VoteB.Round {
  398. return errors.New("DupeoutTx rounds don't match")
  399. }
  400. if tx.VoteA.Type != tx.VoteB.Type {
  401. return errors.New("DupeoutTx types don't match")
  402. }
  403. if bytes.Equal(tx.VoteA.BlockHash, tx.VoteB.BlockHash) {
  404. return errors.New("DupeoutTx blockhashes shouldn't match")
  405. }
  406. }
  407. // Good! (Bad validator!)
  408. s.destroyValidator(accused)
  409. return nil
  410. default:
  411. panic("Unknown Tx type")
  412. }
  413. }
  414. func (s *State) unbondValidator(val *Validator) {
  415. // Move validator to UnbondingValidators
  416. val, removed := s.BondedValidators.Remove(val.Address)
  417. if !removed {
  418. panic("Couldn't remove validator for unbonding")
  419. }
  420. val.UnbondHeight = s.LastBlockHeight + 1
  421. added := s.UnbondingValidators.Add(val)
  422. if !added {
  423. panic("Couldn't add validator for unbonding")
  424. }
  425. }
  426. func (s *State) rebondValidator(val *Validator) {
  427. // Move validator to BondingValidators
  428. val, removed := s.UnbondingValidators.Remove(val.Address)
  429. if !removed {
  430. panic("Couldn't remove validator for rebonding")
  431. }
  432. val.BondHeight = s.LastBlockHeight + 1
  433. added := s.BondedValidators.Add(val)
  434. if !added {
  435. panic("Couldn't add validator for rebonding")
  436. }
  437. }
  438. func (s *State) releaseValidator(val *Validator) {
  439. // Update validatorInfo
  440. valInfo := s.GetValidatorInfo(val.Address)
  441. if valInfo == nil {
  442. panic("Couldn't find validatorInfo for release")
  443. }
  444. valInfo.ReleasedHeight = s.LastBlockHeight + 1
  445. s.SetValidatorInfo(valInfo)
  446. // Send coins back to UnbondTo outputs
  447. accounts, err := s.GetOrMakeAccounts(nil, valInfo.UnbondTo)
  448. if err != nil {
  449. panic("Couldn't get or make unbondTo accounts")
  450. }
  451. s.AdjustByOutputs(accounts, valInfo.UnbondTo)
  452. s.UpdateAccounts(accounts)
  453. // Remove validator from UnbondingValidators
  454. _, removed := s.UnbondingValidators.Remove(val.Address)
  455. if !removed {
  456. panic("Couldn't remove validator for release")
  457. }
  458. }
  459. func (s *State) destroyValidator(val *Validator) {
  460. // Update validatorInfo
  461. valInfo := s.GetValidatorInfo(val.Address)
  462. if valInfo == nil {
  463. panic("Couldn't find validatorInfo for release")
  464. }
  465. valInfo.DestroyedHeight = s.LastBlockHeight + 1
  466. valInfo.DestroyedAmount = val.VotingPower
  467. s.SetValidatorInfo(valInfo)
  468. // Remove validator
  469. _, removed := s.BondedValidators.Remove(val.Address)
  470. if !removed {
  471. _, removed := s.UnbondingValidators.Remove(val.Address)
  472. if !removed {
  473. panic("Couldn't remove validator for destruction")
  474. }
  475. }
  476. }
  477. // NOTE: If an error occurs during block execution, state will be left
  478. // at an invalid state. Copy the state before calling AppendBlock!
  479. func (s *State) AppendBlock(block *blk.Block, blockPartsHeader blk.PartSetHeader) error {
  480. err := s.appendBlock(block, blockPartsHeader)
  481. if err != nil {
  482. return err
  483. }
  484. // State.Hash should match block.StateHash
  485. stateHash := s.Hash()
  486. if !bytes.Equal(stateHash, block.StateHash) {
  487. return Errorf("Invalid state hash. Expected %X, got %X",
  488. stateHash, block.StateHash)
  489. }
  490. return nil
  491. }
  492. func (s *State) SetBlockStateHash(block *blk.Block) error {
  493. sCopy := s.Copy()
  494. err := sCopy.appendBlock(block, blk.PartSetHeader{})
  495. if err != nil {
  496. return err
  497. }
  498. // Set block.StateHash
  499. block.StateHash = sCopy.Hash()
  500. return nil
  501. }
  502. // Appends the block, does not check block.StateHash
  503. // NOTE: If an error occurs during block execution, state will be left
  504. // at an invalid state. Copy the state before calling appendBlock!
  505. func (s *State) appendBlock(block *blk.Block, blockPartsHeader blk.PartSetHeader) error {
  506. // Basic block validation.
  507. err := block.ValidateBasic(s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime)
  508. if err != nil {
  509. return err
  510. }
  511. // Validate block Validation.
  512. if block.Height == 1 {
  513. if len(block.Validation.Commits) != 0 {
  514. return errors.New("Block at height 1 (first block) should have no Validation commits")
  515. }
  516. } else {
  517. if uint(len(block.Validation.Commits)) != s.LastBondedValidators.Size() {
  518. return errors.New(Fmt("Invalid block validation size. Expected %v, got %v",
  519. s.LastBondedValidators.Size(), len(block.Validation.Commits)))
  520. }
  521. var sumVotingPower uint64
  522. s.LastBondedValidators.Iterate(func(index uint, val *Validator) bool {
  523. commit := block.Validation.Commits[index]
  524. if commit.IsZero() {
  525. return false
  526. } else {
  527. vote := &blk.Vote{
  528. Height: block.Height - 1,
  529. Round: commit.Round,
  530. Type: blk.VoteTypeCommit,
  531. BlockHash: block.LastBlockHash,
  532. BlockParts: block.LastBlockParts,
  533. }
  534. if val.PubKey.VerifyBytes(account.SignBytes(vote), commit.Signature) {
  535. sumVotingPower += val.VotingPower
  536. return false
  537. } else {
  538. log.Warn(Fmt("Invalid validation signature.\nval: %v\nvote: %v", val, vote))
  539. err = errors.New("Invalid validation signature")
  540. return true
  541. }
  542. }
  543. })
  544. if err != nil {
  545. return err
  546. }
  547. if sumVotingPower <= s.LastBondedValidators.TotalVotingPower()*2/3 {
  548. return errors.New("Insufficient validation voting power")
  549. }
  550. }
  551. // Update Validator.LastCommitHeight as necessary.
  552. for i, commit := range block.Validation.Commits {
  553. if commit.IsZero() {
  554. continue
  555. }
  556. _, val := s.LastBondedValidators.GetByIndex(uint(i))
  557. if val == nil {
  558. panic(Fmt("Failed to fetch validator at index %v", i))
  559. }
  560. if _, val_ := s.BondedValidators.GetByAddress(val.Address); val_ != nil {
  561. val_.LastCommitHeight = block.Height - 1
  562. updated := s.BondedValidators.Update(val_)
  563. if !updated {
  564. panic("Failed to update bonded validator LastCommitHeight")
  565. }
  566. } else if _, val_ := s.UnbondingValidators.GetByAddress(val.Address); val_ != nil {
  567. val_.LastCommitHeight = block.Height - 1
  568. updated := s.UnbondingValidators.Update(val_)
  569. if !updated {
  570. panic("Failed to update unbonding validator LastCommitHeight")
  571. }
  572. } else {
  573. panic("Could not find validator")
  574. }
  575. }
  576. // Remember LastBondedValidators
  577. s.LastBondedValidators = s.BondedValidators.Copy()
  578. // Commit each tx
  579. for _, tx := range block.Data.Txs {
  580. err := s.ExecTx(tx, true)
  581. if err != nil {
  582. return InvalidTxError{tx, err}
  583. }
  584. }
  585. // If any unbonding periods are over,
  586. // reward account with bonded coins.
  587. toRelease := []*Validator{}
  588. s.UnbondingValidators.Iterate(func(index uint, val *Validator) bool {
  589. if val.UnbondHeight+unbondingPeriodBlocks < block.Height {
  590. toRelease = append(toRelease, val)
  591. }
  592. return false
  593. })
  594. for _, val := range toRelease {
  595. s.releaseValidator(val)
  596. }
  597. // If any validators haven't signed in a while,
  598. // unbond them, they have timed out.
  599. toTimeout := []*Validator{}
  600. s.BondedValidators.Iterate(func(index uint, val *Validator) bool {
  601. lastActivityHeight := MaxUint(val.BondHeight, val.LastCommitHeight)
  602. if lastActivityHeight+validatorTimeoutBlocks < block.Height {
  603. log.Info("Validator timeout", "validator", val, "height", block.Height)
  604. toTimeout = append(toTimeout, val)
  605. }
  606. return false
  607. })
  608. for _, val := range toTimeout {
  609. s.unbondValidator(val)
  610. }
  611. // Increment validator AccumPowers
  612. s.BondedValidators.IncrementAccum(1)
  613. s.LastBlockHeight = block.Height
  614. s.LastBlockHash = block.Hash()
  615. s.LastBlockParts = blockPartsHeader
  616. s.LastBlockTime = block.Time
  617. return nil
  618. }
  619. // The returned Account is a copy, so mutating it
  620. // has no side effects.
  621. func (s *State) GetAccount(address []byte) *account.Account {
  622. _, acc := s.accounts.Get(address)
  623. if acc == nil {
  624. return nil
  625. }
  626. return acc.(*account.Account).Copy()
  627. }
  628. // The returned Account is a copy, so mutating it
  629. // has no side effects.
  630. func (s *State) GetAccounts() merkle.Tree {
  631. return s.accounts.Copy()
  632. }
  633. // The account is copied before setting, so mutating it
  634. // afterwards has no side effects.
  635. func (s *State) UpdateAccount(account *account.Account) {
  636. s.accounts.Set(account.Address, account.Copy())
  637. }
  638. // The accounts are copied before setting, so mutating it
  639. // afterwards has no side effects.
  640. func (s *State) UpdateAccounts(accounts map[string]*account.Account) {
  641. for _, acc := range accounts {
  642. s.accounts.Set(acc.Address, acc.Copy())
  643. }
  644. }
  645. // The returned ValidatorInfo is a copy, so mutating it
  646. // has no side effects.
  647. func (s *State) GetValidatorInfo(address []byte) *ValidatorInfo {
  648. _, valInfo := s.validatorInfos.Get(address)
  649. if valInfo == nil {
  650. return nil
  651. }
  652. return valInfo.(*ValidatorInfo).Copy()
  653. }
  654. // Returns false if new, true if updated.
  655. // The valInfo is copied before setting, so mutating it
  656. // afterwards has no side effects.
  657. func (s *State) SetValidatorInfo(valInfo *ValidatorInfo) (updated bool) {
  658. return s.validatorInfos.Set(valInfo.Address, valInfo.Copy())
  659. }
  660. // Returns a hash that represents the state data,
  661. // excluding Last*
  662. func (s *State) Hash() []byte {
  663. hashables := []merkle.Hashable{
  664. s.BondedValidators,
  665. s.UnbondingValidators,
  666. s.accounts,
  667. s.validatorInfos,
  668. }
  669. return merkle.HashFromHashables(hashables)
  670. }