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.

874 lines
26 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
  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/events"
  8. ptypes "github.com/tendermint/tendermint/permission/types" // for GlobalPermissionAddress ...
  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 errors.New(Fmt("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.ChainID, s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime)
  33. if err != nil {
  34. return err
  35. }
  36. // Validate block LastValidation.
  37. if block.Height == 1 {
  38. if len(block.LastValidation.Precommits) != 0 {
  39. return errors.New("Block at height 1 (first block) should have no LastValidation precommits")
  40. }
  41. } else {
  42. if len(block.LastValidation.Precommits) != s.LastBondedValidators.Size() {
  43. return errors.New(Fmt("Invalid block validation size. Expected %v, got %v",
  44. s.LastBondedValidators.Size(), len(block.LastValidation.Precommits)))
  45. }
  46. err := s.LastBondedValidators.VerifyValidation(
  47. s.ChainID, s.LastBlockHash, s.LastBlockParts, block.Height-1, block.LastValidation)
  48. if err != nil {
  49. return err
  50. }
  51. }
  52. // Update Validator.LastCommitHeight as necessary.
  53. // If we panic in here, something has gone horribly wrong
  54. for i, precommit := range block.LastValidation.Precommits {
  55. if precommit == nil {
  56. continue
  57. }
  58. _, val := s.LastBondedValidators.GetByIndex(i)
  59. if val == nil {
  60. panic(Fmt("Failed to fetch validator at index %v", i))
  61. }
  62. if _, val_ := s.BondedValidators.GetByAddress(val.Address); val_ != nil {
  63. val_.LastCommitHeight = block.Height - 1
  64. updated := s.BondedValidators.Update(val_)
  65. if !updated {
  66. panic("Failed to update bonded validator LastCommitHeight")
  67. }
  68. } else if _, val_ := s.UnbondingValidators.GetByAddress(val.Address); val_ != nil {
  69. val_.LastCommitHeight = block.Height - 1
  70. updated := s.UnbondingValidators.Update(val_)
  71. if !updated {
  72. panic("Failed to update unbonding validator LastCommitHeight")
  73. }
  74. } else {
  75. panic("Could not find validator")
  76. }
  77. }
  78. // Remember LastBondedValidators
  79. s.LastBondedValidators = s.BondedValidators.Copy()
  80. // Create BlockCache to cache changes to state.
  81. blockCache := NewBlockCache(s)
  82. // Execute each tx
  83. for _, tx := range block.Data.Txs {
  84. err := ExecTx(blockCache, tx, true, s.evc)
  85. if err != nil {
  86. return InvalidTxError{tx, err}
  87. }
  88. }
  89. // Now sync the BlockCache to the backend.
  90. blockCache.Sync()
  91. // If any unbonding periods are over,
  92. // reward account with bonded coins.
  93. toRelease := []*Validator{}
  94. s.UnbondingValidators.Iterate(func(index int, val *Validator) bool {
  95. if val.UnbondHeight+unbondingPeriodBlocks < block.Height {
  96. toRelease = append(toRelease, val)
  97. }
  98. return false
  99. })
  100. for _, val := range toRelease {
  101. s.releaseValidator(val)
  102. }
  103. // If any validators haven't signed in a while,
  104. // unbond them, they have timed out.
  105. toTimeout := []*Validator{}
  106. s.BondedValidators.Iterate(func(index int, val *Validator) bool {
  107. lastActivityHeight := MaxInt(val.BondHeight, val.LastCommitHeight)
  108. if lastActivityHeight+validatorTimeoutBlocks < block.Height {
  109. log.Info("Validator timeout", "validator", val, "height", block.Height)
  110. toTimeout = append(toTimeout, val)
  111. }
  112. return false
  113. })
  114. for _, val := range toTimeout {
  115. s.unbondValidator(val)
  116. }
  117. // Increment validator AccumPowers
  118. s.BondedValidators.IncrementAccum(1)
  119. s.LastBlockHeight = block.Height
  120. s.LastBlockHash = block.Hash()
  121. s.LastBlockParts = blockPartsHeader
  122. s.LastBlockTime = block.Time
  123. return nil
  124. }
  125. // The accounts from the TxInputs must either already have
  126. // account.PubKey.(type) != nil, (it must be known),
  127. // or it must be specified in the TxInput. If redeclared,
  128. // the TxInput is modified and input.PubKey set to nil.
  129. func getInputs(state AccountGetter, ins []*types.TxInput) (map[string]*account.Account, error) {
  130. accounts := map[string]*account.Account{}
  131. for _, in := range ins {
  132. // Account shouldn't be duplicated
  133. if _, ok := accounts[string(in.Address)]; ok {
  134. return nil, types.ErrTxDuplicateAddress
  135. }
  136. acc := state.GetAccount(in.Address)
  137. if acc == nil {
  138. return nil, types.ErrTxInvalidAddress
  139. }
  140. // PubKey should be present in either "account" or "in"
  141. if err := checkInputPubKey(acc, in); err != nil {
  142. return nil, err
  143. }
  144. accounts[string(in.Address)] = acc
  145. }
  146. return accounts, nil
  147. }
  148. func getOrMakeOutputs(state AccountGetter, accounts map[string]*account.Account, outs []*types.TxOutput) (map[string]*account.Account, error) {
  149. if accounts == nil {
  150. accounts = make(map[string]*account.Account)
  151. }
  152. var checkedCreatePerms bool
  153. for _, out := range outs {
  154. // Account shouldn't be duplicated
  155. if _, ok := accounts[string(out.Address)]; ok {
  156. return nil, types.ErrTxDuplicateAddress
  157. }
  158. acc := state.GetAccount(out.Address)
  159. // output account may be nil (new)
  160. if acc == nil {
  161. if !checkedCreatePerms {
  162. if !hasCreateAccountPermission(state, accounts) {
  163. return nil, fmt.Errorf("At least one input does not have permission to create accounts")
  164. }
  165. checkedCreatePerms = true
  166. }
  167. acc = &account.Account{
  168. Address: out.Address,
  169. PubKey: nil,
  170. Sequence: 0,
  171. Balance: 0,
  172. Permissions: ptypes.NewAccountPermissions(),
  173. }
  174. }
  175. accounts[string(out.Address)] = acc
  176. }
  177. return accounts, nil
  178. }
  179. func checkInputPubKey(acc *account.Account, in *types.TxInput) error {
  180. if acc.PubKey == nil {
  181. if in.PubKey == nil {
  182. return types.ErrTxUnknownPubKey
  183. }
  184. if !bytes.Equal(in.PubKey.Address(), acc.Address) {
  185. return types.ErrTxInvalidPubKey
  186. }
  187. acc.PubKey = in.PubKey
  188. } else {
  189. in.PubKey = nil
  190. }
  191. return nil
  192. }
  193. func validateInputs(accounts map[string]*account.Account, signBytes []byte, ins []*types.TxInput) (total int64, err error) {
  194. for _, in := range ins {
  195. acc := accounts[string(in.Address)]
  196. // SANITY CHECK
  197. if acc == nil {
  198. panic("validateInputs() expects account in accounts")
  199. }
  200. // SANITY CHECK END
  201. err = validateInput(acc, signBytes, in)
  202. if err != nil {
  203. return
  204. }
  205. // Good. Add amount to total
  206. total += in.Amount
  207. }
  208. return total, nil
  209. }
  210. func validateInput(acc *account.Account, signBytes []byte, in *types.TxInput) (err error) {
  211. // Check TxInput basic
  212. if err := in.ValidateBasic(); err != nil {
  213. return err
  214. }
  215. // Check signatures
  216. if !acc.PubKey.VerifyBytes(signBytes, in.Signature) {
  217. return types.ErrTxInvalidSignature
  218. }
  219. // Check sequences
  220. if acc.Sequence+1 != in.Sequence {
  221. return types.ErrTxInvalidSequence{
  222. Got: in.Sequence,
  223. Expected: acc.Sequence + 1,
  224. }
  225. }
  226. // Check amount
  227. if acc.Balance < in.Amount {
  228. return types.ErrTxInsufficientFunds
  229. }
  230. return nil
  231. }
  232. func validateOutputs(outs []*types.TxOutput) (total int64, err error) {
  233. for _, out := range outs {
  234. // Check TxOutput basic
  235. if err := out.ValidateBasic(); err != nil {
  236. return 0, err
  237. }
  238. // Good. Add amount to total
  239. total += out.Amount
  240. }
  241. return total, nil
  242. }
  243. func adjustByInputs(accounts map[string]*account.Account, ins []*types.TxInput) {
  244. for _, in := range ins {
  245. acc := accounts[string(in.Address)]
  246. // SANITY CHECK
  247. if acc == nil {
  248. panic("adjustByInputs() expects account in accounts")
  249. }
  250. if acc.Balance < in.Amount {
  251. panic("adjustByInputs() expects sufficient funds")
  252. }
  253. // SANITY CHECK END
  254. acc.Balance -= in.Amount
  255. acc.Sequence += 1
  256. }
  257. }
  258. func adjustByOutputs(accounts map[string]*account.Account, outs []*types.TxOutput) {
  259. for _, out := range outs {
  260. acc := accounts[string(out.Address)]
  261. // SANITY CHECK
  262. if acc == nil {
  263. panic("adjustByOutputs() expects account in accounts")
  264. }
  265. // SANITY CHECK END
  266. acc.Balance += out.Amount
  267. }
  268. }
  269. // If the tx is invalid, an error will be returned.
  270. // Unlike ExecBlock(), state will not be altered.
  271. func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Fireable) error {
  272. defer func() {
  273. if r := recover(); r != nil {
  274. err := errors.New(Fmt("Recovered from panic in ExecTx", "err", r, "tx", tx_))
  275. log.Error(err.Error())
  276. // TODO return error
  277. }
  278. }()
  279. // TODO: do something with fees
  280. fees := int64(0)
  281. _s := blockCache.State() // hack to access validators and block height
  282. // Exec tx
  283. switch tx := tx_.(type) {
  284. case *types.SendTx:
  285. accounts, err := getInputs(blockCache, tx.Inputs)
  286. if err != nil {
  287. return err
  288. }
  289. // ensure all inputs have send permissions
  290. if !hasSendPermission(blockCache, accounts) {
  291. return fmt.Errorf("At least one input lacks permission for SendTx")
  292. }
  293. // add outputs to accounts map
  294. // if any outputs don't exist, all inputs must have CreateAccount perm
  295. accounts, err = getOrMakeOutputs(blockCache, accounts, tx.Outputs)
  296. if err != nil {
  297. return err
  298. }
  299. signBytes := account.SignBytes(_s.ChainID, tx)
  300. inTotal, err := validateInputs(accounts, signBytes, tx.Inputs)
  301. if err != nil {
  302. return err
  303. }
  304. outTotal, err := validateOutputs(tx.Outputs)
  305. if err != nil {
  306. return err
  307. }
  308. if outTotal > inTotal {
  309. return types.ErrTxInsufficientFunds
  310. }
  311. fee := inTotal - outTotal
  312. fees += fee
  313. // Good! Adjust accounts
  314. adjustByInputs(accounts, tx.Inputs)
  315. adjustByOutputs(accounts, tx.Outputs)
  316. for _, acc := range accounts {
  317. blockCache.UpdateAccount(acc)
  318. }
  319. // if the evc is nil, nothing will happen
  320. if evc != nil {
  321. for _, i := range tx.Inputs {
  322. evc.FireEvent(types.EventStringAccInput(i.Address), tx)
  323. }
  324. for _, o := range tx.Outputs {
  325. evc.FireEvent(types.EventStringAccOutput(o.Address), tx)
  326. }
  327. }
  328. return nil
  329. case *types.CallTx:
  330. var inAcc, outAcc *account.Account
  331. // Validate input
  332. inAcc = blockCache.GetAccount(tx.Input.Address)
  333. if inAcc == nil {
  334. log.Debug(Fmt("Can't find in account %X", tx.Input.Address))
  335. return types.ErrTxInvalidAddress
  336. }
  337. createAccount := len(tx.Address) == 0
  338. if createAccount {
  339. if !hasCreateContractPermission(blockCache, inAcc) {
  340. return fmt.Errorf("Account %X does not have Create permission", tx.Input.Address)
  341. }
  342. } else {
  343. if !hasCallPermission(blockCache, inAcc) {
  344. return fmt.Errorf("Account %X does not have Call permission", tx.Input.Address)
  345. }
  346. }
  347. // pubKey should be present in either "inAcc" or "tx.Input"
  348. if err := checkInputPubKey(inAcc, tx.Input); err != nil {
  349. log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address))
  350. return err
  351. }
  352. signBytes := account.SignBytes(_s.ChainID, tx)
  353. err := validateInput(inAcc, signBytes, tx.Input)
  354. if err != nil {
  355. log.Debug(Fmt("validateInput failed on %X: %v", tx.Input.Address, err))
  356. return err
  357. }
  358. if tx.Input.Amount < tx.Fee {
  359. log.Debug(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address))
  360. return types.ErrTxInsufficientFunds
  361. }
  362. if !createAccount {
  363. // Validate output
  364. if len(tx.Address) != 20 {
  365. log.Debug(Fmt("Destination address is not 20 bytes %X", tx.Address))
  366. return types.ErrTxInvalidAddress
  367. }
  368. // this may be nil if we are still in mempool and contract was created in same block as this tx
  369. // but that's fine, because the account will be created properly when the create tx runs in the block
  370. // and then this won't return nil. otherwise, we take their fee
  371. // it may also be nil if its an snative (not a "real" account)
  372. outAcc = blockCache.GetAccount(tx.Address)
  373. }
  374. log.Debug(Fmt("Out account: %v", outAcc))
  375. // Good!
  376. value := tx.Input.Amount - tx.Fee
  377. inAcc.Sequence += 1
  378. if runCall {
  379. var (
  380. gas int64 = tx.GasLimit
  381. err error = nil
  382. caller *vm.Account = toVMAccount(inAcc)
  383. callee *vm.Account = nil
  384. code []byte = nil
  385. txCache = NewTxCache(blockCache)
  386. params = vm.Params{
  387. BlockHeight: int64(_s.LastBlockHeight),
  388. BlockHash: LeftPadWord256(_s.LastBlockHash),
  389. BlockTime: _s.LastBlockTime.Unix(),
  390. GasLimit: 10000000,
  391. }
  392. )
  393. // get or create callee
  394. if !createAccount {
  395. if outAcc == nil || len(outAcc.Code) == 0 {
  396. // check if its an snative
  397. if _, ok := vm.RegisteredSNativeContracts[LeftPadWord256(tx.Address)]; ok {
  398. // set the outAcc (simply a placeholder until we reach the call)
  399. outAcc = &account.Account{Address: tx.Address}
  400. } else {
  401. // if you call an account that doesn't exist
  402. // or an account with no code then we take fees (sorry pal)
  403. // NOTE: it's fine to create a contract and call it within one
  404. // block (nonce will prevent re-ordering of those txs)
  405. // but to create with one account and call with another
  406. // you have to wait a block to avoid a re-ordering attack
  407. // that will take your fees
  408. inAcc.Balance -= tx.Fee
  409. blockCache.UpdateAccount(inAcc)
  410. if outAcc == nil {
  411. log.Debug(Fmt("Cannot find destination address %X. Deducting fee from caller", tx.Address))
  412. } else {
  413. log.Debug(Fmt("Attempting to call an account (%X) with no code. Deducting fee from caller", tx.Address))
  414. }
  415. return types.ErrTxInvalidAddress
  416. }
  417. }
  418. callee = toVMAccount(outAcc)
  419. code = callee.Code
  420. log.Debug(Fmt("Calling contract %X with code %X", callee.Address, callee.Code))
  421. } else {
  422. callee = txCache.CreateAccount(caller)
  423. txCache.UpdateAccount(callee)
  424. log.Debug(Fmt("Created new account %X", callee.Address))
  425. code = tx.Data
  426. }
  427. log.Debug(Fmt("Code for this contract: %X", code))
  428. txCache.UpdateAccount(caller) // because we bumped nonce
  429. txCache.UpdateAccount(callee) // so the txCache knows about the callee and the transfer takes effect
  430. vmach := vm.NewVM(txCache, params, caller.Address, account.HashSignBytes(_s.ChainID, tx))
  431. vmach.SetFireable(evc)
  432. vmach.EnablePermissions() // permission checks on CALL/CREATE
  433. vmach.EnableSNatives() // allows calls to snatives (with permission checks)
  434. // NOTE: Call() transfers the value from caller to callee iff call succeeds.
  435. ret, err := vmach.Call(caller, callee, code, tx.Data, value, &gas)
  436. exception := ""
  437. if err != nil {
  438. exception = err.Error()
  439. // Failure. Charge the gas fee. The 'value' was otherwise not transferred.
  440. log.Debug(Fmt("Error on execution: %v", err))
  441. inAcc.Balance -= tx.Fee
  442. blockCache.UpdateAccount(inAcc)
  443. // Throw away 'txCache' which holds incomplete updates (don't sync it).
  444. } else {
  445. log.Debug("Successful execution")
  446. // Success
  447. if createAccount {
  448. callee.Code = ret
  449. }
  450. txCache.Sync()
  451. }
  452. // Create a receipt from the ret and whether errored.
  453. log.Info("VM call complete", "caller", caller, "callee", callee, "return", ret, "err", err)
  454. // Fire Events for sender and receiver
  455. // a separate event will be fired from vm for each additional call
  456. if evc != nil {
  457. evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventMsgCallTx{tx, ret, exception})
  458. evc.FireEvent(types.EventStringAccOutput(tx.Address), types.EventMsgCallTx{tx, ret, exception})
  459. }
  460. } else {
  461. // The mempool does not call txs until
  462. // the proposer determines the order of txs.
  463. // So mempool will skip the actual .Call(),
  464. // and only deduct from the caller's balance.
  465. inAcc.Balance -= value
  466. if createAccount {
  467. inAcc.Sequence += 1
  468. }
  469. blockCache.UpdateAccount(inAcc)
  470. }
  471. return nil
  472. case *types.NameTx:
  473. var inAcc *account.Account
  474. // Validate input
  475. inAcc = blockCache.GetAccount(tx.Input.Address)
  476. if inAcc == nil {
  477. log.Debug(Fmt("Can't find in account %X", tx.Input.Address))
  478. return types.ErrTxInvalidAddress
  479. }
  480. // pubKey should be present in either "inAcc" or "tx.Input"
  481. if err := checkInputPubKey(inAcc, tx.Input); err != nil {
  482. log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address))
  483. return err
  484. }
  485. signBytes := account.SignBytes(_s.ChainID, tx)
  486. err := validateInput(inAcc, signBytes, tx.Input)
  487. if err != nil {
  488. log.Debug(Fmt("validateInput failed on %X: %v", tx.Input.Address, err))
  489. return err
  490. }
  491. // fee is in addition to the amount which is used to determine the TTL
  492. if tx.Input.Amount < tx.Fee {
  493. log.Debug(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address))
  494. return types.ErrTxInsufficientFunds
  495. }
  496. // validate the input strings
  497. if err := tx.ValidateStrings(); err != nil {
  498. log.Debug(err.Error())
  499. return types.ErrTxInvalidString
  500. }
  501. value := tx.Input.Amount - tx.Fee
  502. // let's say cost of a name for one block is len(data) + 32
  503. costPerBlock := types.NameCostPerBlock * types.NameCostPerByte * tx.BaseEntryCost()
  504. expiresIn := int(value / costPerBlock)
  505. lastBlockHeight := _s.LastBlockHeight
  506. log.Debug("New NameTx", "value", value, "costPerBlock", costPerBlock, "expiresIn", expiresIn, "lastBlock", lastBlockHeight)
  507. // check if the name exists
  508. entry := blockCache.GetNameRegEntry(tx.Name)
  509. if entry != nil {
  510. var expired bool
  511. // if the entry already exists, and hasn't expired, we must be owner
  512. if entry.Expires > lastBlockHeight {
  513. // ensure we are owner
  514. if bytes.Compare(entry.Owner, tx.Input.Address) != 0 {
  515. log.Debug(Fmt("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name))
  516. return types.ErrIncorrectOwner
  517. }
  518. } else {
  519. expired = true
  520. }
  521. // no value and empty data means delete the entry
  522. if value == 0 && len(tx.Data) == 0 {
  523. // maybe we reward you for telling us we can delete this crap
  524. // (owners if not expired, anyone if expired)
  525. log.Debug("Removing namereg entry", "name", entry.Name)
  526. blockCache.RemoveNameRegEntry(entry.Name)
  527. } else {
  528. // update the entry by bumping the expiry
  529. // and changing the data
  530. if expired {
  531. if expiresIn < types.MinNameRegistrationPeriod {
  532. return errors.New(Fmt("Names must be registered for at least %d blocks", types.MinNameRegistrationPeriod))
  533. }
  534. entry.Expires = lastBlockHeight + expiresIn
  535. entry.Owner = tx.Input.Address
  536. log.Debug("An old namereg entry has expired and been reclaimed", "name", entry.Name, "expiresIn", expiresIn, "owner", entry.Owner)
  537. } else {
  538. // since the size of the data may have changed
  539. // we use the total amount of "credit"
  540. oldCredit := int64(entry.Expires-lastBlockHeight) * types.BaseEntryCost(entry.Name, entry.Data)
  541. credit := oldCredit + value
  542. expiresIn = int(credit / costPerBlock)
  543. if expiresIn < types.MinNameRegistrationPeriod {
  544. return errors.New(Fmt("Names must be registered for at least %d blocks", types.MinNameRegistrationPeriod))
  545. }
  546. entry.Expires = lastBlockHeight + expiresIn
  547. log.Debug("Updated namereg entry", "name", entry.Name, "expiresIn", expiresIn, "oldCredit", oldCredit, "value", value, "credit", credit)
  548. }
  549. entry.Data = tx.Data
  550. blockCache.UpdateNameRegEntry(entry)
  551. }
  552. } else {
  553. if expiresIn < types.MinNameRegistrationPeriod {
  554. return errors.New(Fmt("Names must be registered for at least %d blocks", types.MinNameRegistrationPeriod))
  555. }
  556. // entry does not exist, so create it
  557. entry = &types.NameRegEntry{
  558. Name: tx.Name,
  559. Owner: tx.Input.Address,
  560. Data: tx.Data,
  561. Expires: lastBlockHeight + expiresIn,
  562. }
  563. log.Debug("Creating namereg entry", "name", entry.Name, "expiresIn", expiresIn)
  564. blockCache.UpdateNameRegEntry(entry)
  565. }
  566. // TODO: something with the value sent?
  567. // Good!
  568. inAcc.Sequence += 1
  569. inAcc.Balance -= value
  570. blockCache.UpdateAccount(inAcc)
  571. // TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
  572. return nil
  573. case *types.BondTx:
  574. valInfo := blockCache.State().GetValidatorInfo(tx.PubKey.Address())
  575. if valInfo != nil {
  576. // TODO: In the future, check that the validator wasn't destroyed,
  577. // add funds, merge UnbondTo outputs, and unbond validator.
  578. return errors.New("Adding coins to existing validators not yet supported")
  579. }
  580. accounts, err := getInputs(blockCache, tx.Inputs)
  581. if err != nil {
  582. return err
  583. }
  584. // add outputs to accounts map
  585. // if any outputs don't exist, all inputs must have CreateAccount perm
  586. // though outputs aren't created until unbonding/release time
  587. canCreate := hasCreateAccountPermission(blockCache, accounts)
  588. for _, out := range tx.UnbondTo {
  589. acc := blockCache.GetAccount(out.Address)
  590. if acc == nil && !canCreate {
  591. return fmt.Errorf("At least one input does not have permission to create accounts")
  592. }
  593. }
  594. bondAcc := blockCache.GetAccount(tx.PubKey.Address())
  595. if !hasBondPermission(blockCache, bondAcc) {
  596. return fmt.Errorf("The bonder does not have permission to bond")
  597. }
  598. if !hasBondOrSendPermission(blockCache, accounts) {
  599. return fmt.Errorf("At least one input lacks permission to bond")
  600. }
  601. signBytes := account.SignBytes(_s.ChainID, tx)
  602. inTotal, err := validateInputs(accounts, signBytes, tx.Inputs)
  603. if err != nil {
  604. return err
  605. }
  606. if err := tx.PubKey.ValidateBasic(); err != nil {
  607. return err
  608. }
  609. if !tx.PubKey.VerifyBytes(signBytes, tx.Signature) {
  610. return types.ErrTxInvalidSignature
  611. }
  612. outTotal, err := validateOutputs(tx.UnbondTo)
  613. if err != nil {
  614. return err
  615. }
  616. if outTotal > inTotal {
  617. return types.ErrTxInsufficientFunds
  618. }
  619. fee := inTotal - outTotal
  620. fees += fee
  621. // Good! Adjust accounts
  622. adjustByInputs(accounts, tx.Inputs)
  623. for _, acc := range accounts {
  624. blockCache.UpdateAccount(acc)
  625. }
  626. // Add ValidatorInfo
  627. _s.SetValidatorInfo(&ValidatorInfo{
  628. Address: tx.PubKey.Address(),
  629. PubKey: tx.PubKey,
  630. UnbondTo: tx.UnbondTo,
  631. FirstBondHeight: _s.LastBlockHeight + 1,
  632. FirstBondAmount: outTotal,
  633. })
  634. // Add Validator
  635. added := _s.BondedValidators.Add(&Validator{
  636. Address: tx.PubKey.Address(),
  637. PubKey: tx.PubKey,
  638. BondHeight: _s.LastBlockHeight + 1,
  639. VotingPower: outTotal,
  640. Accum: 0,
  641. })
  642. if !added {
  643. // SOMETHING HAS GONE HORRIBLY WRONG
  644. panic("Failed to add validator")
  645. }
  646. if evc != nil {
  647. evc.FireEvent(types.EventStringBond(), tx)
  648. }
  649. return nil
  650. case *types.UnbondTx:
  651. // The validator must be active
  652. _, val := _s.BondedValidators.GetByAddress(tx.Address)
  653. if val == nil {
  654. return types.ErrTxInvalidAddress
  655. }
  656. // Verify the signature
  657. signBytes := account.SignBytes(_s.ChainID, tx)
  658. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  659. return types.ErrTxInvalidSignature
  660. }
  661. // tx.Height must be greater than val.LastCommitHeight
  662. if tx.Height <= val.LastCommitHeight {
  663. return errors.New("Invalid unbond height")
  664. }
  665. // Good!
  666. _s.unbondValidator(val)
  667. if evc != nil {
  668. evc.FireEvent(types.EventStringUnbond(), tx)
  669. }
  670. return nil
  671. case *types.RebondTx:
  672. // The validator must be inactive
  673. _, val := _s.UnbondingValidators.GetByAddress(tx.Address)
  674. if val == nil {
  675. return types.ErrTxInvalidAddress
  676. }
  677. // Verify the signature
  678. signBytes := account.SignBytes(_s.ChainID, tx)
  679. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  680. return types.ErrTxInvalidSignature
  681. }
  682. // tx.Height must be equal to the next height
  683. if tx.Height != _s.LastBlockHeight+1 {
  684. return errors.New(Fmt("Invalid rebond height. Expected %v, got %v", _s.LastBlockHeight+1, tx.Height))
  685. }
  686. // Good!
  687. _s.rebondValidator(val)
  688. if evc != nil {
  689. evc.FireEvent(types.EventStringRebond(), tx)
  690. }
  691. return nil
  692. case *types.DupeoutTx:
  693. // Verify the signatures
  694. _, accused := _s.BondedValidators.GetByAddress(tx.Address)
  695. if accused == nil {
  696. _, accused = _s.UnbondingValidators.GetByAddress(tx.Address)
  697. if accused == nil {
  698. return types.ErrTxInvalidAddress
  699. }
  700. }
  701. voteASignBytes := account.SignBytes(_s.ChainID, &tx.VoteA)
  702. voteBSignBytes := account.SignBytes(_s.ChainID, &tx.VoteB)
  703. if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) ||
  704. !accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) {
  705. return types.ErrTxInvalidSignature
  706. }
  707. // Verify equivocation
  708. // TODO: in the future, just require one vote from a previous height that
  709. // doesn't exist on this chain.
  710. if tx.VoteA.Height != tx.VoteB.Height {
  711. return errors.New("DupeoutTx heights don't match")
  712. }
  713. if tx.VoteA.Round != tx.VoteB.Round {
  714. return errors.New("DupeoutTx rounds don't match")
  715. }
  716. if tx.VoteA.Type != tx.VoteB.Type {
  717. return errors.New("DupeoutTx types don't match")
  718. }
  719. if bytes.Equal(tx.VoteA.BlockHash, tx.VoteB.BlockHash) {
  720. return errors.New("DupeoutTx blockhashes shouldn't match")
  721. }
  722. // Good! (Bad validator!)
  723. _s.destroyValidator(accused)
  724. if evc != nil {
  725. evc.FireEvent(types.EventStringDupeout(), tx)
  726. }
  727. return nil
  728. default:
  729. // SANITY CHECK (binary decoding should catch bad tx types
  730. // before they get here
  731. panic("Unknown Tx type")
  732. }
  733. }
  734. //---------------------------------------------------------------
  735. // Get permission on an account or fall back to global value
  736. func HasPermission(state AccountGetter, acc *account.Account, perm ptypes.PermFlag) bool {
  737. if acc == nil {
  738. // TODO
  739. // this needs to fall back to global or do some other specific things
  740. // eg. a bondAcc may be nil and so can only bond if global bonding is true
  741. }
  742. v, err := acc.Permissions.Base.Get(perm)
  743. if _, ok := err.(ptypes.ErrValueNotSet); ok {
  744. return HasPermission(state, state.GetAccount(ptypes.GlobalPermissionsAddress), perm)
  745. }
  746. return v
  747. }
  748. // TODO: for debug log the failed accounts
  749. func hasSendPermission(state AccountGetter, accs map[string]*account.Account) bool {
  750. for _, acc := range accs {
  751. if !HasPermission(state, acc, ptypes.Send) {
  752. return false
  753. }
  754. }
  755. return true
  756. }
  757. func hasCallPermission(state AccountGetter, acc *account.Account) bool {
  758. return HasPermission(state, acc, ptypes.Call)
  759. }
  760. func hasCreateContractPermission(state AccountGetter, acc *account.Account) bool {
  761. return HasPermission(state, acc, ptypes.CreateContract)
  762. }
  763. func hasCreateAccountPermission(state AccountGetter, accs map[string]*account.Account) bool {
  764. for _, acc := range accs {
  765. if !HasPermission(state, acc, ptypes.CreateAccount) {
  766. return false
  767. }
  768. }
  769. return true
  770. }
  771. func hasBondPermission(state AccountGetter, acc *account.Account) bool {
  772. return HasPermission(state, acc, ptypes.Bond)
  773. }
  774. func hasBondOrSendPermission(state AccountGetter, accs map[string]*account.Account) bool {
  775. for _, acc := range accs {
  776. if !HasPermission(state, acc, ptypes.Bond) {
  777. if !HasPermission(state, acc, ptypes.Send) {
  778. return false
  779. }
  780. }
  781. }
  782. return true
  783. }