consensus.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. // Copyright 2017 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 ethash
  17. import (
  18. "bytes"
  19. "errors"
  20. "fmt"
  21. "math/big"
  22. "runtime"
  23. "sync/atomic"
  24. "time"
  25. "github.com/ethereum/go-ethereum/common"
  26. "github.com/ethereum/go-ethereum/common/math"
  27. "github.com/ethereum/go-ethereum/consensus"
  28. "github.com/ethereum/go-ethereum/consensus/misc"
  29. "github.com/ethereum/go-ethereum/core/state"
  30. "github.com/ethereum/go-ethereum/core/types"
  31. "github.com/ethereum/go-ethereum/params"
  32. set "gopkg.in/fatih/set.v0"
  33. )
  34. // Ethash proof-of-work protocol constants.
  35. var (
  36. blockReward *big.Int = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
  37. maxUncles = 2 // Maximum number of uncles allowed in a single block
  38. )
  39. var (
  40. ErrInvalidChain = errors.New("invalid header chain")
  41. ErrTooManyUncles = errors.New("too many uncles")
  42. ErrDuplicateUncle = errors.New("duplicate uncle")
  43. ErrUncleIsAncestor = errors.New("uncle is ancestor")
  44. ErrDanglingUncle = errors.New("uncle's parent is not ancestor")
  45. ErrNonceOutOfRange = errors.New("nonce out of range")
  46. ErrInvalidDifficulty = errors.New("non-positive difficulty")
  47. ErrInvalidMixDigest = errors.New("invalid mix digest")
  48. ErrInvalidPoW = errors.New("invalid proof-of-work")
  49. )
  50. // VerifyHeader checks whether a header conforms to the consensus rules of the
  51. // stock Ethereum ethash engine.
  52. func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
  53. // If we're running a full engine faking, accept any input as valid
  54. if ethash.fakeFull {
  55. return nil
  56. }
  57. // Short circuit if the header is known, or it's parent not
  58. number := header.Number.Uint64()
  59. if chain.GetHeader(header.Hash(), number) != nil {
  60. return nil
  61. }
  62. parent := chain.GetHeader(header.ParentHash, number-1)
  63. if parent == nil {
  64. return consensus.ErrUnknownAncestor
  65. }
  66. // Sanity checks passed, do a proper verification
  67. return ethash.verifyHeader(chain, header, parent, false, seal)
  68. }
  69. // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
  70. // concurrently. The method returns a quit channel to abort the operations and
  71. // a results channel to retrieve the async verifications.
  72. func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
  73. // If we're running a full engine faking, accept any input as valid
  74. if ethash.fakeFull {
  75. abort, results := make(chan struct{}), make(chan error, len(headers))
  76. for i := 0; i < len(headers); i++ {
  77. results <- nil
  78. }
  79. return abort, results
  80. }
  81. // Spawn as many workers as allowed threads
  82. workers := runtime.GOMAXPROCS(0)
  83. if len(headers) < workers {
  84. workers = len(headers)
  85. }
  86. // Create a task channel and spawn the verifiers
  87. type result struct {
  88. index int
  89. err error
  90. }
  91. inputs := make(chan int, workers)
  92. outputs := make(chan result, len(headers))
  93. var badblock uint64
  94. for i := 0; i < workers; i++ {
  95. go func() {
  96. for index := range inputs {
  97. // If we've found a bad block already before this, stop validating
  98. if bad := atomic.LoadUint64(&badblock); bad != 0 && bad <= headers[index].Number.Uint64() {
  99. outputs <- result{index: index, err: ErrInvalidChain}
  100. continue
  101. }
  102. // We need to look up the first parent
  103. var parent *types.Header
  104. if index == 0 {
  105. parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
  106. } else if headers[index-1].Hash() == headers[index].ParentHash {
  107. parent = headers[index-1]
  108. }
  109. // Ensure the validation is useful and execute it
  110. var failure error
  111. switch {
  112. case chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()-1) != nil:
  113. outputs <- result{index: index, err: nil}
  114. case parent == nil:
  115. failure = consensus.ErrUnknownAncestor
  116. outputs <- result{index: index, err: failure}
  117. default:
  118. failure = ethash.verifyHeader(chain, headers[index], parent, false, seals[index])
  119. outputs <- result{index: index, err: failure}
  120. }
  121. // If a validation failure occurred, mark subsequent blocks invalid
  122. if failure != nil {
  123. number := headers[index].Number.Uint64()
  124. if prev := atomic.LoadUint64(&badblock); prev == 0 || prev > number {
  125. // This two step atomic op isn't thread-safe in that `badblock` might end
  126. // up slightly higher than the block number of the first failure (if many
  127. // workers try to write at the same time), but it's fine as we're mostly
  128. // interested to avoid large useless work, we don't care about 1-2 extra
  129. // runs. Doing "full thread safety" would involve mutexes, which would be
  130. // a noticeable sync overhead on the fast spinning worker routines.
  131. atomic.StoreUint64(&badblock, number)
  132. }
  133. }
  134. }
  135. }()
  136. }
  137. // Feed item indices to the workers until done, sorting and feeding the results to the caller
  138. dones := make([]bool, len(headers))
  139. errors := make([]error, len(headers))
  140. abort := make(chan struct{})
  141. returns := make(chan error, len(headers))
  142. go func() {
  143. defer close(inputs)
  144. input, output := 0, 0
  145. for i := 0; i < len(headers)*2; i++ {
  146. var res result
  147. // If there are tasks left, push to workers
  148. if input < len(headers) {
  149. select {
  150. case inputs <- input:
  151. input++
  152. continue
  153. case <-abort:
  154. return
  155. case res = <-outputs:
  156. }
  157. } else {
  158. // Otherwise keep waiting for results
  159. select {
  160. case <-abort:
  161. return
  162. case res = <-outputs:
  163. }
  164. }
  165. // A result arrived, save and propagate if next
  166. dones[res.index], errors[res.index] = true, res.err
  167. for output < len(headers) && dones[output] {
  168. returns <- errors[output]
  169. output++
  170. }
  171. }
  172. }()
  173. return abort, returns
  174. }
  175. // VerifyUncles verifies that the given block's uncles conform to the consensus
  176. // rules of the stock Ethereum ethash engine.
  177. func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
  178. // If we're running a full engine faking, accept any input as valid
  179. if ethash.fakeFull {
  180. return nil
  181. }
  182. // Verify that there are at most 2 uncles included in this block
  183. if len(block.Uncles()) > maxUncles {
  184. return ErrTooManyUncles
  185. }
  186. // Gather the set of past uncles and ancestors
  187. uncles, ancestors := set.New(), make(map[common.Hash]*types.Header)
  188. number, parent := block.NumberU64()-1, block.ParentHash()
  189. for i := 0; i < 7; i++ {
  190. ancestor := chain.GetBlock(parent, number)
  191. if ancestor == nil {
  192. break
  193. }
  194. ancestors[ancestor.Hash()] = ancestor.Header()
  195. for _, uncle := range ancestor.Uncles() {
  196. uncles.Add(uncle.Hash())
  197. }
  198. parent, number = ancestor.ParentHash(), number-1
  199. }
  200. ancestors[block.Hash()] = block.Header()
  201. uncles.Add(block.Hash())
  202. // Verify each of the uncles that it's recent, but not an ancestor
  203. for _, uncle := range block.Uncles() {
  204. // Make sure every uncle is rewarded only once
  205. hash := uncle.Hash()
  206. if uncles.Has(hash) {
  207. return ErrDuplicateUncle
  208. }
  209. uncles.Add(hash)
  210. // Make sure the uncle has a valid ancestry
  211. if ancestors[hash] != nil {
  212. return ErrUncleIsAncestor
  213. }
  214. if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() {
  215. return ErrDanglingUncle
  216. }
  217. if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true); err != nil {
  218. return err
  219. }
  220. }
  221. return nil
  222. }
  223. // verifyHeader checks whether a header conforms to the consensus rules of the
  224. // stock Ethereum ethash engine.
  225. //
  226. // See YP section 4.3.4. "Block Header Validity"
  227. func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *types.Header, uncle bool, seal bool) error {
  228. // Ensure that the header's extra-data section is of a reasonable size
  229. if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
  230. return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize)
  231. }
  232. // Verify the header's timestamp
  233. if uncle {
  234. if header.Time.Cmp(math.MaxBig256) > 0 {
  235. return consensus.ErrLargeBlockTime
  236. }
  237. } else {
  238. if header.Time.Cmp(big.NewInt(time.Now().Unix())) > 0 {
  239. return consensus.ErrFutureBlock
  240. }
  241. }
  242. if header.Time.Cmp(parent.Time) <= 0 {
  243. return consensus.ErrZeroBlockTime
  244. }
  245. // Verify the block's difficulty based in it's timestamp and parent's difficulty
  246. expected := CalcDifficulty(chain.Config(), header.Time.Uint64(), parent.Time.Uint64(), parent.Number, parent.Difficulty)
  247. if expected.Cmp(header.Difficulty) != 0 {
  248. return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
  249. }
  250. // Verify that the gas limit remains within allowed bounds
  251. diff := new(big.Int).Set(parent.GasLimit)
  252. diff = diff.Sub(diff, header.GasLimit)
  253. diff.Abs(diff)
  254. limit := new(big.Int).Set(parent.GasLimit)
  255. limit = limit.Div(limit, params.GasLimitBoundDivisor)
  256. if diff.Cmp(limit) >= 0 || header.GasLimit.Cmp(params.MinGasLimit) < 0 {
  257. return fmt.Errorf("invalid gas limit: have %v, want %v += %v", header.GasLimit, parent.GasLimit, limit)
  258. }
  259. // Verify that the block number is parent's +1
  260. if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
  261. return consensus.ErrInvalidNumber
  262. }
  263. // Verify the engine specific seal securing the block
  264. if seal {
  265. if err := ethash.VerifySeal(chain, header); err != nil {
  266. return err
  267. }
  268. }
  269. // If all checks passed, validate any special fields for hard forks
  270. if err := misc.VerifyDAOHeaderExtraData(chain.Config(), header); err != nil {
  271. return err
  272. }
  273. if err := misc.VerifyForkHashes(chain.Config(), header, uncle); err != nil {
  274. return err
  275. }
  276. return nil
  277. }
  278. // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
  279. // that a new block should have when created at time given the parent block's time
  280. // and difficulty.
  281. //
  282. // TODO (karalabe): Move the chain maker into this package and make this private!
  283. func CalcDifficulty(config *params.ChainConfig, time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
  284. if config.IsHomestead(new(big.Int).Add(parentNumber, common.Big1)) {
  285. return calcDifficultyHomestead(time, parentTime, parentNumber, parentDiff)
  286. }
  287. return calcDifficultyFrontier(time, parentTime, parentNumber, parentDiff)
  288. }
  289. // Some weird constants to avoid constant memory allocs for them.
  290. var (
  291. expDiffPeriod = big.NewInt(100000)
  292. big10 = big.NewInt(10)
  293. bigMinus99 = big.NewInt(-99)
  294. )
  295. // calcDifficultyHomestead is the difficulty adjustment algorithm. It returns
  296. // the difficulty that a new block should have when created at time given the
  297. // parent block's time and difficulty. The calculation uses the Homestead rules.
  298. func calcDifficultyHomestead(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
  299. // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki
  300. // algorithm:
  301. // diff = (parent_diff +
  302. // (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
  303. // ) + 2^(periodCount - 2)
  304. bigTime := new(big.Int).SetUint64(time)
  305. bigParentTime := new(big.Int).SetUint64(parentTime)
  306. // holds intermediate values to make the algo easier to read & audit
  307. x := new(big.Int)
  308. y := new(big.Int)
  309. // 1 - (block_timestamp -parent_timestamp) // 10
  310. x.Sub(bigTime, bigParentTime)
  311. x.Div(x, big10)
  312. x.Sub(common.Big1, x)
  313. // max(1 - (block_timestamp - parent_timestamp) // 10, -99)))
  314. if x.Cmp(bigMinus99) < 0 {
  315. x.Set(bigMinus99)
  316. }
  317. // (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
  318. y.Div(parentDiff, params.DifficultyBoundDivisor)
  319. x.Mul(y, x)
  320. x.Add(parentDiff, x)
  321. // minimum difficulty can ever be (before exponential factor)
  322. if x.Cmp(params.MinimumDifficulty) < 0 {
  323. x.Set(params.MinimumDifficulty)
  324. }
  325. // for the exponential factor
  326. periodCount := new(big.Int).Add(parentNumber, common.Big1)
  327. periodCount.Div(periodCount, expDiffPeriod)
  328. // the exponential factor, commonly referred to as "the bomb"
  329. // diff = diff + 2^(periodCount - 2)
  330. if periodCount.Cmp(common.Big1) > 0 {
  331. y.Sub(periodCount, common.Big2)
  332. y.Exp(common.Big2, y, nil)
  333. x.Add(x, y)
  334. }
  335. return x
  336. }
  337. // calcDifficultyFrontier is the difficulty adjustment algorithm. It returns the
  338. // difficulty that a new block should have when created at time given the parent
  339. // block's time and difficulty. The calculation uses the Frontier rules.
  340. func calcDifficultyFrontier(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
  341. diff := new(big.Int)
  342. adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
  343. bigTime := new(big.Int)
  344. bigParentTime := new(big.Int)
  345. bigTime.SetUint64(time)
  346. bigParentTime.SetUint64(parentTime)
  347. if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 {
  348. diff.Add(parentDiff, adjust)
  349. } else {
  350. diff.Sub(parentDiff, adjust)
  351. }
  352. if diff.Cmp(params.MinimumDifficulty) < 0 {
  353. diff.Set(params.MinimumDifficulty)
  354. }
  355. periodCount := new(big.Int).Add(parentNumber, common.Big1)
  356. periodCount.Div(periodCount, expDiffPeriod)
  357. if periodCount.Cmp(common.Big1) > 0 {
  358. // diff = diff + 2^(periodCount - 2)
  359. expDiff := periodCount.Sub(periodCount, common.Big2)
  360. expDiff.Exp(common.Big2, expDiff, nil)
  361. diff.Add(diff, expDiff)
  362. diff = math.BigMax(diff, params.MinimumDifficulty)
  363. }
  364. return diff
  365. }
  366. // VerifySeal implements consensus.Engine, checking whether the given block satisfies
  367. // the PoW difficulty requirements.
  368. func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
  369. // If we're running a fake PoW, accept any seal as valid
  370. if ethash.fakeMode {
  371. time.Sleep(ethash.fakeDelay)
  372. if ethash.fakeFail == header.Number.Uint64() {
  373. return ErrInvalidPoW
  374. }
  375. return nil
  376. }
  377. // If we're running a shared PoW, delegate verification to it
  378. if ethash.shared != nil {
  379. return ethash.shared.VerifySeal(chain, header)
  380. }
  381. // Sanity check that the block number is below the lookup table size (60M blocks)
  382. number := header.Number.Uint64()
  383. if number/epochLength >= uint64(len(cacheSizes)) {
  384. // Go < 1.7 cannot calculate new cache/dataset sizes (no fast prime check)
  385. return ErrNonceOutOfRange
  386. }
  387. // Ensure that we have a valid difficulty for the block
  388. if header.Difficulty.Sign() <= 0 {
  389. return ErrInvalidDifficulty
  390. }
  391. // Recompute the digest and PoW value and verify against the header
  392. cache := ethash.cache(number)
  393. size := datasetSize(number)
  394. if ethash.tester {
  395. size = 32 * 1024
  396. }
  397. digest, result := hashimotoLight(size, cache, header.HashNoNonce().Bytes(), header.Nonce.Uint64())
  398. if !bytes.Equal(header.MixDigest[:], digest) {
  399. return ErrInvalidMixDigest
  400. }
  401. target := new(big.Int).Div(maxUint256, header.Difficulty)
  402. if new(big.Int).SetBytes(result).Cmp(target) > 0 {
  403. return ErrInvalidPoW
  404. }
  405. return nil
  406. }
  407. // Prepare implements consensus.Engine, initializing the difficulty field of a
  408. // header to conform to the ethash protocol. The changes are done inline.
  409. func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) error {
  410. parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
  411. if parent == nil {
  412. return consensus.ErrUnknownAncestor
  413. }
  414. header.Difficulty = CalcDifficulty(chain.Config(), header.Time.Uint64(),
  415. parent.Time.Uint64(), parent.Number, parent.Difficulty)
  416. return nil
  417. }
  418. // Finalize implements consensus.Engine, accumulating the block and uncle rewards,
  419. // setting the final state and assembling the block.
  420. 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) {
  421. // Accumulate any block and uncle rewards and commit the final state root
  422. AccumulateRewards(state, header, uncles)
  423. header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
  424. // Header seems complete, assemble into a block and return
  425. return types.NewBlock(header, txs, uncles, receipts), nil
  426. }
  427. // Some weird constants to avoid constant memory allocs for them.
  428. var (
  429. big8 = big.NewInt(8)
  430. big32 = big.NewInt(32)
  431. )
  432. // AccumulateRewards credits the coinbase of the given block with the mining
  433. // reward. The total reward consists of the static block reward and rewards for
  434. // included uncles. The coinbase of each uncle block is also rewarded.
  435. //
  436. // TODO (karalabe): Move the chain maker into this package and make this private!
  437. func AccumulateRewards(state *state.StateDB, header *types.Header, uncles []*types.Header) {
  438. reward := new(big.Int).Set(blockReward)
  439. r := new(big.Int)
  440. for _, uncle := range uncles {
  441. r.Add(uncle.Number, big8)
  442. r.Sub(r, header.Number)
  443. r.Mul(r, blockReward)
  444. r.Div(r, big8)
  445. state.AddBalance(uncle.Coinbase, r)
  446. r.Div(blockReward, big32)
  447. reward.Add(reward, r)
  448. }
  449. state.AddBalance(header.Coinbase, reward)
  450. }