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.

880 lines
27 KiB

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