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.

983 lines
30 KiB

9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 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
9 years ago
10 years ago
10 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), types.EventMsgTx{tx, nil, ""})
  311. }
  312. for _, o := range tx.Outputs {
  313. evc.FireEvent(types.EventStringAccOutput(o.Address), types.EventMsgTx{tx, nil, ""})
  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. createContract := len(tx.Address) == 0
  326. if createContract {
  327. if !hasCreateContractPermission(blockCache, inAcc) {
  328. return fmt.Errorf("Account %X does not have CreateContract 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 !createContract {
  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. // check if its a native contract
  357. if vm.RegisteredNativeContract(LeftPadWord256(tx.Address)) {
  358. return fmt.Errorf("NativeContracts can not be called using CallTx. Use a contract or the appropriate tx type (eg. PermissionsTx, NameTx)")
  359. }
  360. // Output account may be nil if we are still in mempool and contract was created in same block as this tx
  361. // but that's fine, because the account will be created properly when the create tx runs in the block
  362. // and then this won't return nil. otherwise, we take their fee
  363. outAcc = blockCache.GetAccount(tx.Address)
  364. }
  365. log.Info(Fmt("Out account: %v", outAcc))
  366. // Good!
  367. value := tx.Input.Amount - tx.Fee
  368. inAcc.Sequence += 1
  369. inAcc.Balance -= tx.Fee
  370. blockCache.UpdateAccount(inAcc)
  371. // The logic in runCall MUST NOT return.
  372. if runCall {
  373. // VM call variables
  374. var (
  375. gas int64 = tx.GasLimit
  376. err error = nil
  377. caller *vm.Account = toVMAccount(inAcc)
  378. callee *vm.Account = nil // initialized below
  379. code []byte = nil
  380. ret []byte = nil
  381. txCache = NewTxCache(blockCache)
  382. params = vm.Params{
  383. BlockHeight: int64(_s.LastBlockHeight),
  384. BlockHash: LeftPadWord256(_s.LastBlockHash),
  385. BlockTime: _s.LastBlockTime.Unix(),
  386. GasLimit: _s.GetGasLimit(),
  387. }
  388. )
  389. if !createContract && (outAcc == nil || len(outAcc.Code) == 0) {
  390. // if you call an account that doesn't exist
  391. // or an account with no code then we take fees (sorry pal)
  392. // NOTE: it's fine to create a contract and call it within one
  393. // block (nonce will prevent re-ordering of those txs)
  394. // but to create with one contract and call with another
  395. // you have to wait a block to avoid a re-ordering attack
  396. // that will take your fees
  397. if outAcc == nil {
  398. log.Info(Fmt("%X tries to call %X but it does not exist.",
  399. inAcc.Address, tx.Address))
  400. } else {
  401. log.Info(Fmt("%X tries to call %X but code is blank.",
  402. inAcc.Address, tx.Address))
  403. }
  404. err = types.ErrTxInvalidAddress
  405. goto CALL_COMPLETE
  406. }
  407. // get or create callee
  408. if createContract {
  409. // We already checked for permission
  410. callee = txCache.CreateAccount(caller)
  411. log.Info(Fmt("Created new contract %X", callee.Address))
  412. code = tx.Data
  413. } else {
  414. callee = toVMAccount(outAcc)
  415. log.Info(Fmt("Calling contract %X with code %X", callee.Address, callee.Code))
  416. code = callee.Code
  417. }
  418. log.Info(Fmt("Code for this contract: %X", code))
  419. // Run VM call and sync txCache to blockCache.
  420. { // Capture scope for goto.
  421. // Write caller/callee to txCache.
  422. txCache.UpdateAccount(caller)
  423. txCache.UpdateAccount(callee)
  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. if err != nil {
  429. // Failure. Charge the gas fee. The 'value' was otherwise not transferred.
  430. log.Info(Fmt("Error on execution: %v", err))
  431. goto CALL_COMPLETE
  432. }
  433. log.Info("Successful execution")
  434. if createContract {
  435. callee.Code = ret
  436. }
  437. txCache.Sync()
  438. }
  439. CALL_COMPLETE: // err may or may not be nil.
  440. // Create a receipt from the ret and whether errored.
  441. log.Notice("VM call complete", "caller", caller, "callee", callee, "return", ret, "err", err)
  442. // Fire Events for sender and receiver
  443. // a separate event will be fired from vm for each additional call
  444. if evc != nil {
  445. exception := ""
  446. if err != nil {
  447. exception = err.Error()
  448. }
  449. evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventMsgTx{tx, ret, exception})
  450. evc.FireEvent(types.EventStringAccOutput(tx.Address), types.EventMsgTx{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 createContract {
  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.Info(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.Info(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.Info(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.Info(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.Info(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.Info("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.Info(Fmt("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name))
  512. return types.ErrTxPermissionDenied
  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.Info("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.Info("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.Info("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.Info("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. if evc != nil {
  569. evc.FireEvent(types.EventStringAccInput(tx.Input.Address), tx)
  570. evc.FireEvent(types.EventStringNameReg(tx.Name), tx)
  571. }
  572. return nil
  573. case *types.BondTx:
  574. valInfo := blockCache.State().GetValidatorInfo(tx.PubKey.Address())
  575. if valInfo != nil {
  576. // TODO: In the future, check that the validator wasn't destroyed,
  577. // add funds, merge UnbondTo outputs, and unbond validator.
  578. return errors.New("Adding coins to existing validators not yet supported")
  579. }
  580. accounts, err := getInputs(blockCache, tx.Inputs)
  581. if err != nil {
  582. return err
  583. }
  584. // add outputs to accounts map
  585. // if any outputs don't exist, all inputs must have CreateAccount perm
  586. // though outputs aren't created until unbonding/release time
  587. canCreate := hasCreateAccountPermission(blockCache, accounts)
  588. for _, out := range tx.UnbondTo {
  589. acc := blockCache.GetAccount(out.Address)
  590. if acc == nil && !canCreate {
  591. return fmt.Errorf("At least one input does not have permission to create accounts")
  592. }
  593. }
  594. bondAcc := blockCache.GetAccount(tx.PubKey.Address())
  595. if !hasBondPermission(blockCache, bondAcc) {
  596. return fmt.Errorf("The bonder does not have permission to bond")
  597. }
  598. if !hasBondOrSendPermission(blockCache, accounts) {
  599. return fmt.Errorf("At least one input lacks permission to bond")
  600. }
  601. signBytes := acm.SignBytes(_s.ChainID, tx)
  602. inTotal, err := validateInputs(accounts, signBytes, tx.Inputs)
  603. if 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. PanicCrisis("Failed to add validator")
  641. }
  642. if evc != nil {
  643. // TODO: fire for all inputs
  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 := acm.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 := acm.SignBytes(_s.ChainID, tx)
  676. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  677. return types.ErrTxInvalidSignature
  678. }
  679. // tx.Height must be in a suitable range
  680. minRebondHeight := _s.LastBlockHeight - (validatorTimeoutBlocks / 2)
  681. maxRebondHeight := _s.LastBlockHeight + 2
  682. if !((minRebondHeight <= tx.Height) && (tx.Height <= maxRebondHeight)) {
  683. return errors.New(Fmt("Rebond height not in range. Expected %v <= %v <= %v",
  684. minRebondHeight, tx.Height, maxRebondHeight))
  685. }
  686. // Good!
  687. _s.rebondValidator(val)
  688. if evc != nil {
  689. evc.FireEvent(types.EventStringRebond(), tx)
  690. }
  691. return nil
  692. case *types.DupeoutTx:
  693. // Verify the signatures
  694. _, accused := _s.BondedValidators.GetByAddress(tx.Address)
  695. if accused == nil {
  696. _, accused = _s.UnbondingValidators.GetByAddress(tx.Address)
  697. if accused == nil {
  698. return types.ErrTxInvalidAddress
  699. }
  700. }
  701. voteASignBytes := acm.SignBytes(_s.ChainID, &tx.VoteA)
  702. voteBSignBytes := acm.SignBytes(_s.ChainID, &tx.VoteB)
  703. if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) ||
  704. !accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) {
  705. return types.ErrTxInvalidSignature
  706. }
  707. // Verify equivocation
  708. // TODO: in the future, just require one vote from a previous height that
  709. // doesn't exist on this chain.
  710. if tx.VoteA.Height != tx.VoteB.Height {
  711. return errors.New("DupeoutTx heights don't match")
  712. }
  713. if tx.VoteA.Round != tx.VoteB.Round {
  714. return errors.New("DupeoutTx rounds don't match")
  715. }
  716. if tx.VoteA.Type != tx.VoteB.Type {
  717. return errors.New("DupeoutTx types don't match")
  718. }
  719. if bytes.Equal(tx.VoteA.BlockHash, tx.VoteB.BlockHash) {
  720. return errors.New("DupeoutTx blockhashes shouldn't match")
  721. }
  722. // Good! (Bad validator!)
  723. _s.destroyValidator(accused)
  724. if evc != nil {
  725. evc.FireEvent(types.EventStringDupeout(), tx)
  726. }
  727. return nil
  728. case *types.PermissionsTx:
  729. var inAcc *acm.Account
  730. // Validate input
  731. inAcc = blockCache.GetAccount(tx.Input.Address)
  732. if inAcc == nil {
  733. log.Debug(Fmt("Can't find in account %X", tx.Input.Address))
  734. return types.ErrTxInvalidAddress
  735. }
  736. permFlag := tx.PermArgs.PermFlag()
  737. // check permission
  738. if !HasPermission(blockCache, inAcc, permFlag) {
  739. return fmt.Errorf("Account %X does not have moderator permission %s (%b)", tx.Input.Address, ptypes.PermFlagToString(permFlag), permFlag)
  740. }
  741. // pubKey should be present in either "inAcc" or "tx.Input"
  742. if err := checkInputPubKey(inAcc, tx.Input); err != nil {
  743. log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address))
  744. return err
  745. }
  746. signBytes := acm.SignBytes(_s.ChainID, tx)
  747. err := validateInput(inAcc, signBytes, tx.Input)
  748. if err != nil {
  749. log.Debug(Fmt("validateInput failed on %X: %v", tx.Input.Address, err))
  750. return err
  751. }
  752. value := tx.Input.Amount
  753. log.Debug("New PermissionsTx", "function", ptypes.PermFlagToString(permFlag), "args", tx.PermArgs)
  754. var permAcc *acm.Account
  755. switch args := tx.PermArgs.(type) {
  756. case *ptypes.HasBaseArgs:
  757. // this one doesn't make sense from txs
  758. return fmt.Errorf("HasBase is for contracts, not humans. Just look at the blockchain")
  759. case *ptypes.SetBaseArgs:
  760. if permAcc = blockCache.GetAccount(args.Address); permAcc == nil {
  761. return fmt.Errorf("Trying to update permissions for unknown account %X", args.Address)
  762. }
  763. err = permAcc.Permissions.Base.Set(args.Permission, args.Value)
  764. case *ptypes.UnsetBaseArgs:
  765. if permAcc = blockCache.GetAccount(args.Address); permAcc == nil {
  766. return fmt.Errorf("Trying to update permissions for unknown account %X", args.Address)
  767. }
  768. err = permAcc.Permissions.Base.Unset(args.Permission)
  769. case *ptypes.SetGlobalArgs:
  770. if permAcc = blockCache.GetAccount(ptypes.GlobalPermissionsAddress); permAcc == nil {
  771. PanicSanity("can't find global permissions account")
  772. }
  773. err = permAcc.Permissions.Base.Set(args.Permission, args.Value)
  774. case *ptypes.HasRoleArgs:
  775. return fmt.Errorf("HasRole is for contracts, not humans. Just look at the blockchain")
  776. case *ptypes.AddRoleArgs:
  777. if permAcc = blockCache.GetAccount(args.Address); permAcc == nil {
  778. return fmt.Errorf("Trying to update roles for unknown account %X", args.Address)
  779. }
  780. if !permAcc.Permissions.AddRole(args.Role) {
  781. return fmt.Errorf("Role (%s) already exists for account %X", args.Role, args.Address)
  782. }
  783. case *ptypes.RmRoleArgs:
  784. if permAcc = blockCache.GetAccount(args.Address); permAcc == nil {
  785. return fmt.Errorf("Trying to update roles for unknown account %X", args.Address)
  786. }
  787. if !permAcc.Permissions.RmRole(args.Role) {
  788. return fmt.Errorf("Role (%s) does not exist for account %X", args.Role, args.Address)
  789. }
  790. default:
  791. PanicSanity(Fmt("invalid permission function: %s", ptypes.PermFlagToString(permFlag)))
  792. }
  793. // TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
  794. if err != nil {
  795. return err
  796. }
  797. // Good!
  798. inAcc.Sequence += 1
  799. inAcc.Balance -= value
  800. blockCache.UpdateAccount(inAcc)
  801. if permAcc != nil {
  802. blockCache.UpdateAccount(permAcc)
  803. }
  804. if evc != nil {
  805. evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventMsgTx{tx, nil, ""})
  806. evc.FireEvent(types.EventStringPermissions(ptypes.PermFlagToString(permFlag)), tx)
  807. }
  808. return nil
  809. default:
  810. // binary decoding should not let this happen
  811. PanicSanity("Unknown Tx type")
  812. return nil
  813. }
  814. }
  815. //---------------------------------------------------------------
  816. // Get permission on an account or fall back to global value
  817. func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag) bool {
  818. if perm > ptypes.AllPermFlags {
  819. PanicSanity("Checking an unknown permission in state should never happen")
  820. }
  821. if acc == nil {
  822. // TODO
  823. // this needs to fall back to global or do some other specific things
  824. // eg. a bondAcc may be nil and so can only bond if global bonding is true
  825. }
  826. permString := ptypes.PermFlagToString(perm)
  827. v, err := acc.Permissions.Base.Get(perm)
  828. if _, ok := err.(ptypes.ErrValueNotSet); ok {
  829. if state == nil {
  830. PanicSanity("All known global permissions should be set!")
  831. }
  832. log.Info("Permission for account is not set. Querying GlobalPermissionsAddress", "perm", permString)
  833. return HasPermission(nil, state.GetAccount(ptypes.GlobalPermissionsAddress), perm)
  834. } else if v {
  835. log.Info("Account has permission", "address", Fmt("%X", acc.Address), "perm", permString)
  836. } else {
  837. log.Info("Account does not have permission", "address", Fmt("%X", acc.Address), "perm", permString)
  838. }
  839. return v
  840. }
  841. // TODO: for debug log the failed accounts
  842. func hasSendPermission(state AccountGetter, accs map[string]*acm.Account) bool {
  843. for _, acc := range accs {
  844. if !HasPermission(state, acc, ptypes.Send) {
  845. return false
  846. }
  847. }
  848. return true
  849. }
  850. func hasNamePermission(state AccountGetter, acc *acm.Account) bool {
  851. return HasPermission(state, acc, ptypes.Name)
  852. }
  853. func hasCallPermission(state AccountGetter, acc *acm.Account) bool {
  854. return HasPermission(state, acc, ptypes.Call)
  855. }
  856. func hasCreateContractPermission(state AccountGetter, acc *acm.Account) bool {
  857. return HasPermission(state, acc, ptypes.CreateContract)
  858. }
  859. func hasCreateAccountPermission(state AccountGetter, accs map[string]*acm.Account) bool {
  860. for _, acc := range accs {
  861. if !HasPermission(state, acc, ptypes.CreateAccount) {
  862. return false
  863. }
  864. }
  865. return true
  866. }
  867. func hasBondPermission(state AccountGetter, acc *acm.Account) bool {
  868. return HasPermission(state, acc, ptypes.Bond)
  869. }
  870. func hasBondOrSendPermission(state AccountGetter, accs map[string]*acm.Account) bool {
  871. for _, acc := range accs {
  872. if !HasPermission(state, acc, ptypes.Bond) {
  873. if !HasPermission(state, acc, ptypes.Send) {
  874. return false
  875. }
  876. }
  877. }
  878. return true
  879. }