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.

993 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
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 := []*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. return err
  495. }
  496. value := tx.Input.Amount - tx.Fee
  497. // let's say cost of a name for one block is len(data) + 32
  498. costPerBlock := types.NameCostPerBlock(types.NameBaseCost(tx.Name, tx.Data))
  499. expiresIn := int(value / costPerBlock)
  500. lastBlockHeight := _s.LastBlockHeight
  501. log.Info("New NameTx", "value", value, "costPerBlock", costPerBlock, "expiresIn", expiresIn, "lastBlock", lastBlockHeight)
  502. // check if the name exists
  503. entry := blockCache.GetNameRegEntry(tx.Name)
  504. if entry != nil {
  505. var expired bool
  506. // if the entry already exists, and hasn't expired, we must be owner
  507. if entry.Expires > lastBlockHeight {
  508. // ensure we are owner
  509. if bytes.Compare(entry.Owner, tx.Input.Address) != 0 {
  510. log.Info(Fmt("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name))
  511. return types.ErrTxPermissionDenied
  512. }
  513. } else {
  514. expired = true
  515. }
  516. // no value and empty data means delete the entry
  517. if value == 0 && len(tx.Data) == 0 {
  518. // maybe we reward you for telling us we can delete this crap
  519. // (owners if not expired, anyone if expired)
  520. log.Info("Removing namereg entry", "name", entry.Name)
  521. blockCache.RemoveNameRegEntry(entry.Name)
  522. } else {
  523. // update the entry by bumping the expiry
  524. // and changing the data
  525. if expired {
  526. if expiresIn < types.MinNameRegistrationPeriod {
  527. return errors.New(Fmt("Names must be registered for at least %d blocks", types.MinNameRegistrationPeriod))
  528. }
  529. entry.Expires = lastBlockHeight + expiresIn
  530. entry.Owner = tx.Input.Address
  531. log.Info("An old namereg entry has expired and been reclaimed", "name", entry.Name, "expiresIn", expiresIn, "owner", entry.Owner)
  532. } else {
  533. // since the size of the data may have changed
  534. // we use the total amount of "credit"
  535. oldCredit := int64(entry.Expires-lastBlockHeight) * types.NameBaseCost(entry.Name, entry.Data)
  536. credit := oldCredit + value
  537. expiresIn = int(credit / costPerBlock)
  538. if expiresIn < types.MinNameRegistrationPeriod {
  539. return errors.New(Fmt("Names must be registered for at least %d blocks", types.MinNameRegistrationPeriod))
  540. }
  541. entry.Expires = lastBlockHeight + expiresIn
  542. log.Info("Updated namereg entry", "name", entry.Name, "expiresIn", expiresIn, "oldCredit", oldCredit, "value", value, "credit", credit)
  543. }
  544. entry.Data = tx.Data
  545. blockCache.UpdateNameRegEntry(entry)
  546. }
  547. } else {
  548. if expiresIn < types.MinNameRegistrationPeriod {
  549. return errors.New(Fmt("Names must be registered for at least %d blocks", types.MinNameRegistrationPeriod))
  550. }
  551. // entry does not exist, so create it
  552. entry = &types.NameRegEntry{
  553. Name: tx.Name,
  554. Owner: tx.Input.Address,
  555. Data: tx.Data,
  556. Expires: lastBlockHeight + expiresIn,
  557. }
  558. log.Info("Creating namereg entry", "name", entry.Name, "expiresIn", expiresIn)
  559. blockCache.UpdateNameRegEntry(entry)
  560. }
  561. // TODO: something with the value sent?
  562. // Good!
  563. inAcc.Sequence += 1
  564. inAcc.Balance -= value
  565. blockCache.UpdateAccount(inAcc)
  566. // TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
  567. if evc != nil {
  568. evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventDataTx{tx, nil, ""})
  569. evc.FireEvent(types.EventStringNameReg(tx.Name), types.EventDataTx{tx, nil, ""})
  570. }
  571. return nil
  572. case *types.BondTx:
  573. valInfo := blockCache.State().GetValidatorInfo(tx.PubKey.Address())
  574. if valInfo != nil {
  575. // TODO: In the future, check that the validator wasn't destroyed,
  576. // add funds, merge UnbondTo outputs, and unbond validator.
  577. return errors.New("Adding coins to existing validators not yet supported")
  578. }
  579. accounts, err := getInputs(blockCache, tx.Inputs)
  580. if err != nil {
  581. return err
  582. }
  583. // add outputs to accounts map
  584. // if any outputs don't exist, all inputs must have CreateAccount perm
  585. // though outputs aren't created until unbonding/release time
  586. canCreate := hasCreateAccountPermission(blockCache, accounts)
  587. for _, out := range tx.UnbondTo {
  588. acc := blockCache.GetAccount(out.Address)
  589. if acc == nil && !canCreate {
  590. return fmt.Errorf("At least one input does not have permission to create accounts")
  591. }
  592. }
  593. bondAcc := blockCache.GetAccount(tx.PubKey.Address())
  594. if !hasBondPermission(blockCache, bondAcc) {
  595. return fmt.Errorf("The bonder does not have permission to bond")
  596. }
  597. if !hasBondOrSendPermission(blockCache, accounts) {
  598. return fmt.Errorf("At least one input lacks permission to bond")
  599. }
  600. signBytes := acm.SignBytes(_s.ChainID, tx)
  601. inTotal, err := validateInputs(accounts, signBytes, tx.Inputs)
  602. if err != nil {
  603. return err
  604. }
  605. if !tx.PubKey.VerifyBytes(signBytes, tx.Signature) {
  606. return types.ErrTxInvalidSignature
  607. }
  608. outTotal, err := validateOutputs(tx.UnbondTo)
  609. if err != nil {
  610. return err
  611. }
  612. if outTotal > inTotal {
  613. return types.ErrTxInsufficientFunds
  614. }
  615. fee := inTotal - outTotal
  616. fees += fee
  617. // Good! Adjust accounts
  618. adjustByInputs(accounts, tx.Inputs)
  619. for _, acc := range accounts {
  620. blockCache.UpdateAccount(acc)
  621. }
  622. // Add ValidatorInfo
  623. _s.SetValidatorInfo(&types.ValidatorInfo{
  624. Address: tx.PubKey.Address(),
  625. PubKey: tx.PubKey,
  626. UnbondTo: tx.UnbondTo,
  627. FirstBondHeight: _s.LastBlockHeight + 1,
  628. FirstBondAmount: outTotal,
  629. })
  630. // Add Validator
  631. added := _s.BondedValidators.Add(&types.Validator{
  632. Address: tx.PubKey.Address(),
  633. PubKey: tx.PubKey,
  634. BondHeight: _s.LastBlockHeight + 1,
  635. VotingPower: outTotal,
  636. Accum: 0,
  637. })
  638. if !added {
  639. PanicCrisis("Failed to add validator")
  640. }
  641. if evc != nil {
  642. // TODO: fire for all inputs
  643. evc.FireEvent(types.EventStringBond(), types.EventDataTx{tx, nil, ""})
  644. }
  645. return nil
  646. case *types.UnbondTx:
  647. // The validator must be active
  648. _, val := _s.BondedValidators.GetByAddress(tx.Address)
  649. if val == nil {
  650. return types.ErrTxInvalidAddress
  651. }
  652. // Verify the signature
  653. signBytes := acm.SignBytes(_s.ChainID, tx)
  654. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  655. return types.ErrTxInvalidSignature
  656. }
  657. // tx.Height must be greater than val.LastCommitHeight
  658. if tx.Height <= val.LastCommitHeight {
  659. return errors.New("Invalid unbond height")
  660. }
  661. // Good!
  662. _s.unbondValidator(val)
  663. if evc != nil {
  664. evc.FireEvent(types.EventStringUnbond(), types.EventDataTx{tx, nil, ""})
  665. }
  666. return nil
  667. case *types.RebondTx:
  668. // The validator must be inactive
  669. _, val := _s.UnbondingValidators.GetByAddress(tx.Address)
  670. if val == nil {
  671. return types.ErrTxInvalidAddress
  672. }
  673. // Verify the signature
  674. signBytes := acm.SignBytes(_s.ChainID, tx)
  675. if !val.PubKey.VerifyBytes(signBytes, tx.Signature) {
  676. return types.ErrTxInvalidSignature
  677. }
  678. // tx.Height must be in a suitable range
  679. minRebondHeight := _s.LastBlockHeight - (validatorTimeoutBlocks / 2)
  680. maxRebondHeight := _s.LastBlockHeight + 2
  681. if !((minRebondHeight <= tx.Height) && (tx.Height <= maxRebondHeight)) {
  682. return errors.New(Fmt("Rebond height not in range. Expected %v <= %v <= %v",
  683. minRebondHeight, tx.Height, maxRebondHeight))
  684. }
  685. // Good!
  686. _s.rebondValidator(val)
  687. if evc != nil {
  688. evc.FireEvent(types.EventStringRebond(), types.EventDataTx{tx, nil, ""})
  689. }
  690. return nil
  691. case *types.DupeoutTx:
  692. // Verify the signatures
  693. _, accused := _s.BondedValidators.GetByAddress(tx.Address)
  694. if accused == nil {
  695. _, accused = _s.UnbondingValidators.GetByAddress(tx.Address)
  696. if accused == nil {
  697. return types.ErrTxInvalidAddress
  698. }
  699. }
  700. voteASignBytes := acm.SignBytes(_s.ChainID, &tx.VoteA)
  701. voteBSignBytes := acm.SignBytes(_s.ChainID, &tx.VoteB)
  702. if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) ||
  703. !accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) {
  704. return types.ErrTxInvalidSignature
  705. }
  706. // Verify equivocation
  707. // TODO: in the future, just require one vote from a previous height that
  708. // doesn't exist on this chain.
  709. if tx.VoteA.Height != tx.VoteB.Height {
  710. return errors.New("DupeoutTx heights don't match")
  711. }
  712. if tx.VoteA.Round != tx.VoteB.Round {
  713. return errors.New("DupeoutTx rounds don't match")
  714. }
  715. if tx.VoteA.Type != tx.VoteB.Type {
  716. return errors.New("DupeoutTx types don't match")
  717. }
  718. if bytes.Equal(tx.VoteA.BlockHash, tx.VoteB.BlockHash) {
  719. return errors.New("DupeoutTx blockhashes shouldn't match")
  720. }
  721. // Good! (Bad validator!)
  722. _s.destroyValidator(accused)
  723. if evc != nil {
  724. evc.FireEvent(types.EventStringDupeout(), types.EventDataTx{tx, nil, ""})
  725. }
  726. return nil
  727. case *types.PermissionsTx:
  728. var inAcc *acm.Account
  729. // Validate input
  730. inAcc = blockCache.GetAccount(tx.Input.Address)
  731. if inAcc == nil {
  732. log.Debug(Fmt("Can't find in account %X", tx.Input.Address))
  733. return types.ErrTxInvalidAddress
  734. }
  735. permFlag := tx.PermArgs.PermFlag()
  736. // check permission
  737. if !HasPermission(blockCache, inAcc, permFlag) {
  738. return fmt.Errorf("Account %X does not have moderator permission %s (%b)", tx.Input.Address, ptypes.PermFlagToString(permFlag), permFlag)
  739. }
  740. // pubKey should be present in either "inAcc" or "tx.Input"
  741. if err := checkInputPubKey(inAcc, tx.Input); err != nil {
  742. log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address))
  743. return err
  744. }
  745. signBytes := acm.SignBytes(_s.ChainID, tx)
  746. err := validateInput(inAcc, signBytes, tx.Input)
  747. if err != nil {
  748. log.Debug(Fmt("validateInput failed on %X: %v", tx.Input.Address, err))
  749. return err
  750. }
  751. value := tx.Input.Amount
  752. log.Debug("New PermissionsTx", "function", ptypes.PermFlagToString(permFlag), "args", tx.PermArgs)
  753. var permAcc *acm.Account
  754. switch args := tx.PermArgs.(type) {
  755. case *ptypes.HasBaseArgs:
  756. // this one doesn't make sense from txs
  757. return fmt.Errorf("HasBase is for contracts, not humans. Just look at the blockchain")
  758. case *ptypes.SetBaseArgs:
  759. if permAcc = blockCache.GetAccount(args.Address); permAcc == nil {
  760. return fmt.Errorf("Trying to update permissions for unknown account %X", args.Address)
  761. }
  762. err = permAcc.Permissions.Base.Set(args.Permission, args.Value)
  763. case *ptypes.UnsetBaseArgs:
  764. if permAcc = blockCache.GetAccount(args.Address); permAcc == nil {
  765. return fmt.Errorf("Trying to update permissions for unknown account %X", args.Address)
  766. }
  767. err = permAcc.Permissions.Base.Unset(args.Permission)
  768. case *ptypes.SetGlobalArgs:
  769. if permAcc = blockCache.GetAccount(ptypes.GlobalPermissionsAddress); permAcc == nil {
  770. PanicSanity("can't find global permissions account")
  771. }
  772. err = permAcc.Permissions.Base.Set(args.Permission, args.Value)
  773. case *ptypes.HasRoleArgs:
  774. return fmt.Errorf("HasRole is for contracts, not humans. Just look at the blockchain")
  775. case *ptypes.AddRoleArgs:
  776. if permAcc = blockCache.GetAccount(args.Address); permAcc == nil {
  777. return fmt.Errorf("Trying to update roles for unknown account %X", args.Address)
  778. }
  779. if !permAcc.Permissions.AddRole(args.Role) {
  780. return fmt.Errorf("Role (%s) already exists for account %X", args.Role, args.Address)
  781. }
  782. case *ptypes.RmRoleArgs:
  783. if permAcc = blockCache.GetAccount(args.Address); permAcc == nil {
  784. return fmt.Errorf("Trying to update roles for unknown account %X", args.Address)
  785. }
  786. if !permAcc.Permissions.RmRole(args.Role) {
  787. return fmt.Errorf("Role (%s) does not exist for account %X", args.Role, args.Address)
  788. }
  789. default:
  790. PanicSanity(Fmt("invalid permission function: %s", ptypes.PermFlagToString(permFlag)))
  791. }
  792. // TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
  793. if err != nil {
  794. return err
  795. }
  796. // Good!
  797. inAcc.Sequence += 1
  798. inAcc.Balance -= value
  799. blockCache.UpdateAccount(inAcc)
  800. if permAcc != nil {
  801. blockCache.UpdateAccount(permAcc)
  802. }
  803. if evc != nil {
  804. evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventDataTx{tx, nil, ""})
  805. evc.FireEvent(types.EventStringPermissions(ptypes.PermFlagToString(permFlag)), types.EventDataTx{tx, nil, ""})
  806. }
  807. return nil
  808. default:
  809. // binary decoding should not let this happen
  810. PanicSanity("Unknown Tx type")
  811. return nil
  812. }
  813. }
  814. //---------------------------------------------------------------
  815. // Get permission on an account or fall back to global value
  816. func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag) bool {
  817. if perm > ptypes.AllPermFlags {
  818. PanicSanity("Checking an unknown permission in state should never happen")
  819. }
  820. if acc == nil {
  821. // TODO
  822. // this needs to fall back to global or do some other specific things
  823. // eg. a bondAcc may be nil and so can only bond if global bonding is true
  824. }
  825. permString := ptypes.PermFlagToString(perm)
  826. v, err := acc.Permissions.Base.Get(perm)
  827. if _, ok := err.(ptypes.ErrValueNotSet); ok {
  828. if state == nil {
  829. PanicSanity("All known global permissions should be set!")
  830. }
  831. log.Info("Permission for account is not set. Querying GlobalPermissionsAddress", "perm", permString)
  832. return HasPermission(nil, state.GetAccount(ptypes.GlobalPermissionsAddress), perm)
  833. } else if v {
  834. log.Info("Account has permission", "address", Fmt("%X", acc.Address), "perm", permString)
  835. } else {
  836. log.Info("Account does not have permission", "address", Fmt("%X", acc.Address), "perm", permString)
  837. }
  838. return v
  839. }
  840. // TODO: for debug log the failed accounts
  841. func hasSendPermission(state AccountGetter, accs map[string]*acm.Account) bool {
  842. for _, acc := range accs {
  843. if !HasPermission(state, acc, ptypes.Send) {
  844. return false
  845. }
  846. }
  847. return true
  848. }
  849. func hasNamePermission(state AccountGetter, acc *acm.Account) bool {
  850. return HasPermission(state, acc, ptypes.Name)
  851. }
  852. func hasCallPermission(state AccountGetter, acc *acm.Account) bool {
  853. return HasPermission(state, acc, ptypes.Call)
  854. }
  855. func hasCreateContractPermission(state AccountGetter, acc *acm.Account) bool {
  856. return HasPermission(state, acc, ptypes.CreateContract)
  857. }
  858. func hasCreateAccountPermission(state AccountGetter, accs map[string]*acm.Account) bool {
  859. for _, acc := range accs {
  860. if !HasPermission(state, acc, ptypes.CreateAccount) {
  861. return false
  862. }
  863. }
  864. return true
  865. }
  866. func hasBondPermission(state AccountGetter, acc *acm.Account) bool {
  867. return HasPermission(state, acc, ptypes.Bond)
  868. }
  869. func hasBondOrSendPermission(state AccountGetter, accs map[string]*acm.Account) bool {
  870. for _, acc := range accs {
  871. if !HasPermission(state, acc, ptypes.Bond) {
  872. if !HasPermission(state, acc, ptypes.Send) {
  873. return false
  874. }
  875. }
  876. }
  877. return true
  878. }
  879. //-----------------------------------------------------------------------------
  880. type InvalidTxError struct {
  881. Tx types.Tx
  882. Reason error
  883. }
  884. func (txErr InvalidTxError) Error() string {
  885. return Fmt("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason)
  886. }