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.

686 lines
20 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
  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 _, isNil := acc.PubKey.(account.PubKeyNil); isNil {
  120. if _, isNil := in.PubKey.(account.PubKeyNil); isNil {
  121. return nil, blk.ErrTxUnknownPubKey
  122. }
  123. if !bytes.Equal(in.PubKey.Address(), acc.Address) {
  124. return nil, blk.ErrTxInvalidPubKey
  125. }
  126. acc.PubKey = in.PubKey
  127. } else {
  128. in.PubKey = account.PubKeyNil{}
  129. }
  130. accounts[string(in.Address)] = acc
  131. }
  132. for _, out := range outs {
  133. // Account shouldn't be duplicated
  134. if _, ok := accounts[string(out.Address)]; ok {
  135. return nil, blk.ErrTxDuplicateAddress
  136. }
  137. acc := s.GetAccount(out.Address)
  138. // output account may be nil (new)
  139. if acc == nil {
  140. acc = &account.Account{
  141. Address: out.Address,
  142. PubKey: account.PubKeyNil{},
  143. Sequence: 0,
  144. Balance: 0,
  145. }
  146. }
  147. accounts[string(out.Address)] = acc
  148. }
  149. return accounts, nil
  150. }
  151. func (s *State) ValidateInputs(accounts map[string]*account.Account, signBytes []byte, ins []*blk.TxInput) (total uint64, err error) {
  152. for _, in := range ins {
  153. acc := accounts[string(in.Address)]
  154. if acc == nil {
  155. panic("ValidateInputs() expects account in accounts")
  156. }
  157. // Check TxInput basic
  158. if err := in.ValidateBasic(); err != nil {
  159. return 0, err
  160. }
  161. // Check signatures
  162. if !acc.PubKey.VerifyBytes(signBytes, in.Signature) {
  163. return 0, blk.ErrTxInvalidSignature
  164. }
  165. // Check sequences
  166. if acc.Sequence+1 != in.Sequence {
  167. return 0, blk.ErrTxInvalidSequence
  168. }
  169. // Check amount
  170. if acc.Balance < in.Amount {
  171. return 0, blk.ErrTxInsufficientFunds
  172. }
  173. // Good. Add amount to total
  174. total += in.Amount
  175. }
  176. return total, nil
  177. }
  178. func (s *State) ValidateOutputs(outs []*blk.TxOutput) (total uint64, err error) {
  179. for _, out := range outs {
  180. // Check TxOutput basic
  181. if err := out.ValidateBasic(); err != nil {
  182. return 0, err
  183. }
  184. // Good. Add amount to total
  185. total += out.Amount
  186. }
  187. return total, nil
  188. }
  189. func (s *State) AdjustByInputs(accounts map[string]*account.Account, ins []*blk.TxInput) {
  190. for _, in := range ins {
  191. acc := accounts[string(in.Address)]
  192. if acc == nil {
  193. panic("AdjustByInputs() expects account in accounts")
  194. }
  195. if acc.Balance < in.Amount {
  196. panic("AdjustByInputs() expects sufficient funds")
  197. }
  198. acc.Balance -= in.Amount
  199. acc.Sequence += 1
  200. }
  201. }
  202. func (s *State) AdjustByOutputs(accounts map[string]*account.Account, outs []*blk.TxOutput) {
  203. for _, out := range outs {
  204. acc := accounts[string(out.Address)]
  205. if acc == nil {
  206. panic("AdjustByOutputs() expects account in accounts")
  207. }
  208. acc.Balance += out.Amount
  209. }
  210. }
  211. // If the tx is invalid, an error will be returned.
  212. // Unlike AppendBlock(), state will not be altered.
  213. func (s *State) ExecTx(tx_ blk.Tx) error {
  214. // TODO: do something with fees
  215. fees := uint64(0)
  216. // Exec tx
  217. switch tx_.(type) {
  218. case *blk.SendTx:
  219. tx := tx_.(*blk.SendTx)
  220. accounts, err := s.GetOrMakeAccounts(tx.Inputs, tx.Outputs)
  221. if err != nil {
  222. return err
  223. }
  224. signBytes := account.SignBytes(tx)
  225. inTotal, err := s.ValidateInputs(accounts, signBytes, tx.Inputs)
  226. if err != nil {
  227. return err
  228. }
  229. outTotal, err := s.ValidateOutputs(tx.Outputs)
  230. if err != nil {
  231. return err
  232. }
  233. if outTotal > inTotal {
  234. return blk.ErrTxInsufficientFunds
  235. }
  236. fee := inTotal - outTotal
  237. fees += fee
  238. // Good! Adjust accounts
  239. s.AdjustByInputs(accounts, tx.Inputs)
  240. s.AdjustByOutputs(accounts, tx.Outputs)
  241. s.UpdateAccounts(accounts)
  242. return nil
  243. case *blk.BondTx:
  244. tx := tx_.(*blk.BondTx)
  245. valInfo := s.GetValidatorInfo(tx.PubKey.Address())
  246. if valInfo != nil {
  247. // TODO: In the future, check that the validator wasn't destroyed,
  248. // add funds, merge UnbondTo outputs, and unbond validator.
  249. return errors.New("Adding coins to existing validators not yet supported")
  250. }
  251. accounts, err := s.GetOrMakeAccounts(tx.Inputs, nil)
  252. if err != nil {
  253. return err
  254. }
  255. signBytes := account.SignBytes(tx)
  256. inTotal, err := s.ValidateInputs(accounts, signBytes, tx.Inputs)
  257. if err != nil {
  258. return err
  259. }
  260. if err := tx.PubKey.ValidateBasic(); err != nil {
  261. return err
  262. }
  263. outTotal, err := s.ValidateOutputs(tx.UnbondTo)
  264. if err != nil {
  265. return err
  266. }
  267. if outTotal > inTotal {
  268. return blk.ErrTxInsufficientFunds
  269. }
  270. fee := inTotal - outTotal
  271. fees += fee
  272. // Good! Adjust accounts
  273. s.AdjustByInputs(accounts, tx.Inputs)
  274. s.UpdateAccounts(accounts)
  275. // Add ValidatorInfo
  276. s.SetValidatorInfo(&ValidatorInfo{
  277. Address: tx.PubKey.Address(),
  278. PubKey: tx.PubKey,
  279. UnbondTo: tx.UnbondTo,
  280. FirstBondHeight: s.LastBlockHeight + 1,
  281. FirstBondAmount: outTotal,
  282. })
  283. // Add Validator
  284. added := s.BondedValidators.Add(&Validator{
  285. Address: tx.PubKey.Address(),
  286. PubKey: tx.PubKey,
  287. BondHeight: s.LastBlockHeight + 1,
  288. VotingPower: outTotal,
  289. Accum: 0,
  290. })
  291. if !added {
  292. panic("Failed to add validator")
  293. }
  294. return nil
  295. case *blk.UnbondTx:
  296. tx := tx_.(*blk.UnbondTx)
  297. // The validator must be active
  298. _, val := s.BondedValidators.GetByAddress(tx.Address)
  299. if val == nil {
  300. return blk.ErrTxInvalidAddress
  301. }
  302. // Verify the signature
  303. signBytes := account.SignBytes(tx)
  304. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  305. return blk.ErrTxInvalidSignature
  306. }
  307. // tx.Height must be greater than val.LastCommitHeight
  308. if tx.Height <= val.LastCommitHeight {
  309. return errors.New("Invalid unbond height")
  310. }
  311. // Good!
  312. s.unbondValidator(val)
  313. return nil
  314. case *blk.RebondTx:
  315. tx := tx_.(*blk.RebondTx)
  316. // The validator must be inactive
  317. _, val := s.UnbondingValidators.GetByAddress(tx.Address)
  318. if val == nil {
  319. return blk.ErrTxInvalidAddress
  320. }
  321. // Verify the signature
  322. signBytes := account.SignBytes(tx)
  323. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  324. return blk.ErrTxInvalidSignature
  325. }
  326. // tx.Height must be equal to the next height
  327. if tx.Height != s.LastBlockHeight+1 {
  328. return errors.New(Fmt("Invalid rebond height. Expected %v, got %v", s.LastBlockHeight+1, tx.Height))
  329. }
  330. // Good!
  331. s.rebondValidator(val)
  332. return nil
  333. case *blk.DupeoutTx:
  334. tx := tx_.(*blk.DupeoutTx)
  335. // Verify the signatures
  336. _, accused := s.BondedValidators.GetByAddress(tx.Address)
  337. if accused == nil {
  338. _, accused = s.UnbondingValidators.GetByAddress(tx.Address)
  339. if accused == nil {
  340. return blk.ErrTxInvalidAddress
  341. }
  342. }
  343. voteASignBytes := account.SignBytes(&tx.VoteA)
  344. voteBSignBytes := account.SignBytes(&tx.VoteB)
  345. if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) ||
  346. !accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) {
  347. return blk.ErrTxInvalidSignature
  348. }
  349. // Verify equivocation
  350. // TODO: in the future, just require one vote from a previous height that
  351. // doesn't exist on this chain.
  352. if tx.VoteA.Height != tx.VoteB.Height {
  353. return errors.New("DupeoutTx heights don't match")
  354. }
  355. if tx.VoteA.Type == blk.VoteTypeCommit && tx.VoteA.Round < tx.VoteB.Round {
  356. // Check special case.
  357. // Validators should not sign another vote after committing.
  358. } else {
  359. if tx.VoteA.Round != tx.VoteB.Round {
  360. return errors.New("DupeoutTx rounds don't match")
  361. }
  362. if tx.VoteA.Type != tx.VoteB.Type {
  363. return errors.New("DupeoutTx types don't match")
  364. }
  365. if bytes.Equal(tx.VoteA.BlockHash, tx.VoteB.BlockHash) {
  366. return errors.New("DupeoutTx blockhashes shouldn't match")
  367. }
  368. }
  369. // Good! (Bad validator!)
  370. s.destroyValidator(accused)
  371. return nil
  372. default:
  373. panic("Unknown Tx type")
  374. }
  375. }
  376. func (s *State) unbondValidator(val *Validator) {
  377. // Move validator to UnbondingValidators
  378. val, removed := s.BondedValidators.Remove(val.Address)
  379. if !removed {
  380. panic("Couldn't remove validator for unbonding")
  381. }
  382. val.UnbondHeight = s.LastBlockHeight + 1
  383. added := s.UnbondingValidators.Add(val)
  384. if !added {
  385. panic("Couldn't add validator for unbonding")
  386. }
  387. }
  388. func (s *State) rebondValidator(val *Validator) {
  389. // Move validator to BondingValidators
  390. val, removed := s.UnbondingValidators.Remove(val.Address)
  391. if !removed {
  392. panic("Couldn't remove validator for rebonding")
  393. }
  394. val.BondHeight = s.LastBlockHeight + 1
  395. added := s.BondedValidators.Add(val)
  396. if !added {
  397. panic("Couldn't add validator for rebonding")
  398. }
  399. }
  400. func (s *State) releaseValidator(val *Validator) {
  401. // Update validatorInfo
  402. valInfo := s.GetValidatorInfo(val.Address)
  403. if valInfo == nil {
  404. panic("Couldn't find validatorInfo for release")
  405. }
  406. valInfo.ReleasedHeight = s.LastBlockHeight + 1
  407. s.SetValidatorInfo(valInfo)
  408. // Send coins back to UnbondTo outputs
  409. accounts, err := s.GetOrMakeAccounts(nil, valInfo.UnbondTo)
  410. if err != nil {
  411. panic("Couldn't get or make unbondTo accounts")
  412. }
  413. s.AdjustByOutputs(accounts, valInfo.UnbondTo)
  414. s.UpdateAccounts(accounts)
  415. // Remove validator from UnbondingValidators
  416. _, removed := s.UnbondingValidators.Remove(val.Address)
  417. if !removed {
  418. panic("Couldn't remove validator for release")
  419. }
  420. }
  421. func (s *State) destroyValidator(val *Validator) {
  422. // Update validatorInfo
  423. valInfo := s.GetValidatorInfo(val.Address)
  424. if valInfo == nil {
  425. panic("Couldn't find validatorInfo for release")
  426. }
  427. valInfo.DestroyedHeight = s.LastBlockHeight + 1
  428. valInfo.DestroyedAmount = val.VotingPower
  429. s.SetValidatorInfo(valInfo)
  430. // Remove validator
  431. _, removed := s.BondedValidators.Remove(val.Address)
  432. if !removed {
  433. _, removed := s.UnbondingValidators.Remove(val.Address)
  434. if !removed {
  435. panic("Couldn't remove validator for destruction")
  436. }
  437. }
  438. }
  439. // "checkStateHash": If false, instead of checking the resulting
  440. // state.Hash() against blk.StateHash, it *sets* the blk.StateHash.
  441. // (used for constructing a new proposal)
  442. // NOTE: If an error occurs during block execution, state will be left
  443. // at an invalid state. Copy the state before calling AppendBlock!
  444. func (s *State) AppendBlock(block *blk.Block, blockPartsHeader blk.PartSetHeader, checkStateHash bool) error {
  445. // Basic block validation.
  446. err := block.ValidateBasic(s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime)
  447. if err != nil {
  448. return err
  449. }
  450. // Validate block Validation.
  451. if block.Height == 1 {
  452. if len(block.Validation.Commits) != 0 {
  453. return errors.New("Block at height 1 (first block) should have no Validation commits")
  454. }
  455. } else {
  456. if uint(len(block.Validation.Commits)) != s.LastBondedValidators.Size() {
  457. return errors.New(Fmt("Invalid block validation size. Expected %v, got %v",
  458. s.LastBondedValidators.Size(), len(block.Validation.Commits)))
  459. }
  460. var sumVotingPower uint64
  461. s.LastBondedValidators.Iterate(func(index uint, val *Validator) bool {
  462. commit := block.Validation.Commits[index]
  463. if commit.IsZero() {
  464. return false
  465. } else {
  466. vote := &blk.Vote{
  467. Height: block.Height - 1,
  468. Round: commit.Round,
  469. Type: blk.VoteTypeCommit,
  470. BlockHash: block.LastBlockHash,
  471. BlockParts: block.LastBlockParts,
  472. }
  473. if val.PubKey.VerifyBytes(account.SignBytes(vote), commit.Signature) {
  474. sumVotingPower += val.VotingPower
  475. return false
  476. } else {
  477. log.Warn(Fmt("Invalid validation signature.\nval: %v\nvote: %v", val, vote))
  478. err = errors.New("Invalid validation signature")
  479. return true
  480. }
  481. }
  482. })
  483. if err != nil {
  484. return err
  485. }
  486. if sumVotingPower <= s.LastBondedValidators.TotalVotingPower()*2/3 {
  487. return errors.New("Insufficient validation voting power")
  488. }
  489. }
  490. // Update Validator.LastCommitHeight as necessary.
  491. for i, commit := range block.Validation.Commits {
  492. if commit.IsZero() {
  493. continue
  494. }
  495. _, val := s.LastBondedValidators.GetByIndex(uint(i))
  496. if val == nil {
  497. panic(Fmt("Failed to fetch validator at index %v", i))
  498. }
  499. if _, val_ := s.BondedValidators.GetByAddress(val.Address); val_ != nil {
  500. val_.LastCommitHeight = block.Height - 1
  501. updated := s.BondedValidators.Update(val_)
  502. if !updated {
  503. panic("Failed to update bonded validator LastCommitHeight")
  504. }
  505. } else if _, val_ := s.UnbondingValidators.GetByAddress(val.Address); val_ != nil {
  506. val_.LastCommitHeight = block.Height - 1
  507. updated := s.UnbondingValidators.Update(val_)
  508. if !updated {
  509. panic("Failed to update unbonding validator LastCommitHeight")
  510. }
  511. } else {
  512. panic("Could not find validator")
  513. }
  514. }
  515. // Remember LastBondedValidators
  516. s.LastBondedValidators = s.BondedValidators.Copy()
  517. // Commit each tx
  518. for _, tx := range block.Data.Txs {
  519. err := s.ExecTx(tx)
  520. if err != nil {
  521. return InvalidTxError{tx, err}
  522. }
  523. }
  524. // If any unbonding periods are over,
  525. // reward account with bonded coins.
  526. toRelease := []*Validator{}
  527. s.UnbondingValidators.Iterate(func(index uint, val *Validator) bool {
  528. if val.UnbondHeight+unbondingPeriodBlocks < block.Height {
  529. toRelease = append(toRelease, val)
  530. }
  531. return false
  532. })
  533. for _, val := range toRelease {
  534. s.releaseValidator(val)
  535. }
  536. // If any validators haven't signed in a while,
  537. // unbond them, they have timed out.
  538. toTimeout := []*Validator{}
  539. s.BondedValidators.Iterate(func(index uint, val *Validator) bool {
  540. lastActivityHeight := MaxUint(val.BondHeight, val.LastCommitHeight)
  541. if lastActivityHeight+validatorTimeoutBlocks < block.Height {
  542. log.Info("Validator timeout", "validator", val, "height", block.Height)
  543. toTimeout = append(toTimeout, val)
  544. }
  545. return false
  546. })
  547. for _, val := range toTimeout {
  548. s.unbondValidator(val)
  549. }
  550. // Increment validator AccumPowers
  551. s.BondedValidators.IncrementAccum(1)
  552. // Check or set blk.StateHash
  553. stateHash := s.Hash()
  554. if checkStateHash {
  555. // State hash should match
  556. if !bytes.Equal(stateHash, block.StateHash) {
  557. return Errorf("Invalid state hash. Got %X, block says %X",
  558. stateHash, block.StateHash)
  559. }
  560. } else {
  561. // Set the state hash.
  562. if block.StateHash != nil {
  563. panic("Cannot overwrite block.StateHash")
  564. }
  565. block.StateHash = stateHash
  566. }
  567. s.LastBlockHeight = block.Height
  568. s.LastBlockHash = block.Hash()
  569. s.LastBlockParts = blockPartsHeader
  570. s.LastBlockTime = block.Time
  571. return nil
  572. }
  573. // The returned Account is a copy, so mutating it
  574. // has no side effects.
  575. func (s *State) GetAccount(address []byte) *account.Account {
  576. _, acc := s.accounts.Get(address)
  577. if acc == nil {
  578. return nil
  579. }
  580. return acc.(*account.Account).Copy()
  581. }
  582. // The returned Account is a copy, so mutating it
  583. // has no side effects.
  584. func (s *State) GetAccounts() merkle.Tree {
  585. return s.accounts.Copy()
  586. }
  587. // The account is copied before setting, so mutating it
  588. // afterwards has no side effects.
  589. func (s *State) UpdateAccount(account *account.Account) {
  590. s.accounts.Set(account.Address, account.Copy())
  591. }
  592. // The accounts are copied before setting, so mutating it
  593. // afterwards has no side effects.
  594. func (s *State) UpdateAccounts(accounts map[string]*account.Account) {
  595. for _, acc := range accounts {
  596. s.accounts.Set(acc.Address, acc.Copy())
  597. }
  598. }
  599. // The returned ValidatorInfo is a copy, so mutating it
  600. // has no side effects.
  601. func (s *State) GetValidatorInfo(address []byte) *ValidatorInfo {
  602. _, valInfo := s.validatorInfos.Get(address)
  603. if valInfo == nil {
  604. return nil
  605. }
  606. return valInfo.(*ValidatorInfo).Copy()
  607. }
  608. // Returns false if new, true if updated.
  609. // The valInfo is copied before setting, so mutating it
  610. // afterwards has no side effects.
  611. func (s *State) SetValidatorInfo(valInfo *ValidatorInfo) (updated bool) {
  612. return s.validatorInfos.Set(valInfo.Address, valInfo.Copy())
  613. }
  614. // Returns a hash that represents the state data,
  615. // excluding LastBlock*
  616. func (s *State) Hash() []byte {
  617. hashables := []merkle.Hashable{
  618. s.BondedValidators,
  619. s.UnbondingValidators,
  620. s.accounts,
  621. s.validatorInfos,
  622. }
  623. return merkle.HashFromHashables(hashables)
  624. }