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.

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