state_processor.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Copyright 2015 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package core
  17. import (
  18. "errors"
  19. "math/big"
  20. "github.com/ethereum/go-ethereum/common"
  21. "github.com/ethereum/go-ethereum/core/state"
  22. "github.com/ethereum/go-ethereum/core/types"
  23. "github.com/ethereum/go-ethereum/core/vm"
  24. "github.com/ethereum/go-ethereum/crypto"
  25. "github.com/ethereum/go-ethereum/logger"
  26. "github.com/ethereum/go-ethereum/logger/glog"
  27. )
  28. var (
  29. big8 = big.NewInt(8)
  30. big32 = big.NewInt(32)
  31. blockedCodeHashErr = errors.New("core: blocked code-hash found during execution")
  32. // DAO attack chain rupture mechanism
  33. ruptureBlock = uint64(1760000) // Block number of the voted soft fork
  34. ruptureThreshold = big.NewInt(4000000) // Gas threshold for passing a fork vote
  35. ruptureGasCache = make(map[common.Hash]*big.Int) // Amount of gas in the point of rupture
  36. ruptureCodeHashes = map[common.Hash]struct{}{
  37. common.HexToHash("6a5d24750f78441e56fec050dc52fe8e911976485b7472faac7464a176a67caa"): struct{}{},
  38. }
  39. ruptureWhitelist = map[common.Address]bool{
  40. common.HexToAddress("Da4a4626d3E16e094De3225A751aAb7128e96526"): true, // multisig
  41. common.HexToAddress("2ba9D006C1D72E67A70b5526Fc6b4b0C0fd6D334"): true, // attack contract
  42. }
  43. ruptureCacheLimit = 30000 // 1 epoch, 0.5 per possible fork
  44. )
  45. // StateProcessor is a basic Processor, which takes care of transitioning
  46. // state from one point to another.
  47. //
  48. // StateProcessor implements Processor.
  49. type StateProcessor struct {
  50. config *ChainConfig
  51. bc *BlockChain
  52. }
  53. // NewStateProcessor initialises a new StateProcessor.
  54. func NewStateProcessor(config *ChainConfig, bc *BlockChain) *StateProcessor {
  55. return &StateProcessor{
  56. config: config,
  57. bc: bc,
  58. }
  59. }
  60. // Process processes the state changes according to the Ethereum rules by running
  61. // the transaction messages using the statedb and applying any rewards to both
  62. // the processor (coinbase) and any included uncles.
  63. //
  64. // Process returns the receipts and logs accumulated during the process and
  65. // returns the amount of gas that was used in the process. If any of the
  66. // transactions failed to execute due to insufficient gas it will return an error.
  67. func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, vm.Logs, *big.Int, error) {
  68. var (
  69. receipts types.Receipts
  70. totalUsedGas = big.NewInt(0)
  71. err error
  72. header = block.Header()
  73. allLogs vm.Logs
  74. gp = new(GasPool).AddGas(block.GasLimit())
  75. )
  76. for i, tx := range block.Transactions() {
  77. statedb.StartRecord(tx.Hash(), block.Hash(), i)
  78. receipt, logs, _, err := ApplyTransaction(p.config, p.bc, gp, statedb, header, tx, totalUsedGas, cfg)
  79. if err != nil {
  80. return nil, nil, totalUsedGas, err
  81. }
  82. receipts = append(receipts, receipt)
  83. allLogs = append(allLogs, logs...)
  84. }
  85. AccumulateRewards(statedb, header, block.Uncles())
  86. return receipts, allLogs, totalUsedGas, err
  87. }
  88. // ApplyTransaction attempts to apply a transaction to the given state database
  89. // and uses the input parameters for its environment.
  90. //
  91. // ApplyTransactions returns the generated receipts and vm logs during the
  92. // execution of the state transition phase.
  93. func ApplyTransaction(config *ChainConfig, bc *BlockChain, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, vm.Logs, *big.Int, error) {
  94. env := NewEnv(statedb, config, bc, tx, header, cfg)
  95. _, gas, err := ApplyMessage(env, tx, gp)
  96. if err != nil {
  97. return nil, nil, nil, err
  98. }
  99. // Check whether the DAO needs to be blocked or not
  100. if bc != nil { // Test chain maker uses nil to construct the potential chain
  101. blockRuptureCodes := false
  102. if number := header.Number.Uint64(); number >= ruptureBlock {
  103. // We're past the rupture point, find the vote result on this chain and apply it
  104. ancestry := []common.Hash{header.Hash(), header.ParentHash}
  105. for _, ok := ruptureGasCache[ancestry[len(ancestry)-1]]; !ok && number >= ruptureBlock+uint64(len(ancestry)); {
  106. ancestry = append(ancestry, bc.GetHeaderByHash(ancestry[len(ancestry)-1]).ParentHash)
  107. }
  108. decider := ancestry[len(ancestry)-1]
  109. vote, ok := ruptureGasCache[decider]
  110. if !ok {
  111. // We've reached the rupture point, retrieve the vote
  112. vote = bc.GetHeaderByHash(decider).GasLimit
  113. ruptureGasCache[decider] = vote
  114. }
  115. // Cache the vote result for all ancestors and check the DAO
  116. for _, hash := range ancestry {
  117. ruptureGasCache[hash] = vote
  118. }
  119. if ruptureGasCache[ancestry[0]].Cmp(ruptureThreshold) <= 0 {
  120. blockRuptureCodes = true
  121. }
  122. // Make sure we don't OOM long run due to too many votes caching up
  123. for len(ruptureGasCache) > ruptureCacheLimit {
  124. for hash, _ := range ruptureGasCache {
  125. delete(ruptureGasCache, hash)
  126. break
  127. }
  128. }
  129. }
  130. // Iterate over the bullshit blacklist to keep waste some time while keeping random Joe's happy
  131. if len(BlockedCodeHashes) > 0 {
  132. for hash, _ := range env.GetMarkedCodeHashes() {
  133. // Figure out whether this contract should in general be blocked
  134. if _, blocked := BlockedCodeHashes[hash]; blocked {
  135. return nil, nil, nil, blockedCodeHashErr
  136. }
  137. }
  138. }
  139. // Actually verify the DAO soft fork
  140. recipient := tx.To()
  141. if blockRuptureCodes && (recipient == nil || !ruptureWhitelist[*recipient]) {
  142. for hash, _ := range env.GetMarkedCodeHashes() {
  143. if _, blocked := ruptureCodeHashes[hash]; blocked {
  144. return nil, nil, nil, blockedCodeHashErr
  145. }
  146. }
  147. }
  148. }
  149. // Update the state with pending changes
  150. usedGas.Add(usedGas, gas)
  151. receipt := types.NewReceipt(statedb.IntermediateRoot().Bytes(), usedGas)
  152. receipt.TxHash = tx.Hash()
  153. receipt.GasUsed = new(big.Int).Set(gas)
  154. if MessageCreatesContract(tx) {
  155. from, _ := tx.From()
  156. receipt.ContractAddress = crypto.CreateAddress(from, tx.Nonce())
  157. }
  158. logs := statedb.GetLogs(tx.Hash())
  159. receipt.Logs = logs
  160. receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
  161. glog.V(logger.Debug).Infoln(receipt)
  162. return receipt, logs, gas, err
  163. }
  164. // AccumulateRewards credits the coinbase of the given block with the
  165. // mining reward. The total reward consists of the static block reward
  166. // and rewards for included uncles. The coinbase of each uncle block is
  167. // also rewarded.
  168. func AccumulateRewards(statedb *state.StateDB, header *types.Header, uncles []*types.Header) {
  169. reward := new(big.Int).Set(BlockReward)
  170. r := new(big.Int)
  171. for _, uncle := range uncles {
  172. r.Add(uncle.Number, big8)
  173. r.Sub(r, header.Number)
  174. r.Mul(r, BlockReward)
  175. r.Div(r, big8)
  176. statedb.AddBalance(uncle.Coinbase, r)
  177. r.Div(BlockReward, big32)
  178. reward.Add(reward, r)
  179. }
  180. statedb.AddBalance(header.Coinbase, reward)
  181. }