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.

594 lines
17 KiB

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