github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/core/block_processor.go (about) 1 // Copyright 2014 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 "fmt" 21 "math/big" 22 "sync" 23 "time" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/core/state" 27 "github.com/ethereum/go-ethereum/core/types" 28 "github.com/ethereum/go-ethereum/crypto" 29 "github.com/ethereum/go-ethereum/event" 30 "github.com/ethereum/go-ethereum/logger" 31 "github.com/ethereum/go-ethereum/logger/glog" 32 "github.com/ethereum/go-ethereum/params" 33 "github.com/ethereum/go-ethereum/pow" 34 "gopkg.in/fatih/set.v0" 35 ) 36 37 const ( 38 // must be bumped when consensus algorithm is changed, this forces the upgradedb 39 // command to be run (forces the blocks to be imported again using the new algorithm) 40 BlockChainVersion = 3 41 ) 42 43 type BlockProcessor struct { 44 chainDb common.Database 45 // Mutex for locking the block processor. Blocks can only be handled one at a time 46 mutex sync.Mutex 47 // Canonical block chain 48 bc *ChainManager 49 // non-persistent key/value memory storage 50 mem map[string]*big.Int 51 // Proof of work used for validating 52 Pow pow.PoW 53 54 events event.Subscription 55 56 eventMux *event.TypeMux 57 } 58 59 // TODO: type GasPool big.Int 60 // 61 // GasPool is implemented by state.StateObject. This is a historical 62 // coincidence. Gas tracking should move out of StateObject. 63 64 // GasPool tracks the amount of gas available during 65 // execution of the transactions in a block. 66 type GasPool interface { 67 AddGas(gas, price *big.Int) 68 SubGas(gas, price *big.Int) error 69 } 70 71 func NewBlockProcessor(db common.Database, pow pow.PoW, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor { 72 sm := &BlockProcessor{ 73 chainDb: db, 74 mem: make(map[string]*big.Int), 75 Pow: pow, 76 bc: chainManager, 77 eventMux: eventMux, 78 } 79 return sm 80 } 81 82 func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block, transientProcess bool) (receipts types.Receipts, err error) { 83 gp := statedb.GetOrNewStateObject(block.Coinbase()) 84 gp.SetGasLimit(block.GasLimit()) 85 86 // Process the transactions on to parent state 87 receipts, err = sm.ApplyTransactions(gp, statedb, block, block.Transactions(), transientProcess) 88 if err != nil { 89 return nil, err 90 } 91 92 return receipts, nil 93 } 94 95 func (self *BlockProcessor) ApplyTransaction(gp GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) { 96 _, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, header), tx, gp) 97 if err != nil { 98 return nil, nil, err 99 } 100 101 // Update the state with pending changes 102 statedb.SyncIntermediate() 103 104 usedGas.Add(usedGas, gas) 105 receipt := types.NewReceipt(statedb.Root().Bytes(), usedGas) 106 receipt.TxHash = tx.Hash() 107 receipt.GasUsed = new(big.Int).Set(gas) 108 if MessageCreatesContract(tx) { 109 from, _ := tx.From() 110 receipt.ContractAddress = crypto.CreateAddress(from, tx.Nonce()) 111 } 112 113 logs := statedb.GetLogs(tx.Hash()) 114 receipt.SetLogs(logs) 115 receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) 116 117 glog.V(logger.Debug).Infoln(receipt) 118 119 // Notify all subscribers 120 if !transientProcess { 121 go self.eventMux.Post(TxPostEvent{tx}) 122 go self.eventMux.Post(logs) 123 } 124 125 return receipt, gas, err 126 } 127 func (self *BlockProcessor) ChainManager() *ChainManager { 128 return self.bc 129 } 130 131 func (self *BlockProcessor) ApplyTransactions(gp GasPool, statedb *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, error) { 132 var ( 133 receipts types.Receipts 134 totalUsedGas = big.NewInt(0) 135 err error 136 cumulativeSum = new(big.Int) 137 header = block.Header() 138 ) 139 140 for i, tx := range txs { 141 statedb.StartRecord(tx.Hash(), block.Hash(), i) 142 143 receipt, txGas, err := self.ApplyTransaction(gp, statedb, header, tx, totalUsedGas, transientProcess) 144 if err != nil { 145 return nil, err 146 } 147 148 if err != nil { 149 glog.V(logger.Core).Infoln("TX err:", err) 150 } 151 receipts = append(receipts, receipt) 152 153 cumulativeSum.Add(cumulativeSum, new(big.Int).Mul(txGas, tx.GasPrice())) 154 } 155 156 if block.GasUsed().Cmp(totalUsedGas) != 0 { 157 return nil, ValidationError(fmt.Sprintf("gas used error (%v / %v)", block.GasUsed(), totalUsedGas)) 158 } 159 160 if transientProcess { 161 go self.eventMux.Post(PendingBlockEvent{block, statedb.Logs()}) 162 } 163 164 return receipts, err 165 } 166 167 func (sm *BlockProcessor) RetryProcess(block *types.Block) (logs state.Logs, err error) { 168 // Processing a blocks may never happen simultaneously 169 sm.mutex.Lock() 170 defer sm.mutex.Unlock() 171 172 if !sm.bc.HasBlock(block.ParentHash()) { 173 return nil, ParentError(block.ParentHash()) 174 } 175 parent := sm.bc.GetBlock(block.ParentHash()) 176 177 // FIXME Change to full header validation. See #1225 178 errch := make(chan bool) 179 go func() { errch <- sm.Pow.Verify(block) }() 180 181 logs, _, err = sm.processWithParent(block, parent) 182 if !<-errch { 183 return nil, ValidationError("Block's nonce is invalid (= %x)", block.Nonce) 184 } 185 186 return logs, err 187 } 188 189 // Process block will attempt to process the given block's transactions and applies them 190 // on top of the block's parent state (given it exists) and will return wether it was 191 // successful or not. 192 func (sm *BlockProcessor) Process(block *types.Block) (logs state.Logs, receipts types.Receipts, err error) { 193 // Processing a blocks may never happen simultaneously 194 sm.mutex.Lock() 195 defer sm.mutex.Unlock() 196 197 if sm.bc.HasBlock(block.Hash()) { 198 return nil, nil, &KnownBlockError{block.Number(), block.Hash()} 199 } 200 201 if !sm.bc.HasBlock(block.ParentHash()) { 202 return nil, nil, ParentError(block.ParentHash()) 203 } 204 parent := sm.bc.GetBlock(block.ParentHash()) 205 return sm.processWithParent(block, parent) 206 } 207 208 func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs state.Logs, receipts types.Receipts, err error) { 209 // Create a new state based on the parent's root (e.g., create copy) 210 state := state.New(parent.Root(), sm.chainDb) 211 header := block.Header() 212 uncles := block.Uncles() 213 txs := block.Transactions() 214 215 // Block validation 216 if err = ValidateHeader(sm.Pow, header, parent, false, false); err != nil { 217 return 218 } 219 220 // There can be at most two uncles 221 if len(uncles) > 2 { 222 return nil, nil, ValidationError("Block can only contain maximum 2 uncles (contained %v)", len(uncles)) 223 } 224 225 receipts, err = sm.TransitionState(state, parent, block, false) 226 if err != nil { 227 return 228 } 229 230 // Validate the received block's bloom with the one derived from the generated receipts. 231 // For valid blocks this should always validate to true. 232 rbloom := types.CreateBloom(receipts) 233 if rbloom != header.Bloom { 234 err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) 235 return 236 } 237 238 // The transactions Trie's root (R = (Tr [[i, RLP(T1)], [i, RLP(T2)], ... [n, RLP(Tn)]])) 239 // can be used by light clients to make sure they've received the correct Txs 240 txSha := types.DeriveSha(txs) 241 if txSha != header.TxHash { 242 err = fmt.Errorf("invalid transaction root hash. received=%x calculated=%x", header.TxHash, txSha) 243 return 244 } 245 246 // Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]])) 247 receiptSha := types.DeriveSha(receipts) 248 if receiptSha != header.ReceiptHash { 249 err = fmt.Errorf("invalid receipt root hash. received=%x calculated=%x", header.ReceiptHash, receiptSha) 250 return 251 } 252 253 // Verify UncleHash before running other uncle validations 254 unclesSha := types.CalcUncleHash(uncles) 255 if unclesSha != header.UncleHash { 256 err = fmt.Errorf("invalid uncles root hash. received=%x calculated=%x", header.UncleHash, unclesSha) 257 return 258 } 259 260 // Verify uncles 261 if err = sm.VerifyUncles(state, block, parent); err != nil { 262 return 263 } 264 // Accumulate static rewards; block reward, uncle's and uncle inclusion. 265 AccumulateRewards(state, header, uncles) 266 267 // Commit state objects/accounts to a temporary trie (does not save) 268 // used to calculate the state root. 269 state.SyncObjects() 270 if header.Root != state.Root() { 271 err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root()) 272 return 273 } 274 275 // Sync the current block's state to the database 276 state.Sync() 277 278 return state.Logs(), receipts, nil 279 } 280 281 var ( 282 big8 = big.NewInt(8) 283 big32 = big.NewInt(32) 284 ) 285 286 // AccumulateRewards credits the coinbase of the given block with the 287 // mining reward. The total reward consists of the static block reward 288 // and rewards for included uncles. The coinbase of each uncle block is 289 // also rewarded. 290 func AccumulateRewards(statedb *state.StateDB, header *types.Header, uncles []*types.Header) { 291 reward := new(big.Int).Set(BlockReward) 292 r := new(big.Int) 293 for _, uncle := range uncles { 294 r.Add(uncle.Number, big8) 295 r.Sub(r, header.Number) 296 r.Mul(r, BlockReward) 297 r.Div(r, big8) 298 statedb.AddBalance(uncle.Coinbase, r) 299 300 r.Div(BlockReward, big32) 301 reward.Add(reward, r) 302 } 303 statedb.AddBalance(header.Coinbase, reward) 304 } 305 306 func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *types.Block) error { 307 uncles := set.New() 308 ancestors := make(map[common.Hash]*types.Block) 309 for _, ancestor := range sm.bc.GetBlocksFromHash(block.ParentHash(), 7) { 310 ancestors[ancestor.Hash()] = ancestor 311 // Include ancestors uncles in the uncle set. Uncles must be unique. 312 for _, uncle := range ancestor.Uncles() { 313 uncles.Add(uncle.Hash()) 314 } 315 } 316 ancestors[block.Hash()] = block 317 uncles.Add(block.Hash()) 318 319 for i, uncle := range block.Uncles() { 320 hash := uncle.Hash() 321 if uncles.Has(hash) { 322 // Error not unique 323 return UncleError("uncle[%d](%x) not unique", i, hash[:4]) 324 } 325 uncles.Add(hash) 326 327 if ancestors[hash] != nil { 328 branch := fmt.Sprintf(" O - %x\n |\n", block.Hash()) 329 for h := range ancestors { 330 branch += fmt.Sprintf(" O - %x\n |\n", h) 331 } 332 glog.Infoln(branch) 333 return UncleError("uncle[%d](%x) is ancestor", i, hash[:4]) 334 } 335 336 if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == parent.Hash() { 337 return UncleError("uncle[%d](%x)'s parent is not ancestor (%x)", i, hash[:4], uncle.ParentHash[0:4]) 338 } 339 340 if err := ValidateHeader(sm.Pow, uncle, ancestors[uncle.ParentHash], true, true); err != nil { 341 return ValidationError(fmt.Sprintf("uncle[%d](%x) header invalid: %v", i, hash[:4], err)) 342 } 343 } 344 345 return nil 346 } 347 348 // GetBlockReceipts returns the receipts beloniging to the block hash 349 func (sm *BlockProcessor) GetBlockReceipts(bhash common.Hash) types.Receipts { 350 if block := sm.ChainManager().GetBlock(bhash); block != nil { 351 return GetBlockReceipts(sm.chainDb, block.Hash()) 352 } 353 354 return nil 355 } 356 357 // GetLogs returns the logs of the given block. This method is using a two step approach 358 // where it tries to get it from the (updated) method which gets them from the receipts or 359 // the depricated way by re-processing the block. 360 func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) { 361 receipts := GetBlockReceipts(sm.chainDb, block.Hash()) 362 // coalesce logs 363 for _, receipt := range receipts { 364 logs = append(logs, receipt.Logs()...) 365 } 366 return logs, nil 367 } 368 369 // See YP section 4.3.4. "Block Header Validity" 370 // Validates a block. Returns an error if the block is invalid. 371 func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, checkPow, uncle bool) error { 372 if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 { 373 return fmt.Errorf("Block extra data too long (%d)", len(block.Extra)) 374 } 375 376 if uncle { 377 if block.Time.Cmp(common.MaxBig) == 1 { 378 return BlockTSTooBigErr 379 } 380 } else { 381 if block.Time.Cmp(big.NewInt(time.Now().Unix())) == 1 { 382 return BlockFutureErr 383 } 384 } 385 if block.Time.Cmp(parent.Time()) != 1 { 386 return BlockEqualTSErr 387 } 388 389 expd := CalcDifficulty(block.Time.Uint64(), parent.Time().Uint64(), parent.Number(), parent.Difficulty()) 390 if expd.Cmp(block.Difficulty) != 0 { 391 return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd) 392 } 393 394 var a, b *big.Int 395 a = parent.GasLimit() 396 a = a.Sub(a, block.GasLimit) 397 a.Abs(a) 398 b = parent.GasLimit() 399 b = b.Div(b, params.GasLimitBoundDivisor) 400 if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) { 401 return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b) 402 } 403 404 num := parent.Number() 405 num.Sub(block.Number, num) 406 if num.Cmp(big.NewInt(1)) != 0 { 407 return BlockNumberErr 408 } 409 410 if checkPow { 411 // Verify the nonce of the block. Return an error if it's not valid 412 if !pow.Verify(types.NewBlockWithHeader(block)) { 413 return ValidationError("Block's nonce is invalid (= %x)", block.Nonce) 414 } 415 } 416 417 return nil 418 }