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.

994 lines
31 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
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 := []*types.Validator{}
  94. s.UnbondingValidators.Iterate(func(index int, val *types.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 := []*types.Validator{}
  106. s.BondedValidators.Iterate(func(index int, val *types.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.EventDataTx{tx, nil, ""})
  311. }
  312. for _, o := range tx.Outputs {
  313. evc.FireEvent(types.EventStringAccOutput(o.Address), types.EventDataTx{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.EventDataTx{tx, ret, exception})
  450. evc.FireEvent(types.EventStringAccOutput(tx.Address), types.EventDataTx{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), types.EventDataTx{tx, nil, ""})
  570. evc.FireEvent(types.EventStringNameReg(tx.Name), types.EventDataTx{tx, nil, ""})
  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(&types.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(&types.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(), types.EventDataTx{tx, nil, ""})
  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(), types.EventDataTx{tx, nil, ""})
  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(), types.EventDataTx{tx, nil, ""})
  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(), types.EventDataTx{tx, nil, ""})
  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.EventDataTx{tx, nil, ""})
  806. evc.FireEvent(types.EventStringPermissions(ptypes.PermFlagToString(permFlag)), types.EventDataTx{tx, nil, ""})
  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. }
  880. //-----------------------------------------------------------------------------
  881. type InvalidTxError struct {
  882. Tx types.Tx
  883. Reason error
  884. }
  885. func (txErr InvalidTxError) Error() string {
  886. return Fmt("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason)
  887. }