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

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
  1. package state
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. acm "github.com/tendermint/tendermint/account"
  7. . "github.com/tendermint/tendermint/common"
  8. "github.com/tendermint/tendermint/events"
  9. ptypes "github.com/tendermint/tendermint/permission/types" // for GlobalPermissionAddress ...
  10. "github.com/tendermint/tendermint/types"
  11. "github.com/tendermint/tendermint/vm"
  12. )
  13. // NOTE: If an error occurs during block execution, state will be left
  14. // at an invalid state. Copy the state before calling ExecBlock!
  15. func ExecBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeader) error {
  16. err := execBlock(s, block, blockPartsHeader)
  17. if err != nil {
  18. return err
  19. }
  20. // State.Hash should match block.StateHash
  21. stateHash := s.Hash()
  22. if !bytes.Equal(stateHash, block.StateHash) {
  23. return errors.New(Fmt("Invalid state hash. Expected %X, got %X",
  24. stateHash, block.StateHash))
  25. }
  26. return nil
  27. }
  28. // executes transactions of a block, does not check block.StateHash
  29. // NOTE: If an error occurs during block execution, state will be left
  30. // at an invalid state. Copy the state before calling execBlock!
  31. func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeader) error {
  32. // Basic block validation.
  33. err := block.ValidateBasic(s.ChainID, s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime)
  34. if err != nil {
  35. return err
  36. }
  37. // Validate block LastValidation.
  38. if block.Height == 1 {
  39. if len(block.LastValidation.Precommits) != 0 {
  40. return errors.New("Block at height 1 (first block) should have no LastValidation precommits")
  41. }
  42. } else {
  43. if len(block.LastValidation.Precommits) != s.LastBondedValidators.Size() {
  44. return errors.New(Fmt("Invalid block validation size. Expected %v, got %v",
  45. s.LastBondedValidators.Size(), len(block.LastValidation.Precommits)))
  46. }
  47. err := s.LastBondedValidators.VerifyValidation(
  48. s.ChainID, s.LastBlockHash, s.LastBlockParts, block.Height-1, block.LastValidation)
  49. if err != nil {
  50. return err
  51. }
  52. }
  53. // Update Validator.LastCommitHeight as necessary.
  54. 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. }