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.

642 lines
19 KiB

10 years ago
  1. package state
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "github.com/tendermint/tendermint/account"
  7. . "github.com/tendermint/tendermint/common"
  8. "github.com/tendermint/tendermint/events"
  9. "github.com/tendermint/tendermint/types"
  10. "github.com/tendermint/tendermint/vm"
  11. )
  12. // NOTE: If an error occurs during block execution, state will be left
  13. // at an invalid state. Copy the state before calling ExecBlock!
  14. func ExecBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeader) error {
  15. err := execBlock(s, block, blockPartsHeader)
  16. if err != nil {
  17. return err
  18. }
  19. // State.Hash should match block.StateHash
  20. stateHash := s.Hash()
  21. if !bytes.Equal(stateHash, block.StateHash) {
  22. return fmt.Errorf("Invalid state hash. Expected %X, got %X",
  23. stateHash, block.StateHash)
  24. }
  25. return nil
  26. }
  27. // executes transactions of a block, does not check block.StateHash
  28. // NOTE: If an error occurs during block execution, state will be left
  29. // at an invalid state. Copy the state before calling execBlock!
  30. func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeader) error {
  31. // Basic block validation.
  32. err := block.ValidateBasic(s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime)
  33. if err != nil {
  34. return err
  35. }
  36. // Validate block Validation.
  37. if block.Height == 1 {
  38. if len(block.Validation.Commits) != 0 {
  39. return errors.New("Block at height 1 (first block) should have no Validation commits")
  40. }
  41. } else {
  42. if uint(len(block.Validation.Commits)) != s.LastBondedValidators.Size() {
  43. return errors.New(Fmt("Invalid block validation size. Expected %v, got %v",
  44. s.LastBondedValidators.Size(), len(block.Validation.Commits)))
  45. }
  46. var sumVotingPower uint64
  47. s.LastBondedValidators.Iterate(func(index uint, val *Validator) bool {
  48. commit := block.Validation.Commits[index]
  49. if commit.IsZero() {
  50. return false
  51. } else {
  52. vote := &types.Vote{
  53. Height: block.Height - 1,
  54. Round: commit.Round,
  55. Type: types.VoteTypeCommit,
  56. BlockHash: block.LastBlockHash,
  57. BlockParts: block.LastBlockParts,
  58. }
  59. if val.PubKey.VerifyBytes(account.SignBytes(vote), commit.Signature) {
  60. sumVotingPower += val.VotingPower
  61. return false
  62. } else {
  63. log.Warn(Fmt("Invalid validation signature.\nval: %v\nvote: %v", val, vote))
  64. err = errors.New("Invalid validation signature")
  65. return true
  66. }
  67. }
  68. })
  69. if err != nil {
  70. return err
  71. }
  72. if sumVotingPower <= s.LastBondedValidators.TotalVotingPower()*2/3 {
  73. return errors.New("Insufficient validation voting power")
  74. }
  75. }
  76. // Update Validator.LastCommitHeight as necessary.
  77. for i, commit := range block.Validation.Commits {
  78. if commit.IsZero() {
  79. continue
  80. }
  81. _, val := s.LastBondedValidators.GetByIndex(uint(i))
  82. if val == nil {
  83. panic(Fmt("Failed to fetch validator at index %v", i))
  84. }
  85. if _, val_ := s.BondedValidators.GetByAddress(val.Address); val_ != nil {
  86. val_.LastCommitHeight = block.Height - 1
  87. updated := s.BondedValidators.Update(val_)
  88. if !updated {
  89. panic("Failed to update bonded validator LastCommitHeight")
  90. }
  91. } else if _, val_ := s.UnbondingValidators.GetByAddress(val.Address); val_ != nil {
  92. val_.LastCommitHeight = block.Height - 1
  93. updated := s.UnbondingValidators.Update(val_)
  94. if !updated {
  95. panic("Failed to update unbonding validator LastCommitHeight")
  96. }
  97. } else {
  98. panic("Could not find validator")
  99. }
  100. }
  101. // Remember LastBondedValidators
  102. s.LastBondedValidators = s.BondedValidators.Copy()
  103. // Create BlockCache to cache changes to state.
  104. blockCache := NewBlockCache(s)
  105. // Commit each tx
  106. for _, tx := range block.Data.Txs {
  107. err := ExecTx(blockCache, tx, true, s.evc)
  108. if err != nil {
  109. return InvalidTxError{tx, err}
  110. }
  111. }
  112. // Now sync the BlockCache to the backend.
  113. blockCache.Sync()
  114. // If any unbonding periods are over,
  115. // reward account with bonded coins.
  116. toRelease := []*Validator{}
  117. s.UnbondingValidators.Iterate(func(index uint, val *Validator) bool {
  118. if val.UnbondHeight+unbondingPeriodBlocks < block.Height {
  119. toRelease = append(toRelease, val)
  120. }
  121. return false
  122. })
  123. for _, val := range toRelease {
  124. s.releaseValidator(val)
  125. }
  126. // If any validators haven't signed in a while,
  127. // unbond them, they have timed out.
  128. toTimeout := []*Validator{}
  129. s.BondedValidators.Iterate(func(index uint, val *Validator) bool {
  130. lastActivityHeight := MaxUint(val.BondHeight, val.LastCommitHeight)
  131. if lastActivityHeight+validatorTimeoutBlocks < block.Height {
  132. log.Info("Validator timeout", "validator", val, "height", block.Height)
  133. toTimeout = append(toTimeout, val)
  134. }
  135. return false
  136. })
  137. for _, val := range toTimeout {
  138. s.unbondValidator(val)
  139. }
  140. // Increment validator AccumPowers
  141. s.BondedValidators.IncrementAccum(1)
  142. s.LastBlockHeight = block.Height
  143. s.LastBlockHash = block.Hash()
  144. s.LastBlockParts = blockPartsHeader
  145. s.LastBlockTime = block.Time
  146. return nil
  147. }
  148. // The accounts from the TxInputs must either already have
  149. // account.PubKey.(type) != nil, (it must be known),
  150. // or it must be specified in the TxInput. If redeclared,
  151. // the TxInput is modified and input.PubKey set to nil.
  152. func getOrMakeAccounts(state AccountGetter, ins []*types.TxInput, outs []*types.TxOutput) (map[string]*account.Account, error) {
  153. accounts := map[string]*account.Account{}
  154. for _, in := range ins {
  155. // Account shouldn't be duplicated
  156. if _, ok := accounts[string(in.Address)]; ok {
  157. return nil, types.ErrTxDuplicateAddress
  158. }
  159. acc := state.GetAccount(in.Address)
  160. if acc == nil {
  161. return nil, types.ErrTxInvalidAddress
  162. }
  163. // PubKey should be present in either "account" or "in"
  164. if err := checkInputPubKey(acc, in); err != nil {
  165. return nil, err
  166. }
  167. accounts[string(in.Address)] = acc
  168. }
  169. for _, out := range outs {
  170. // Account shouldn't be duplicated
  171. if _, ok := accounts[string(out.Address)]; ok {
  172. return nil, types.ErrTxDuplicateAddress
  173. }
  174. acc := state.GetAccount(out.Address)
  175. // output account may be nil (new)
  176. if acc == nil {
  177. acc = &account.Account{
  178. Address: out.Address,
  179. PubKey: nil,
  180. Sequence: 0,
  181. Balance: 0,
  182. }
  183. }
  184. accounts[string(out.Address)] = acc
  185. }
  186. return accounts, nil
  187. }
  188. func checkInputPubKey(acc *account.Account, in *types.TxInput) error {
  189. if acc.PubKey == nil {
  190. if in.PubKey == nil {
  191. return types.ErrTxUnknownPubKey
  192. }
  193. if !bytes.Equal(in.PubKey.Address(), acc.Address) {
  194. return types.ErrTxInvalidPubKey
  195. }
  196. acc.PubKey = in.PubKey
  197. } else {
  198. in.PubKey = nil
  199. }
  200. return nil
  201. }
  202. func validateInputs(accounts map[string]*account.Account, signBytes []byte, ins []*types.TxInput) (total uint64, err error) {
  203. for _, in := range ins {
  204. acc := accounts[string(in.Address)]
  205. if acc == nil {
  206. panic("validateInputs() expects account in accounts")
  207. }
  208. err = validateInput(acc, signBytes, in)
  209. if err != nil {
  210. return
  211. }
  212. // Good. Add amount to total
  213. total += in.Amount
  214. }
  215. return total, nil
  216. }
  217. func validateInput(acc *account.Account, signBytes []byte, in *types.TxInput) (err error) {
  218. // Check TxInput basic
  219. if err := in.ValidateBasic(); err != nil {
  220. return err
  221. }
  222. // Check signatures
  223. if !acc.PubKey.VerifyBytes(signBytes, in.Signature) {
  224. return types.ErrTxInvalidSignature
  225. }
  226. // Check sequences
  227. if acc.Sequence+1 != in.Sequence {
  228. return types.ErrTxInvalidSequence{
  229. Got: uint64(in.Sequence),
  230. Expected: uint64(acc.Sequence + 1),
  231. }
  232. }
  233. // Check amount
  234. if acc.Balance < in.Amount {
  235. return types.ErrTxInsufficientFunds
  236. }
  237. return nil
  238. }
  239. func validateOutputs(outs []*types.TxOutput) (total uint64, err error) {
  240. for _, out := range outs {
  241. // Check TxOutput basic
  242. if err := out.ValidateBasic(); err != nil {
  243. return 0, err
  244. }
  245. // Good. Add amount to total
  246. total += out.Amount
  247. }
  248. return total, nil
  249. }
  250. func adjustByInputs(accounts map[string]*account.Account, ins []*types.TxInput) {
  251. for _, in := range ins {
  252. acc := accounts[string(in.Address)]
  253. if acc == nil {
  254. panic("adjustByInputs() expects account in accounts")
  255. }
  256. if acc.Balance < in.Amount {
  257. panic("adjustByInputs() expects sufficient funds")
  258. }
  259. acc.Balance -= in.Amount
  260. acc.Sequence += 1
  261. }
  262. }
  263. func adjustByOutputs(accounts map[string]*account.Account, outs []*types.TxOutput) {
  264. for _, out := range outs {
  265. acc := accounts[string(out.Address)]
  266. if acc == nil {
  267. panic("adjustByOutputs() expects account in accounts")
  268. }
  269. acc.Balance += out.Amount
  270. }
  271. }
  272. // If the tx is invalid, an error will be returned.
  273. // Unlike ExecBlock(), state will not be altered.
  274. func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Fireable) error {
  275. // TODO: do something with fees
  276. fees := uint64(0)
  277. _s := blockCache.State() // hack to access validators and event switch.
  278. // Exec tx
  279. switch tx := tx_.(type) {
  280. case *types.SendTx:
  281. accounts, err := getOrMakeAccounts(blockCache, tx.Inputs, tx.Outputs)
  282. if err != nil {
  283. return err
  284. }
  285. signBytes := account.SignBytes(tx)
  286. inTotal, err := validateInputs(accounts, signBytes, tx.Inputs)
  287. if err != nil {
  288. return err
  289. }
  290. outTotal, err := validateOutputs(tx.Outputs)
  291. if err != nil {
  292. return err
  293. }
  294. if outTotal > inTotal {
  295. return types.ErrTxInsufficientFunds
  296. }
  297. fee := inTotal - outTotal
  298. fees += fee
  299. // Good! Adjust accounts
  300. adjustByInputs(accounts, tx.Inputs)
  301. adjustByOutputs(accounts, tx.Outputs)
  302. for _, acc := range accounts {
  303. blockCache.UpdateAccount(acc)
  304. }
  305. // if the evc is nil, nothing will happen
  306. if evc != nil {
  307. for _, i := range tx.Inputs {
  308. evc.FireEvent(types.EventStringAccInput(i.Address), tx)
  309. }
  310. for _, o := range tx.Outputs {
  311. evc.FireEvent(types.EventStringAccOutput(o.Address), tx)
  312. }
  313. }
  314. return nil
  315. case *types.CallTx:
  316. var inAcc, outAcc *account.Account
  317. // Validate input
  318. inAcc = blockCache.GetAccount(tx.Input.Address)
  319. if inAcc == nil {
  320. log.Debug(Fmt("Can't find in account %X", tx.Input.Address))
  321. return types.ErrTxInvalidAddress
  322. }
  323. // pubKey should be present in either "inAcc" or "tx.Input"
  324. if err := checkInputPubKey(inAcc, tx.Input); err != nil {
  325. log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address))
  326. return err
  327. }
  328. signBytes := account.SignBytes(tx)
  329. err := validateInput(inAcc, signBytes, tx.Input)
  330. if err != nil {
  331. log.Debug(Fmt("validateInput failed on %X:", tx.Input.Address))
  332. return err
  333. }
  334. if tx.Input.Amount < tx.Fee {
  335. log.Debug(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address))
  336. return types.ErrTxInsufficientFunds
  337. }
  338. createAccount := len(tx.Address) == 0
  339. if !createAccount {
  340. // Validate output
  341. if len(tx.Address) != 20 {
  342. log.Debug(Fmt("Destination address is not 20 bytes %X", tx.Address))
  343. return types.ErrTxInvalidAddress
  344. }
  345. // this may be nil if we are still in mempool and contract was created in same block as this tx
  346. // but that's fine, because the account will be created properly when the create tx runs in the block
  347. // and then this won't return nil. otherwise, we take their fee
  348. outAcc = blockCache.GetAccount(tx.Address)
  349. }
  350. log.Debug(Fmt("Out account: %v", outAcc))
  351. // Good!
  352. value := tx.Input.Amount - tx.Fee
  353. inAcc.Sequence += 1
  354. if runCall {
  355. var (
  356. gas uint64 = tx.GasLimit
  357. err error = nil
  358. caller *vm.Account = toVMAccount(inAcc)
  359. callee *vm.Account = nil
  360. code []byte = nil
  361. txCache = NewTxCache(blockCache)
  362. params = vm.Params{
  363. BlockHeight: uint64(_s.LastBlockHeight),
  364. BlockHash: LeftPadWord256(_s.LastBlockHash),
  365. BlockTime: _s.LastBlockTime.Unix(),
  366. GasLimit: 10000000,
  367. }
  368. )
  369. // Maybe create a new callee account if
  370. // this transaction is creating a new contract.
  371. if !createAccount {
  372. if outAcc == nil || len(outAcc.Code) == 0 {
  373. // if you call an account that doesn't exist
  374. // or an account with no code then we take fees (sorry pal)
  375. // NOTE: it's fine to create a contract and call it within one
  376. // block (nonce will prevent re-ordering of those txs)
  377. // but to create with one account and call with another
  378. // you have to wait a block to avoid a re-ordering attack
  379. // that will take your fees
  380. inAcc.Balance -= tx.Fee
  381. blockCache.UpdateAccount(inAcc)
  382. if outAcc == nil {
  383. log.Debug(Fmt("Cannot find destination address %X. Deducting fee from caller", tx.Address))
  384. } else {
  385. log.Debug(Fmt("Attempting to call an account (%X) with no code. Deducting fee from caller", tx.Address))
  386. }
  387. return types.ErrTxInvalidAddress
  388. }
  389. callee = toVMAccount(outAcc)
  390. code = callee.Code
  391. log.Debug(Fmt("Calling contract %X with code %X", callee.Address, callee.Code))
  392. } else {
  393. callee = txCache.CreateAccount(caller)
  394. log.Debug(Fmt("Created new account %X", callee.Address))
  395. code = tx.Data
  396. }
  397. log.Debug(Fmt("Code for this contract: %X", code))
  398. txCache.UpdateAccount(caller) // because we adjusted by input above, and bumped nonce maybe.
  399. txCache.UpdateAccount(callee) // because we adjusted by input above.
  400. vmach := vm.NewVM(txCache, params, caller.Address, account.HashSignBytes(tx))
  401. vmach.SetFireable(evc)
  402. // NOTE: Call() transfers the value from caller to callee iff call succeeds.
  403. ret, err := vmach.Call(caller, callee, code, tx.Data, value, &gas)
  404. exception := ""
  405. if err != nil {
  406. exception = err.Error()
  407. // Failure. Charge the gas fee. The 'value' was otherwise not transferred.
  408. log.Debug(Fmt("Error on execution: %v", err))
  409. inAcc.Balance -= tx.Fee
  410. blockCache.UpdateAccount(inAcc)
  411. // Throw away 'txCache' which holds incomplete updates (don't sync it).
  412. } else {
  413. log.Debug("Successful execution")
  414. // Success
  415. if createAccount {
  416. callee.Code = ret
  417. }
  418. txCache.Sync()
  419. }
  420. // Create a receipt from the ret and whether errored.
  421. log.Info("VM call complete", "caller", caller, "callee", callee, "return", ret, "err", err)
  422. // Fire Events for sender and receiver
  423. // a separate event will be fired from vm for each additional call
  424. if evc != nil {
  425. evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventMsgCallTx{tx, ret, exception})
  426. evc.FireEvent(types.EventStringAccOutput(tx.Address), types.EventMsgCallTx{tx, ret, exception})
  427. }
  428. } else {
  429. // The mempool does not call txs until
  430. // the proposer determines the order of txs.
  431. // So mempool will skip the actual .Call(),
  432. // and only deduct from the caller's balance.
  433. inAcc.Balance -= value
  434. if createAccount {
  435. inAcc.Sequence += 1
  436. }
  437. blockCache.UpdateAccount(inAcc)
  438. }
  439. return nil
  440. case *types.BondTx:
  441. valInfo := blockCache.State().GetValidatorInfo(tx.PubKey.Address())
  442. if valInfo != nil {
  443. // TODO: In the future, check that the validator wasn't destroyed,
  444. // add funds, merge UnbondTo outputs, and unbond validator.
  445. return errors.New("Adding coins to existing validators not yet supported")
  446. }
  447. accounts, err := getOrMakeAccounts(blockCache, tx.Inputs, nil)
  448. if err != nil {
  449. return err
  450. }
  451. signBytes := account.SignBytes(tx)
  452. inTotal, err := validateInputs(accounts, signBytes, tx.Inputs)
  453. if err != nil {
  454. return err
  455. }
  456. if err := tx.PubKey.ValidateBasic(); err != nil {
  457. return err
  458. }
  459. if !tx.PubKey.VerifyBytes(signBytes, tx.Signature) {
  460. return types.ErrTxInvalidSignature
  461. }
  462. outTotal, err := validateOutputs(tx.UnbondTo)
  463. if err != nil {
  464. return err
  465. }
  466. if outTotal > inTotal {
  467. return types.ErrTxInsufficientFunds
  468. }
  469. fee := inTotal - outTotal
  470. fees += fee
  471. // Good! Adjust accounts
  472. adjustByInputs(accounts, tx.Inputs)
  473. for _, acc := range accounts {
  474. blockCache.UpdateAccount(acc)
  475. }
  476. // Add ValidatorInfo
  477. _s.SetValidatorInfo(&ValidatorInfo{
  478. Address: tx.PubKey.Address(),
  479. PubKey: tx.PubKey,
  480. UnbondTo: tx.UnbondTo,
  481. FirstBondHeight: _s.LastBlockHeight + 1,
  482. FirstBondAmount: outTotal,
  483. })
  484. // Add Validator
  485. added := _s.BondedValidators.Add(&Validator{
  486. Address: tx.PubKey.Address(),
  487. PubKey: tx.PubKey,
  488. BondHeight: _s.LastBlockHeight + 1,
  489. VotingPower: outTotal,
  490. Accum: 0,
  491. })
  492. if !added {
  493. panic("Failed to add validator")
  494. }
  495. if evc != nil {
  496. evc.FireEvent(types.EventStringBond(), tx)
  497. }
  498. return nil
  499. case *types.UnbondTx:
  500. // The validator must be active
  501. _, val := _s.BondedValidators.GetByAddress(tx.Address)
  502. if val == nil {
  503. return types.ErrTxInvalidAddress
  504. }
  505. // Verify the signature
  506. signBytes := account.SignBytes(tx)
  507. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  508. return types.ErrTxInvalidSignature
  509. }
  510. // tx.Height must be greater than val.LastCommitHeight
  511. if tx.Height <= val.LastCommitHeight {
  512. return errors.New("Invalid unbond height")
  513. }
  514. // Good!
  515. _s.unbondValidator(val)
  516. if evc != nil {
  517. evc.FireEvent(types.EventStringUnbond(), tx)
  518. }
  519. return nil
  520. case *types.RebondTx:
  521. // The validator must be inactive
  522. _, val := _s.UnbondingValidators.GetByAddress(tx.Address)
  523. if val == nil {
  524. return types.ErrTxInvalidAddress
  525. }
  526. // Verify the signature
  527. signBytes := account.SignBytes(tx)
  528. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  529. return types.ErrTxInvalidSignature
  530. }
  531. // tx.Height must be equal to the next height
  532. if tx.Height != _s.LastBlockHeight+1 {
  533. return errors.New(Fmt("Invalid rebond height. Expected %v, got %v", _s.LastBlockHeight+1, tx.Height))
  534. }
  535. // Good!
  536. _s.rebondValidator(val)
  537. if evc != nil {
  538. evc.FireEvent(types.EventStringRebond(), tx)
  539. }
  540. return nil
  541. case *types.DupeoutTx:
  542. // Verify the signatures
  543. _, accused := _s.BondedValidators.GetByAddress(tx.Address)
  544. if accused == nil {
  545. _, accused = _s.UnbondingValidators.GetByAddress(tx.Address)
  546. if accused == nil {
  547. return types.ErrTxInvalidAddress
  548. }
  549. }
  550. voteASignBytes := account.SignBytes(&tx.VoteA)
  551. voteBSignBytes := account.SignBytes(&tx.VoteB)
  552. if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) ||
  553. !accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) {
  554. return types.ErrTxInvalidSignature
  555. }
  556. // Verify equivocation
  557. // TODO: in the future, just require one vote from a previous height that
  558. // doesn't exist on this chain.
  559. if tx.VoteA.Height != tx.VoteB.Height {
  560. return errors.New("DupeoutTx heights don't match")
  561. }
  562. if tx.VoteA.Type == types.VoteTypeCommit && tx.VoteA.Round < tx.VoteB.Round {
  563. // Check special case (not an error, validator must be slashed!)
  564. // Validators should not sign another vote after committing.
  565. } else if tx.VoteB.Type == types.VoteTypeCommit && tx.VoteB.Round < tx.VoteA.Round {
  566. // We need to check both orderings of the votes
  567. } else {
  568. if tx.VoteA.Round != tx.VoteB.Round {
  569. return errors.New("DupeoutTx rounds don't match")
  570. }
  571. if tx.VoteA.Type != tx.VoteB.Type {
  572. return errors.New("DupeoutTx types don't match")
  573. }
  574. if bytes.Equal(tx.VoteA.BlockHash, tx.VoteB.BlockHash) {
  575. return errors.New("DupeoutTx blockhashes shouldn't match")
  576. }
  577. }
  578. // Good! (Bad validator!)
  579. _s.destroyValidator(accused)
  580. if evc != nil {
  581. evc.FireEvent(types.EventStringDupeout(), tx)
  582. }
  583. return nil
  584. default:
  585. panic("Unknown Tx type")
  586. }
  587. }