github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/core/state_processor.go (about) 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 17 package core 18 19 import ( 20 "errors" 21 "fmt" 22 "math/big" 23 24 "github.com/ethereumproject/go-ethereum/core/state" 25 "github.com/ethereumproject/go-ethereum/core/types" 26 "github.com/ethereumproject/go-ethereum/core/vm" 27 "github.com/ethereumproject/go-ethereum/crypto" 28 "github.com/ethereumproject/go-ethereum/logger" 29 "github.com/ethereumproject/go-ethereum/logger/glog" 30 ) 31 32 var ( 33 MaximumBlockReward = big.NewInt(5e+18) // that's shiny 5 ether 34 big8 = big.NewInt(8) 35 big32 = big.NewInt(32) 36 DisinflationRateQuotient = big.NewInt(4) 37 DisinflationRateDivisor = big.NewInt(5) 38 39 ErrConfiguration = errors.New("invalid configuration") 40 ) 41 42 // StateProcessor is a basic Processor, which takes care of transitioning 43 // state from one point to another. 44 // 45 // StateProcessor implements Processor. 46 type StateProcessor struct { 47 config *ChainConfig 48 bc *BlockChain 49 } 50 51 // NewStateProcessor initialises a new StateProcessor. 52 func NewStateProcessor(config *ChainConfig, bc *BlockChain) *StateProcessor { 53 return &StateProcessor{ 54 config: config, 55 bc: bc, 56 } 57 } 58 59 // Process processes the state changes according to the Ethereum rules by running 60 // the transaction messages using the statedb and applying any rewards to both 61 // the processor (coinbase) and any included uncles. 62 // 63 // Process returns the receipts and logs accumulated during the process and 64 // returns the amount of gas that was used in the process. If any of the 65 // transactions failed to execute due to insufficient gas it will return an error. 66 func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB) (types.Receipts, vm.Logs, *big.Int, error) { 67 var ( 68 receipts types.Receipts 69 totalUsedGas = big.NewInt(0) 70 err error 71 header = block.Header() 72 allLogs vm.Logs 73 gp = new(GasPool).AddGas(block.GasLimit()) 74 ) 75 // Iterate over and process the individual transactions 76 for i, tx := range block.Transactions() { 77 if tx.Protected() { 78 chainId := p.config.GetChainID() 79 if chainId.Cmp(new(big.Int)) == 0 { 80 return nil, nil, nil, fmt.Errorf("ChainID is not set for EIP-155 in chain configuration at block number: %v. \n Tx ChainID: %v", block.Number(), tx.ChainId()) 81 } 82 if tx.ChainId() == nil || tx.ChainId().Cmp(chainId) != 0 { 83 return nil, nil, nil, fmt.Errorf("Invalid transaction chain id. Current chain id: %v tx chain id: %v", p.config.GetChainID(), tx.ChainId()) 84 } 85 } 86 statedb.StartRecord(tx.Hash(), block.Hash(), i) 87 if UseSputnikVM != "true" { 88 receipt, logs, _, err := ApplyTransaction(p.config, p.bc, gp, statedb, header, tx, totalUsedGas) 89 if err != nil { 90 return nil, nil, totalUsedGas, err 91 } 92 receipts = append(receipts, receipt) 93 allLogs = append(allLogs, logs...) 94 continue 95 } 96 receipt, logs, _, err := ApplyMultiVmTransaction(p.config, p.bc, gp, statedb, header, tx, totalUsedGas) 97 if err != nil { 98 return nil, nil, totalUsedGas, err 99 } 100 receipts = append(receipts, receipt) 101 allLogs = append(allLogs, logs...) 102 } 103 AccumulateRewards(p.config, statedb, header, block.Uncles()) 104 105 return receipts, allLogs, totalUsedGas, err 106 } 107 108 // ApplyTransaction attempts to apply a transaction to the given state database 109 // and uses the input parameters for its environment. 110 // 111 // ApplyTransactions returns the generated receipts and vm logs during the 112 // execution of the state transition phase. 113 func ApplyTransaction(config *ChainConfig, bc *BlockChain, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int) (*types.Receipt, vm.Logs, *big.Int, error) { 114 tx.SetSigner(config.GetSigner(header.Number)) 115 116 _, gas, failed, err := ApplyMessage(NewEnv(statedb, config, bc, tx, header), tx, gp) 117 if err != nil { 118 return nil, nil, nil, err 119 } 120 121 // Update the state with pending changes 122 usedGas.Add(usedGas, gas) 123 receipt := types.NewReceipt(statedb.IntermediateRoot(false).Bytes(), usedGas) 124 receipt.TxHash = tx.Hash() 125 receipt.GasUsed = new(big.Int).Set(gas) 126 if MessageCreatesContract(tx) { 127 from, _ := tx.From() 128 receipt.ContractAddress = crypto.CreateAddress(from, tx.Nonce()) 129 } 130 131 logs := statedb.GetLogs(tx.Hash()) 132 receipt.Logs = logs 133 receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) 134 if failed { 135 receipt.Status = types.TxFailure 136 } else { 137 receipt.Status = types.TxSuccess 138 } 139 140 glog.V(logger.Debug).Infoln(receipt) 141 142 return receipt, logs, gas, err 143 } 144 145 // AccumulateRewards credits the coinbase of the given block with the 146 // mining reward. The total reward consists of the static block reward 147 // and rewards for included uncles. The coinbase of each uncle block is 148 // also rewarded. 149 func AccumulateRewards(config *ChainConfig, statedb *state.StateDB, header *types.Header, uncles []*types.Header) { 150 151 // An uncle is a block that would be considered an orphan because its not on the longest chain (it's an alternative block at the same height as your parent). 152 // https://www.reddit.com/r/ethereum/comments/3c9jbf/wtf_are_uncles_and_why_do_they_matter/ 153 154 // uncle.Number = 2,535,998 // assuming "latest" uncle... 155 // block.Number = 2,534,999 // uncles can be at same height as each other 156 // ... as uncles get older (within validation; <=n-7), reward drops 157 158 // Since ECIP1017 impacts "Era 1" idempotently and with constant 0-block based eras, 159 // we don't care about where the block/fork implementing it is. 160 feat, _, configured := config.HasFeature("reward") 161 if !configured { 162 reward := new(big.Int).Set(MaximumBlockReward) 163 r := new(big.Int) 164 165 for _, uncle := range uncles { 166 r.Add(uncle.Number, big8) // 2,534,998 + 8 = 2,535,006 167 r.Sub(r, header.Number) // 2,535,006 - 2,534,999 = 7 168 r.Mul(r, MaximumBlockReward) // 7 * 5e+18 = 35e+18 169 r.Div(r, big8) // 35e+18 / 8 = 7/8 * 5e+18 170 171 statedb.AddBalance(uncle.Coinbase, r) // $$ 172 173 r.Div(MaximumBlockReward, big32) // 5e+18 / 32 174 reward.Add(reward, r) // 5e+18 + (1/32*5e+18) 175 } 176 statedb.AddBalance(header.Coinbase, reward) // $$ => 5e+18 + (1/32*5e+18) 177 } else { 178 // Check that configuration specifies ECIP1017. 179 val, ok := feat.GetString("type") 180 if !ok || val != "ecip1017" { 181 panic(ErrConfiguration) 182 } 183 184 // Ensure value 'era' is configured. 185 eraLen, ok := feat.GetBigInt("era") 186 if !ok || eraLen.Cmp(big.NewInt(0)) <= 0 { 187 panic(ErrConfiguration) 188 } 189 190 era := GetBlockEra(header.Number, eraLen) 191 192 wr := GetBlockWinnerRewardByEra(era) // wr "winner reward". 5, 4, 3.2, 2.56, ... 193 194 wurs := GetBlockWinnerRewardForUnclesByEra(era, uncles) // wurs "winner uncle rewards" 195 wr.Add(wr, wurs) 196 197 statedb.AddBalance(header.Coinbase, wr) // $$ 198 199 // Reward uncle miners. 200 for _, uncle := range uncles { 201 ur := GetBlockUncleRewardByEra(era, header, uncle) 202 statedb.AddBalance(uncle.Coinbase, ur) // $$ 203 } 204 } 205 } 206 207 // As of "Era 2" (zero-index era 1), uncle miners and winners are rewarded equally for each included block. 208 // So they share this function. 209 func getEraUncleBlockReward(era *big.Int) *big.Int { 210 return new(big.Int).Div(GetBlockWinnerRewardByEra(era), big32) 211 } 212 213 // GetBlockUncleRewardByEra gets called _for each uncle miner_ associated with a winner block's uncles. 214 func GetBlockUncleRewardByEra(era *big.Int, header, uncle *types.Header) *big.Int { 215 // Era 1 (index 0): 216 // An extra reward to the winning miner for including uncles as part of the block, in the form of an extra 1/32 (0.15625ETC) per uncle included, up to a maximum of two (2) uncles. 217 if era.Cmp(big.NewInt(0)) == 0 { 218 r := new(big.Int) 219 r.Add(uncle.Number, big8) // 2,534,998 + 8 = 2,535,006 220 r.Sub(r, header.Number) // 2,535,006 - 2,534,999 = 7 221 r.Mul(r, MaximumBlockReward) // 7 * 5e+18 = 35e+18 222 r.Div(r, big8) // 35e+18 / 8 = 7/8 * 5e+18 223 224 return r 225 } 226 return getEraUncleBlockReward(era) 227 } 228 229 // GetBlockWinnerRewardForUnclesByEra gets called _per winner_, and accumulates rewards for each included uncle. 230 // Assumes uncles have been validated and limited (@ func (v *BlockValidator) VerifyUncles). 231 func GetBlockWinnerRewardForUnclesByEra(era *big.Int, uncles []*types.Header) *big.Int { 232 r := big.NewInt(0) 233 234 for range uncles { 235 r.Add(r, getEraUncleBlockReward(era)) // can reuse this, since 1/32 for winner's uncles remain unchanged from "Era 1" 236 } 237 return r 238 } 239 240 // GetRewardByEra gets a block reward at disinflation rate. 241 // Constants MaxBlockReward, DisinflationRateQuotient, and DisinflationRateDivisor assumed. 242 func GetBlockWinnerRewardByEra(era *big.Int) *big.Int { 243 if era.Cmp(big.NewInt(0)) == 0 { 244 return new(big.Int).Set(MaximumBlockReward) 245 } 246 247 // MaxBlockReward _r_ * (4/5)**era == MaxBlockReward * (4**era) / (5**era) 248 // since (q/d)**n == q**n / d**n 249 // qed 250 var q, d, r *big.Int = new(big.Int), new(big.Int), new(big.Int) 251 252 q.Exp(DisinflationRateQuotient, era, nil) 253 d.Exp(DisinflationRateDivisor, era, nil) 254 255 r.Mul(MaximumBlockReward, q) 256 r.Div(r, d) 257 258 return r 259 } 260 261 // GetBlockEra gets which "Era" a given block is within, given an era length (ecip-1017 has era=5,000,000 blocks) 262 // Returns a zero-index era number, so "Era 1": 0, "Era 2": 1, "Era 3": 2 ... 263 func GetBlockEra(blockNum, eraLength *big.Int) *big.Int { 264 // If genesis block or impossible negative-numbered block, return zero-val. 265 if blockNum.Sign() < 1 { 266 return new(big.Int) 267 } 268 269 remainder := big.NewInt(0).Mod(big.NewInt(0).Sub(blockNum, big.NewInt(1)), eraLength) 270 base := big.NewInt(0).Sub(blockNum, remainder) 271 272 d := big.NewInt(0).Div(base, eraLength) 273 dremainder := big.NewInt(0).Mod(d, big.NewInt(1)) 274 275 return new(big.Int).Sub(d, dremainder) 276 }