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.

593 lines
17 KiB

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