github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/consensus/ethash/consensus.go (about) 1 // Copyright 2018 Wanchain Foundation Ltd 2 // Copyright 2017 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 18 package ethash 19 20 import ( 21 "bytes" 22 "errors" 23 "fmt" 24 "math/big" 25 //"runtime" 26 "time" 27 28 "github.com/wanchain/go-wanchain/common" 29 "github.com/wanchain/go-wanchain/common/math" 30 "github.com/wanchain/go-wanchain/consensus" 31 //"github.com/wanchain/go-wanchain/consensus/misc" 32 "github.com/wanchain/go-wanchain/accounts" 33 "github.com/wanchain/go-wanchain/core/state" 34 "github.com/wanchain/go-wanchain/core/types" 35 "github.com/wanchain/go-wanchain/crypto" 36 "github.com/wanchain/go-wanchain/crypto/sha3" 37 "github.com/wanchain/go-wanchain/log" 38 "github.com/wanchain/go-wanchain/params" 39 "github.com/wanchain/go-wanchain/rlp" 40 //set "gopkg.in/fatih/set.v0" 41 "runtime" 42 ) 43 44 const ( 45 checkpointInterval = 8192 // Number of blocks after which to save the signers state 46 // checkpointInterval = 4 // Number of blocks after which to save the signers state, using small value for testing... 47 ) 48 49 // Ethash proof-of-work protocol constants. 50 var ( 51 //frontierBlockReward *big.Int = big.NewInt(5e+18) // Block reward in wei for successfully mining a block 52 byzantiumBlockReward *big.Int = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium 53 maxUncles = 0 // Maximum number of uncles allowed in a single block 54 extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity 55 extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal 56 allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks 57 58 ) 59 60 // Various error messages to mark blocks invalid. These should be private to 61 // prevent engine specific errors from being referenced in the remainder of the 62 // codebase, inherently breaking if the engine is swapped out. Please put common 63 // error types into the consensus package. 64 var ( 65 errLargeBlockTime = errors.New("timestamp too big") 66 errZeroBlockTime = errors.New("timestamp equals parent's") 67 errTooManyUncles = errors.New("too many uncles") 68 errDuplicateUncle = errors.New("duplicate uncle") 69 errUncleIsAncestor = errors.New("uncle is ancestor") 70 errDanglingUncle = errors.New("uncle's parent is not ancestor") 71 errNonceOutOfRange = errors.New("nonce out of range") 72 errInvalidDifficulty = errors.New("non-positive difficulty") 73 errInvalidMixDigest = errors.New("invalid mix digest") 74 errInvalidPoW = errors.New("invalid proof-of-work") 75 errMissingSignature = errors.New("extra data 65 byte suffix signature missing") 76 errUnauthorized = errors.New("unauthorized signer") 77 errAuthorTooOften = errors.New("signer too often") 78 errUsedSignerDescend = errors.New("disallow used signer descend") 79 ) 80 81 // INFO: copied from consensus/clique/clique.go 82 type SignerFn func(accounts.Account, []byte) ([]byte, error) 83 84 // INFO: copied from consensus/clique/clique.go 85 func sigHash(header *types.Header) (hash common.Hash) { 86 hasher := sha3.NewKeccak256() 87 88 rlp.Encode(hasher, []interface{}{ 89 header.ParentHash, 90 header.UncleHash, 91 header.Coinbase, 92 header.Root, 93 header.TxHash, 94 header.ReceiptHash, 95 header.Bloom, 96 header.Difficulty, 97 header.Number, 98 header.GasLimit, 99 header.GasUsed, 100 header.Time, 101 header.Extra[:len(header.Extra)-extraSeal], // Yes, this will panic if extra is too short 102 }) 103 hasher.Sum(hash[:0]) 104 return hash 105 } 106 107 // INFO: copied from consensus/clique/clique.go 108 // ecrecover extracts the Ethereum account address from a signed header. 109 func ecrecover(header *types.Header) (common.Address, error) { 110 // Retrieve the signature from the header extra-data 111 if len(header.Extra) < extraSeal { 112 return common.Address{}, errMissingSignature 113 } 114 signature := header.Extra[len(header.Extra)-extraSeal:] 115 116 // Recover the public key and the Ethereum address 117 //log.Trace(fmt.Sprintf(header.String())) 118 119 pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), signature) 120 // log.Trace("ecrecover(): Seal hash", "Input hash", sigHash(header).String()) 121 if err != nil { 122 return common.Address{}, err 123 } 124 var signer common.Address 125 copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) 126 127 // The signer's address should match the coinbase address in Wanchain Release 1, shall we add a warning if it's not? 128 // log.Trace("ecrecover()", "recovered signer", signer) 129 130 return signer, nil 131 } 132 133 // INFO: copied from consensus/clique/clique.go 134 // Author implements consensus.Engine, returning the header's coinbase as the 135 // proof-of-work verified author of the block. 136 func (ethash *Ethash) Author(header *types.Header) (common.Address, error) { 137 return header.Coinbase, nil 138 } 139 140 func (self *Ethash) Authorize(signer common.Address, signFn SignerFn) { 141 self.lock.Lock() 142 defer self.lock.Unlock() 143 144 self.signFn = signFn 145 self.signer = signer 146 } 147 148 // VerifyHeader checks whether a header conforms to the consensus rules of the 149 // stock Ethereum ethash engine. 150 func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { 151 // If we're running a full engine faking, accept any input as valid 152 if ethash.config.PowMode == ModeFullFake { 153 return nil 154 } 155 // Short circuit if the header is known, or it's parent not 156 number := header.Number.Uint64() 157 if chain.GetHeader(header.Hash(), number) != nil { 158 return nil 159 } 160 parent := chain.GetHeader(header.ParentHash, number-1) 161 if parent == nil { 162 return consensus.ErrUnknownAncestor 163 } 164 // Sanity checks passed, do a proper verification 165 parents := []*types.Header{parent} 166 return ethash.verifyHeader(chain, header, parents, false, seal) 167 } 168 169 func (ethash *Ethash) VerifyPPOWReorg(chain consensus.ChainReader, commonBlock *types.Block, oldChain []*types.Block, newChain []*types.Block) error { 170 s, err := ethash.snapshot(chain, commonBlock.NumberU64(), commonBlock.Hash(), nil) 171 if err != nil { 172 return err 173 } 174 oldSignerSet := make(map[common.Address]struct{}) 175 newSignerSet := make(map[common.Address]struct{}) 176 for signer := range s.UsedSigners { 177 oldSignerSet[signer] = struct{}{} 178 newSignerSet[signer] = struct{}{} 179 } 180 181 for _, b := range oldChain { 182 //using coinbase here, previously checked signature by node or verify headers 183 oldSignerSet[b.Coinbase()] = struct{}{} 184 } 185 186 for _, nb := range newChain { 187 newSignerSet[nb.Coinbase()] = struct{}{} 188 } 189 190 //TODO:PPOW how to make a reasonable choice 191 if len(newSignerSet) < (len(oldSignerSet) - 1) { 192 return errUsedSignerDescend 193 } 194 195 return nil 196 } 197 198 // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers 199 // concurrently. The method returns a quit channel to abort the operations and 200 // a results channel to retrieve the async verifications. 201 func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { 202 // If we're running a full engine faking, accept any input as valid 203 if ethash.config.PowMode == ModeFullFake || len(headers) == 0 { 204 abort, results := make(chan struct{}), make(chan error, len(headers)) 205 for i := 0; i < len(headers); i++ { 206 results <- nil 207 } 208 return abort, results 209 } 210 211 // Spawn as many workers as allowed threads 212 //workers := runtime.GOMAXPROCS(0) 213 workers := 1 214 if len(headers) < workers { 215 workers = len(headers) 216 } 217 218 // Create a task channel and spawn the verifiers 219 var ( 220 inputs = make(chan int) 221 done = make(chan int, workers) 222 errors = make([]error, len(headers)) 223 abort = make(chan struct{}) 224 ) 225 for i := 0; i < workers; i++ { 226 go func() { 227 for index := range inputs { 228 errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index) 229 done <- index 230 } 231 }() 232 } 233 234 errorsOut := make(chan error, len(headers)) 235 go func() { 236 defer close(inputs) 237 var ( 238 in, out = 0, 0 239 checked = make([]bool, len(headers)) 240 inputs = inputs 241 ) 242 for { 243 select { 244 case inputs <- in: 245 if in++; in == len(headers) { 246 // Reached end of headers. Stop sending to workers. 247 inputs = nil 248 } 249 case index := <-done: 250 for checked[index] = true; checked[out]; out++ { 251 errorsOut <- errors[out] 252 if out == len(headers)-1 { 253 return 254 } 255 } 256 case <-abort: 257 return 258 } 259 } 260 }() 261 return abort, errorsOut 262 } 263 264 func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error { 265 var parent *types.Header 266 if index == 0 { 267 parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1) 268 } else if headers[index-1].Hash() == headers[index].ParentHash { 269 parent = headers[index-1] 270 } 271 if parent == nil { 272 return consensus.ErrUnknownAncestor 273 } 274 if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil { 275 return nil // known block 276 } 277 278 var parents []*types.Header 279 if index == 0 { 280 parents = []*types.Header{parent} 281 } else { 282 parents = headers[:index] 283 } 284 return ethash.verifyHeader(chain, headers[index], parents, false, seals[index]) 285 } 286 287 // VerifyUncles verifies that the given block's uncles conform to the consensus 288 // rules of the stock Ethereum ethash engine. 289 func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { 290 // If we're running a full engine faking, accept any input as valid 291 if ethash.config.PowMode == ModeFullFake { 292 return nil 293 } 294 // Verify that there are at most 2 uncles included in this block 295 if len(block.Uncles()) > maxUncles { 296 return errTooManyUncles 297 } 298 // Gather the set of past uncles and ancestors 299 //uncles, ancestors := set.New(), make(map[common.Hash]*types.Header) 300 // 301 //number, parent := block.NumberU64()-1, block.ParentHash() 302 //for i := 0; i < 7; i++ { 303 // ancestor := chain.GetBlock(parent, number) 304 // if ancestor == nil { 305 // break 306 // } 307 // ancestors[ancestor.Hash()] = ancestor.Header() 308 // for _, uncle := range ancestor.Uncles() { 309 // uncles.Add(uncle.Hash()) 310 // } 311 // parent, number = ancestor.ParentHash(), number-1 312 //} 313 //ancestors[block.Hash()] = block.Header() 314 //uncles.Add(block.Hash()) 315 // 316 //// Verify each of the uncles that it's recent, but not an ancestor 317 //for _, uncle := range block.Uncles() { 318 // // Make sure every uncle is rewarded only once 319 // hash := uncle.Hash() 320 // if uncles.Has(hash) { 321 // return errDuplicateUncle 322 // } 323 // uncles.Add(hash) 324 // 325 // // Make sure the uncle has a valid ancestry 326 // if ancestors[hash] != nil { 327 // return errUncleIsAncestor 328 // } 329 // if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() { 330 // return errDanglingUncle 331 // } 332 // //if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true); err != nil { 333 // // return err 334 // //} 335 //} 336 return nil 337 } 338 339 // verifyHeader checks whether a header conforms to the consensus rules of the 340 // stock Ethereum ethash engine. 341 // See YP section 4.3.4. "Block Header Validity" 342 func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header, uncle bool, seal bool) error { 343 if header.Number.Uint64() == 0 { 344 return nil 345 } 346 // Ensure that the header's extra-data section is of a reasonable size 347 parent := parents[len(parents)-1] 348 if uint64(len(header.Extra)) > params.MaximumExtraDataSize { 349 return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize) 350 } 351 if len(header.Extra) != extraVanity+extraSeal { 352 return fmt.Errorf("extra-data size invalid: %d", len(header.Extra)) 353 } 354 // Verify the header's timestamp 355 if uncle { 356 if header.Time.Cmp(math.MaxBig256) > 0 { 357 return errLargeBlockTime 358 } 359 } else { 360 if header.Time.Cmp(big.NewInt(time.Now().Add(allowedFutureBlockTime).Unix())) > 0 { 361 return consensus.ErrFutureBlock 362 } 363 } 364 if header.Time.Cmp(parent.Time) <= 0 { 365 return errZeroBlockTime 366 } 367 // Verify the block's difficulty based in it's timestamp and parent's difficulty 368 expected := ethash.CalcDifficulty(chain, header.Time.Uint64(), parent) 369 370 if expected.Cmp(header.Difficulty) != 0 { 371 return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected) 372 } 373 // Verify that the gas limit is <= 2^63-1 374 cap := uint64(0x7fffffffffffffff) 375 if header.GasLimit.Uint64() > cap { 376 return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap) 377 } 378 // Verify that the gasUsed is <= gasLimit 379 if header.GasUsed.Cmp(header.GasLimit)>0 { 380 return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) 381 } 382 383 // Verify that the gas limit remains within allowed bounds 384 diff := int64(parent.GasLimit.Int64()) - int64(header.GasLimit.Int64()) 385 if diff < 0 { 386 diff *= -1 387 } 388 limit := parent.GasLimit.Uint64() / params.GasLimitBoundDivisor.Uint64() 389 390 if uint64(diff) >= limit || header.GasLimit.Uint64() < params.MinGasLimit.Uint64() { 391 return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) 392 } 393 // Verify that the block number is parent's +1 394 if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 { 395 return consensus.ErrInvalidNumber 396 } 397 // Verify the engine specific seal securing the block 398 if seal { 399 if err := ethash.VerifySeal(chain, header); err != nil { 400 return err 401 } 402 } 403 404 //if seal 405 if err := ethash.verifySignerIdentity(chain, header, parents); err != nil { 406 return err 407 } 408 409 // If all checks passed, validate any special fields for hard forks 410 //if err := misc.VerifyDAOHeaderExtraData(chain.Config(), header); err != nil { 411 // return err 412 //} 413 //if err := misc.VerifyForkHashes(chain.Config(), header, uncle); err != nil { 414 // return err 415 //} 416 417 return nil 418 } 419 420 // CalcDifficulty is the difficulty adjustment algorithm. It returns 421 // the difficulty that a new block should have when created at time 422 // given the parent block's time and difficulty. 423 func (ethash *Ethash) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { 424 return CalcDifficulty(chain.Config(), time, parent) 425 } 426 // TODO (karalabe): Move the chain maker into this package and make this private! 427 func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int { 428 //next := new(big.Int).Add(parent.Number, big1) 429 // 430 switch { 431 //case config.IsByzantium(next): 432 // return calcDifficultyByzantium(time, parent) 433 //case config.IsHomestead(next): 434 // return calcDifficultyHomestead(time, parent) 435 default: 436 //return calcDifficultyFrontier(time, parent) 437 return calcDifficultyByzantium(time, parent) 438 } 439 } 440 441 // verify does current coinbase valid for sign 442 func (self *Ethash) verifySignerIdentity(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error { 443 number := header.Number.Uint64() 444 445 s, err := self.snapshot(chain, number-1, header.ParentHash, parents) 446 if err != nil { 447 return err 448 } 449 450 if err = s.isLegal4Sign(header.Coinbase); err != nil { 451 return err 452 } 453 454 return nil 455 } 456 457 // INFO: copied from consensus/clique/clique.go , mostly 458 // snapshot retrieves the signer status at a given point 459 func (self *Ethash) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) { 460 var ( 461 headers []*types.Header 462 snap *Snapshot 463 ) 464 465 for snap == nil { 466 if s, ok := self.recents.Get(hash); ok { 467 snap = s.(*Snapshot) 468 break 469 } 470 471 if number%checkpointInterval == 0 { 472 if s, err := loadSnapShot(self.db, hash); err == nil { 473 snap = s 474 break 475 } 476 } 477 478 if number == 0 { 479 genesis := chain.GetHeaderByNumber(0) 480 // verify genesis hash match 481 if err := self.VerifyHeader(chain, genesis, false); err != nil { 482 return nil, err 483 } 484 485 signers := make([]common.Address, len(genesis.Extra)/common.AddressLength) 486 for i := 0; i < len(signers); i++ { 487 copy(signers[i][:], genesis.Extra[i*common.AddressLength:]) 488 } 489 snap = newSnapshot(0, genesis.Hash(), signers) 490 if err := snap.store(self.db); err != nil { 491 return nil, err 492 } 493 break 494 } 495 496 var header *types.Header 497 if len(parents) > 0 { 498 header = parents[len(parents)-1] 499 if header.Hash() != hash || header.Number.Uint64() != number { 500 return nil, consensus.ErrUnknownAncestor 501 } 502 parents = parents[:len(parents)-1] 503 } else { 504 header = chain.GetHeader(hash, number) 505 if header == nil { 506 return nil, consensus.ErrUnknownAncestor 507 } 508 } 509 headers = append(headers, header) 510 number, hash = number-1, header.ParentHash 511 } 512 513 for i := 0; i < len(headers)/2; i++ { 514 headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] 515 } 516 517 snap, err := snap.apply(headers) 518 if err != nil { 519 return nil, err 520 } 521 522 self.recents.Add(snap.Hash, snap) 523 524 if snap.Number%checkpointInterval == 0 && len(headers) > 0 { 525 if err = snap.store(self.db); err != nil { 526 return nil, err 527 } 528 log.Trace("Stored ppow snapshot to disk", "number", snap.Number, "hash", snap.Hash) 529 } 530 531 return snap, err 532 } 533 534 // Some weird constants to avoid constant memory allocs for them. 535 var ( 536 expDiffPeriod = big.NewInt(100000) 537 big1 = big.NewInt(1) 538 big2 = big.NewInt(2) 539 big9 = big.NewInt(9) 540 big10 = big.NewInt(10) 541 bigMinus99 = big.NewInt(-99) 542 big2999999 = big.NewInt(2999999) 543 ) 544 545 // calcDifficultyByzantium is the difficulty adjustment algorithm. It returns 546 // the difficulty that a new block should have when created at time given the 547 // parent block's time and difficulty. The calculation uses the Byzantium rules. 548 func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int { 549 // https://github.com/ethereum/EIPs/issues/100. 550 // algorithm: 551 // diff = (parent_diff + 552 // (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) 553 // ) + 2^(periodCount - 2) 554 555 bigTime := new(big.Int).SetUint64(time) 556 bigParentTime := new(big.Int).Set(parent.Time) 557 558 // holds intermediate values to make the algo easier to read & audit 559 x := new(big.Int) 560 y := new(big.Int) 561 562 // (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9 563 x.Sub(bigTime, bigParentTime) 564 x.Div(x, big9) 565 if parent.UncleHash == types.EmptyUncleHash { 566 x.Sub(big1, x) 567 } else { 568 x.Sub(big2, x) 569 } 570 // max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99) 571 if x.Cmp(bigMinus99) < 0 { 572 x.Set(bigMinus99) 573 } 574 // parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) 575 y.Div(parent.Difficulty, params.DifficultyBoundDivisor) 576 x.Mul(y, x) 577 x.Add(parent.Difficulty, x) 578 579 // minimum difficulty can ever be (before exponential factor) 580 if x.Cmp(params.MinimumDifficulty) < 0 { 581 x.Set(params.MinimumDifficulty) 582 } 583 /* 584 // calculate a fake block numer for the ice-age delay: 585 // https://github.com/ethereum/EIPs/pull/669 586 // fake_block_number = min(0, block.number - 3_000_000 587 fakeBlockNumber := new(big.Int) 588 if parent.Number.Cmp(big2999999) >= 0 { 589 fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, big2999999) // Note, parent is 1 less than the actual block number 590 } 591 // for the exponential factor 592 periodCount := fakeBlockNumber 593 periodCount.Div(periodCount, expDiffPeriod) 594 595 // the exponential factor, commonly referred to as "the bomb" 596 // diff = diff + 2^(periodCount - 2) 597 if periodCount.Cmp(big1) > 0 { 598 y.Sub(periodCount, big2) 599 y.Exp(big2, y, nil) 600 x.Add(x, y) 601 } 602 */ 603 return x 604 } 605 606 // calcDifficultyHomestead is the difficulty adjustment algorithm. It returns 607 // the difficulty that a new block should have when created at time given the 608 // parent block's time and difficulty. The calculation uses the Homestead rules. 609 func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int { 610 // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md 611 // algorithm: 612 // diff = (parent_diff + 613 // (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)) 614 // ) + 2^(periodCount - 2) 615 616 bigTime := new(big.Int).SetUint64(time) 617 bigParentTime := new(big.Int).Set(parent.Time) 618 619 // holds intermediate values to make the algo easier to read & audit 620 x := new(big.Int) 621 y := new(big.Int) 622 623 // 1 - (block_timestamp - parent_timestamp) // 10 624 x.Sub(bigTime, bigParentTime) 625 x.Div(x, big10) 626 x.Sub(big1, x) 627 628 // max(1 - (block_timestamp - parent_timestamp) // 10, -99) 629 if x.Cmp(bigMinus99) < 0 { 630 x.Set(bigMinus99) 631 } 632 // (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)) 633 y.Div(parent.Difficulty, params.DifficultyBoundDivisor) 634 x.Mul(y, x) 635 x.Add(parent.Difficulty, x) 636 637 // minimum difficulty can ever be (before exponential factor) 638 if x.Cmp(params.MinimumDifficulty) < 0 { 639 x.Set(params.MinimumDifficulty) 640 } 641 // for the exponential factor 642 periodCount := new(big.Int).Add(parent.Number, big1) 643 periodCount.Div(periodCount, expDiffPeriod) 644 645 // the exponential factor, commonly referred to as "the bomb" 646 // diff = diff + 2^(periodCount - 2) 647 if periodCount.Cmp(big1) > 0 { 648 y.Sub(periodCount, big2) 649 y.Exp(big2, y, nil) 650 x.Add(x, y) 651 } 652 return x 653 } 654 655 // calcDifficultyFrontier is the difficulty adjustment algorithm. It returns the 656 // difficulty that a new block should have when created at time given the parent 657 // block's time and difficulty. The calculation uses the Frontier rules. 658 func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int { 659 diff := new(big.Int) 660 adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor) 661 bigTime := new(big.Int) 662 bigParentTime := new(big.Int) 663 664 bigTime.SetUint64(time) 665 bigParentTime.Set(parent.Time) 666 667 if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 { 668 diff.Add(parent.Difficulty, adjust) 669 } else { 670 diff.Sub(parent.Difficulty, adjust) 671 } 672 if diff.Cmp(params.MinimumDifficulty) < 0 { 673 diff.Set(params.MinimumDifficulty) 674 } 675 676 periodCount := new(big.Int).Add(parent.Number, big1) 677 periodCount.Div(periodCount, expDiffPeriod) 678 if periodCount.Cmp(big1) > 0 { 679 // diff = diff + 2^(periodCount - 2) 680 expDiff := periodCount.Sub(periodCount, big2) 681 expDiff.Exp(big2, expDiff, nil) 682 diff.Add(diff, expDiff) 683 diff = math.BigMax(diff, params.MinimumDifficulty) 684 } 685 return diff 686 } 687 688 // VerifySeal implements consensus.Engine, checking whether the given block satisfies 689 // the PoW difficulty requirements. 690 func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error { 691 // If we're running a fake PoW, accept any seal as valid 692 if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake { 693 time.Sleep(ethash.fakeDelay) 694 if ethash.fakeFail == header.Number.Uint64() { 695 return errInvalidPoW 696 } 697 return nil 698 } 699 700 // If we're running a shared PoW, delegate verification to it 701 if ethash.shared != nil { 702 return ethash.shared.VerifySeal(chain, header) 703 } 704 // Sanity check that the block number is below the lookup table size (60M blocks) 705 number := header.Number.Uint64() 706 if number/epochLength >= maxEpoch { 707 // Go < 1.7 cannot calculate new cache/dataset sizes (no fast prime check) 708 return errNonceOutOfRange 709 } 710 // Ensure that we have a valid difficulty for the block 711 if header.Difficulty.Sign() <= 0 { 712 return errInvalidDifficulty 713 } 714 // Recompute the digest and PoW value and verify against the header 715 cache := ethash.cache(number) 716 717 size := datasetSize(number) 718 if ethash.config.PowMode == ModeTest { 719 size = 32 * 1024 720 } 721 digest, result := hashimotoLight(size, cache.cache, header.HashNoNonce().Bytes(), header.Nonce.Uint64()) 722 // Caches are unmapped in a finalizer. Ensure that the cache stays live 723 // until after the call to hashimotoLight so it's not unmapped while being used. 724 runtime.KeepAlive(cache) 725 726 if !bytes.Equal(header.MixDigest[:], digest) { 727 return errInvalidMixDigest 728 } 729 target := new(big.Int).Div(maxUint256, header.Difficulty) 730 if new(big.Int).SetBytes(result).Cmp(target) > 0 { 731 return errInvalidPoW 732 } 733 return nil 734 } 735 736 // Prepare implements consensus.Engine, initializing the difficulty field of a 737 // header to conform to the ethash protocol. The changes are done inline. 738 func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header, mining bool) error { 739 parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) 740 if parent == nil { 741 return consensus.ErrUnknownAncestor 742 } 743 744 if mining { 745 snap, err := ethash.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil) 746 if err != nil { 747 return err 748 } 749 750 err = snap.isLegal4Sign(header.Coinbase) 751 if err != nil { 752 return err 753 } 754 } 755 756 header.Difficulty = ethash.CalcDifficulty(chain, header.Time.Uint64(), parent) 757 758 if len(header.Extra) < extraVanity { 759 header.Extra = append(header.Extra, make([]byte, extraVanity-len(header.Extra))...) 760 } 761 header.Extra = header.Extra[:extraVanity] 762 header.Extra = append(header.Extra, make([]byte, extraSeal)...) 763 764 return nil 765 } 766 767 // Finalize implements consensus.Engine, accumulating the block and uncle rewards, 768 // setting the final state and assembling the block. 769 func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { 770 // Accumulate any block and uncle rewards and commit the final state root 771 AccumulateRewards(chain.Config(), state, header, uncles) 772 header.Root = state.IntermediateRoot(true /*chain.Config().IsEIP158(header.Number)*/) 773 774 // Header seems complete, assemble into a block and return 775 return types.NewBlock(header, txs, uncles, receipts), nil 776 } 777 778 // Some weird constants to avoid constant memory allocs for them. 779 var ( 780 big8 = big.NewInt(8) 781 big32 = big.NewInt(32) 782 ) 783 784 // AccumulateRewards credits the coinbase of the given block with the mining 785 // reward. The total reward consists of the static block reward and rewards for 786 // included uncles. The coinbase of each uncle block is also rewarded. 787 // TODO (karalabe): Move the chain maker into this package and make this private! 788 func AccumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { 789 //if header.Number.Uint64() == 29900 { 790 // fmt.Println("got 29900") 791 //} 792 // Select the correct block reward based on chain progression 793 //blockReward := frontierBlockReward 794 //if config.IsByzantium(header.Number) { 795 // blockReward := byzantiumBlockReward 796 //} 797 // Accumulate the rewards for the miner and any included uncles 798 //reward := new(big.Int).Set(blockReward) 799 //r := new(big.Int) 800 //for _, uncle := range uncles { 801 // r.Add(uncle.Number, big8) 802 // r.Sub(r, header.Number) 803 // r.Mul(r, blockReward) 804 // r.Div(r, big8) 805 // state.AddBalance(uncle.Coinbase, r) 806 // 807 // r.Div(blockReward, big32) 808 // reward.Add(reward, r) 809 //} 810 //state.AddBalance(header.Coinbase, reward) 811 }