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.

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