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.

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