git.pirl.io/community/pirl@v0.0.0-20201111064343-9d3d31ff74be/consensus/ethash/consensus.go (about) 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 17 package ethash 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "errors" 23 "fmt" 24 "math/big" 25 "runtime" 26 "time" 27 28 mapset "github.com/deckarep/golang-set" 29 "git.pirl.io/community/pirl/common" 30 "git.pirl.io/community/pirl/common/math" 31 "git.pirl.io/community/pirl/consensus" 32 "git.pirl.io/community/pirl/consensus/misc" 33 "git.pirl.io/community/pirl/core/state" 34 "git.pirl.io/community/pirl/core/types" 35 "git.pirl.io/community/pirl/params" 36 "git.pirl.io/community/pirl/rlp" 37 "golang.org/x/crypto/sha3" 38 EthLog "git.pirl.io/community/pirl/log" 39 ) 40 41 // Ethash proof-of-work protocol constants. 42 var ( 43 FrontierBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block 44 ByzantiumBlockReward = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium 45 ConstantinopleBlockReward = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople 46 ResetEthDevAddress *big.Int = new(big.Int).Mul(big.NewInt(10), big.NewInt(0)) 47 ResetFithyOneAddress *big.Int = new(big.Int).Mul(big.NewInt(10), big.NewInt(0)) 48 blockReward *big.Int = new(big.Int).Mul(big.NewInt(10), big.NewInt(1e+18)) 49 devreward *big.Int = new(big.Int).Mul(big.NewInt(1), big.NewInt(1e+18)) 50 nodereward *big.Int = new(big.Int).Mul(big.NewInt(1), big.NewInt(1e+18)) 51 SuperblockReward *big.Int = new(big.Int).Mul(big.NewInt(2000000), big.NewInt(1e+18)) 52 maxUncles = 2 // Maximum number of uncles allowed in a single block 53 allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks 54 55 // calcDifficultyEip2384 is the difficulty adjustment algorithm as specified by EIP 2384. 56 // It offsets the bomb 4M blocks from Constantinople, so in total 9M blocks. 57 // Specification EIP-2384: https://eips.ethereum.org/EIPS/eip-2384 58 calcDifficultyEip2384 = makeDifficultyCalculator(big.NewInt(9000000)) 59 60 // calcDifficultyConstantinople is the difficulty adjustment algorithm for Constantinople. 61 // It returns the difficulty that a new block should have when created at time given the 62 // parent block's time and difficulty. The calculation uses the Byzantium rules, but with 63 // bomb offset 5M. 64 // Specification EIP-1234: https://eips.ethereum.org/EIPS/eip-1234 65 calcDifficultyConstantinople = makeDifficultyCalculator(big.NewInt(5000000)) 66 67 // calcDifficultyByzantium is the difficulty adjustment algorithm. It returns 68 // the difficulty that a new block should have when created at time given the 69 // parent block's time and difficulty. The calculation uses the Byzantium rules. 70 // Specification EIP-649: https://eips.ethereum.org/EIPS/eip-649 71 //calcDifficultyByzantium = makeDifficultyCalculator(big.NewInt(3000000)) 72 ) 73 74 // Various error messages to mark blocks invalid. These should be private to 75 // prevent engine specific errors from being referenced in the remainder of the 76 // codebase, inherently breaking if the engine is swapped out. Please put common 77 // error types into the consensus package. 78 var ( 79 errOlderBlockTime = errors.New("timestamp older than parent") 80 errTooManyUncles = errors.New("too many uncles") 81 errDuplicateUncle = errors.New("duplicate uncle") 82 errUncleIsAncestor = errors.New("uncle is ancestor") 83 errDanglingUncle = errors.New("uncle's parent is not ancestor") 84 errInvalidDifficulty = errors.New("non-positive difficulty") 85 errInvalidMixDigest = errors.New("invalid mix digest") 86 errInvalidPoW = errors.New("invalid proof-of-work") 87 ) 88 89 // reset address 90 91 var f interface{} 92 var g interface{} 93 94 // Author implements consensus.Engine, returning the header's coinbase as the 95 // proof-of-work verified author of the block. 96 func (ethash *Ethash) Author(header *types.Header) (common.Address, error) { 97 return header.Coinbase, nil 98 } 99 100 // VerifyHeader checks whether a header conforms to the consensus rules of the 101 // stock Ethereum ethash engine. 102 func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error { 103 // If we're running a full engine faking, accept any input as valid 104 if ethash.config.PowMode == ModeFullFake { 105 return nil 106 } 107 // Short circuit if the header is known, or its parent not 108 number := header.Number.Uint64() 109 if chain.GetHeader(header.Hash(), number) != nil { 110 return nil 111 } 112 parent := chain.GetHeader(header.ParentHash, number-1) 113 if parent == nil { 114 return consensus.ErrUnknownAncestor 115 } 116 // Sanity checks passed, do a proper verification 117 return ethash.verifyHeader(chain, header, parent, false, seal) 118 } 119 120 // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers 121 // concurrently. The method returns a quit channel to abort the operations and 122 // a results channel to retrieve the async verifications. 123 func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { 124 // If we're running a full engine faking, accept any input as valid 125 if ethash.config.PowMode == ModeFullFake || len(headers) == 0 { 126 abort, results := make(chan struct{}), make(chan error, len(headers)) 127 for i := 0; i < len(headers); i++ { 128 results <- nil 129 } 130 return abort, results 131 } 132 133 // Spawn as many workers as allowed threads 134 workers := runtime.GOMAXPROCS(0) 135 if len(headers) < workers { 136 workers = len(headers) 137 } 138 139 // Create a task channel and spawn the verifiers 140 var ( 141 inputs = make(chan int) 142 done = make(chan int, workers) 143 errors = make([]error, len(headers)) 144 abort = make(chan struct{}) 145 ) 146 for i := 0; i < workers; i++ { 147 go func() { 148 for index := range inputs { 149 errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index) 150 done <- index 151 } 152 }() 153 } 154 155 errorsOut := make(chan error, len(headers)) 156 go func() { 157 defer close(inputs) 158 var ( 159 in, out = 0, 0 160 checked = make([]bool, len(headers)) 161 inputs = inputs 162 ) 163 for { 164 select { 165 case inputs <- in: 166 if in++; in == len(headers) { 167 // Reached end of headers. Stop sending to workers. 168 inputs = nil 169 } 170 case index := <-done: 171 for checked[index] = true; checked[out]; out++ { 172 errorsOut <- errors[out] 173 if out == len(headers)-1 { 174 return 175 } 176 } 177 case <-abort: 178 return 179 } 180 } 181 }() 182 return abort, errorsOut 183 } 184 185 func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error { 186 var parent *types.Header 187 if index == 0 { 188 parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1) 189 } else if headers[index-1].Hash() == headers[index].ParentHash { 190 parent = headers[index-1] 191 } 192 if parent == nil { 193 return consensus.ErrUnknownAncestor 194 } 195 if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil { 196 return nil // known block 197 } 198 return ethash.verifyHeader(chain, headers[index], parent, false, seals[index]) 199 } 200 201 // VerifyUncles verifies that the given block's uncles conform to the consensus 202 // rules of the stock Ethereum ethash engine. 203 func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { 204 // If we're running a full engine faking, accept any input as valid 205 if ethash.config.PowMode == ModeFullFake { 206 return nil 207 } 208 // Verify that there are at most 2 uncles included in this block 209 if len(block.Uncles()) > maxUncles { 210 return errTooManyUncles 211 } 212 if len(block.Uncles()) == 0 { 213 return nil 214 } 215 // Gather the set of past uncles and ancestors 216 uncles, ancestors := mapset.NewSet(), make(map[common.Hash]*types.Header) 217 218 number, parent := block.NumberU64()-1, block.ParentHash() 219 for i := 0; i < 7; i++ { 220 ancestor := chain.GetBlock(parent, number) 221 if ancestor == nil { 222 break 223 } 224 ancestors[ancestor.Hash()] = ancestor.Header() 225 for _, uncle := range ancestor.Uncles() { 226 uncles.Add(uncle.Hash()) 227 } 228 parent, number = ancestor.ParentHash(), number-1 229 } 230 ancestors[block.Hash()] = block.Header() 231 uncles.Add(block.Hash()) 232 233 // Verify each of the uncles that it's recent, but not an ancestor 234 for _, uncle := range block.Uncles() { 235 // Make sure every uncle is rewarded only once 236 hash := uncle.Hash() 237 if uncles.Contains(hash) { 238 return errDuplicateUncle 239 } 240 uncles.Add(hash) 241 242 // Make sure the uncle has a valid ancestry 243 if ancestors[hash] != nil { 244 return errUncleIsAncestor 245 } 246 if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() { 247 return errDanglingUncle 248 } 249 if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true); err != nil { 250 return err 251 } 252 } 253 return nil 254 } 255 256 // verifyHeader checks whether a header conforms to the consensus rules of the 257 // stock Ethereum ethash engine. 258 // See YP section 4.3.4. "Block Header Validity" 259 func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *types.Header, uncle bool, seal bool) error { 260 // Ensure that the header's extra-data section is of a reasonable size 261 if uint64(len(header.Extra)) > params.MaximumExtraDataSize { 262 return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize) 263 } 264 // Verify the header's timestamp 265 if !uncle { 266 if header.Time > uint64(time.Now().Add(allowedFutureBlockTime).Unix()) { 267 return consensus.ErrFutureBlock 268 } 269 } 270 if header.Time <= parent.Time { 271 return errOlderBlockTime 272 } 273 // Verify the block's difficulty based on its timestamp and parent's difficulty 274 expected := ethash.CalcDifficulty(chain, header.Time, parent) 275 276 if expected.Cmp(header.Difficulty) != 0 { 277 return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected) 278 } 279 // Verify that the gas limit is <= 2^63-1 280 cap := uint64(0x7fffffffffffffff) 281 if header.GasLimit > cap { 282 return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap) 283 } 284 // Verify that the gasUsed is <= gasLimit 285 if header.GasUsed > header.GasLimit { 286 return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) 287 } 288 289 // Verify that the gas limit remains within allowed bounds 290 diff := int64(parent.GasLimit) - int64(header.GasLimit) 291 if diff < 0 { 292 diff *= -1 293 } 294 limit := parent.GasLimit / params.GasLimitBoundDivisor 295 296 if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit { 297 return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) 298 } 299 // Verify that the block number is parent's +1 300 if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 { 301 return consensus.ErrInvalidNumber 302 } 303 // Verify the engine specific seal securing the block 304 if seal { 305 if err := ethash.VerifySeal(chain, header); err != nil { 306 return err 307 } 308 } 309 // If all checks passed, validate any special fields for hard forks 310 if err := misc.VerifyDAOHeaderExtraData(chain.Config(), header); err != nil { 311 return err 312 } 313 if err := misc.VerifyForkHashes(chain.Config(), header, uncle); err != nil { 314 return err 315 } 316 return nil 317 } 318 319 // CalcDifficulty is the difficulty adjustment algorithm. It returns 320 // the difficulty that a new block should have when created at time 321 // given the parent block's time and difficulty. 322 func (ethash *Ethash) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { 323 return CalcDifficulty(chain.Config(), time, parent) 324 325 } 326 327 // CalcDifficulty is the difficulty adjustment algorithm. It returns 328 // the difficulty that a new block should have when created at time 329 // given the parent block's time and difficulty. 330 func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int { 331 next := new(big.Int).Add(parent.Number, big1) 332 switch { 333 case isForked(big.NewInt(2000001), next): 334 if parent.Number.Int64() > params.PirlGuardActivationBlock { 335 if config.IsIstanbul(next) { 336 return calcDifficultyPirlv2(time, parent) 337 } else { 338 return calcDifficultyByzantium(time, parent) 339 } 340 } else { 341 return calcDifficultyPirl(time, parent) 342 } 343 //case config.IsByzantium(next): 344 // return calcDifficultyByzantium(time, parent) 345 case config.IsHomestead(next): 346 return calcDifficultyHomestead(time, parent) 347 default: 348 return calcDifficultyFrontier(time, parent) 349 } 350 351 } 352 353 func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int { 354 // https://github.com/ethereum/EIPs/issues/100. 355 // algorithm: 356 // diff = (parent_diff + 357 // (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) 358 // ) + 2^(periodCount - 2) 359 360 bigTime := new(big.Int).SetUint64(time) 361 i := new(big.Int).SetUint64(parent.Time) 362 bigParentTime := new(big.Int).Set(i) 363 364 365 // holds intermediate values to make the algo easier to read & audit 366 x := new(big.Int) 367 y := new(big.Int) 368 369 // (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9 370 x.Sub(bigTime, bigParentTime) 371 x.Div(x, big9) 372 if parent.UncleHash == types.EmptyUncleHash { 373 x.Sub(big1, x) 374 } else { 375 x.Sub(big2, x) 376 } 377 // max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99) 378 if x.Cmp(bigMinus99) < 0 { 379 x.Set(bigMinus99) 380 } 381 // parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) 382 y.Div(parent.Difficulty, params.DifficultyBoundDivisor) 383 x.Mul(y, x) 384 x.Add(parent.Difficulty, x) 385 386 // minimum difficulty can ever be (before exponential factor) 387 if x.Cmp(params.MinimumDifficulty) < 0 { 388 x.Set(params.MinimumDifficulty) 389 } 390 // calculate a fake block numer for the ice-age delay: 391 // https://github.com/ethereum/EIPs/pull/669 392 // fake_block_number = min(0, block.number - 3_000_000 393 fakeBlockNumber := new(big.Int) 394 if parent.Number.Cmp(big2999999) >= 0 { 395 fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, big2999999) // Note, parent is 1 less than the actual block number 396 } 397 // for the exponential factor 398 periodCount := fakeBlockNumber 399 periodCount.Div(periodCount, expDiffPeriod) 400 401 // the exponential factor, commonly referred to as "the bomb" 402 // diff = diff + 2^(periodCount - 2) 403 if periodCount.Cmp(big1) > 0 { 404 y.Sub(periodCount, big2) 405 y.Exp(big2, y, nil) 406 x.Add(x, y) 407 } 408 return x 409 } 410 411 412 // Some weird constants to avoid constant memory allocs for them. 413 var ( 414 expDiffPeriod = big.NewInt(100000) 415 big1 = big.NewInt(1) 416 big2 = big.NewInt(2) 417 big9 = big.NewInt(8) 418 big10 = big.NewInt(10) 419 bigMinus99 = big.NewInt(-99) 420 big2999999 = big.NewInt(2999999) 421 big9hulk = big.NewInt(7) // previous is 6 422 bigMinus99hulk = big.NewInt(-99) 423 big2999999hulk = big.NewInt(29999999) 424 425 426 ) 427 428 429 func isForked(s, head *big.Int) bool { 430 if s == nil || head == nil { 431 return false 432 } 433 return s.Cmp(head) <= 0 434 } 435 436 437 // makeDifficultyCalculator creates a difficultyCalculator with the given bomb-delay. 438 // the difficulty is calculated with Byzantium rules, which differs from Homestead in 439 // how uncles affect the calculation 440 func makeDifficultyCalculator(bombDelay *big.Int) func(time uint64, parent *types.Header) *big.Int { 441 // Note, the calculations below looks at the parent number, which is 1 below 442 // the block number. Thus we remove one from the delay given 443 bombDelayFromParent := new(big.Int).Sub(bombDelay, big1) 444 return func(time uint64, parent *types.Header) *big.Int { 445 // https://github.com/ethereum/EIPs/issues/100. 446 // algorithm: 447 // diff = (parent_diff + 448 // (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) 449 // ) + 2^(periodCount - 2) 450 451 bigTime := new(big.Int).SetUint64(time) 452 bigParentTime := new(big.Int).SetUint64(parent.Time) 453 454 // holds intermediate values to make the algo easier to read & audit 455 x := new(big.Int) 456 y := new(big.Int) 457 458 // (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9 459 x.Sub(bigTime, bigParentTime) 460 x.Div(x, big9) 461 if parent.UncleHash == types.EmptyUncleHash { 462 x.Sub(big1, x) 463 } else { 464 x.Sub(big2, x) 465 } 466 // max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99) 467 if x.Cmp(bigMinus99) < 0 { 468 x.Set(bigMinus99) 469 } 470 // parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) 471 y.Div(parent.Difficulty, params.DifficultyBoundDivisor) 472 x.Mul(y, x) 473 x.Add(parent.Difficulty, x) 474 475 // minimum difficulty can ever be (before exponential factor) 476 if x.Cmp(params.MinimumDifficulty) < 0 { 477 x.Set(params.MinimumDifficulty) 478 } 479 // calculate a fake block number for the ice-age delay 480 // Specification: https://eips.ethereum.org/EIPS/eip-1234 481 fakeBlockNumber := new(big.Int) 482 if parent.Number.Cmp(bombDelayFromParent) >= 0 { 483 fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, bombDelayFromParent) 484 } 485 // for the exponential factor 486 periodCount := fakeBlockNumber 487 periodCount.Div(periodCount, expDiffPeriod) 488 489 // the exponential factor, commonly referred to as "the bomb" 490 // diff = diff + 2^(periodCount - 2) 491 if periodCount.Cmp(big1) > 0 { 492 y.Sub(periodCount, big2) 493 y.Exp(big2, y, nil) 494 x.Add(x, y) 495 } 496 return x 497 } 498 } 499 500 501 func calcDifficultyPirl(time uint64, parent *types.Header) *big.Int { 502 diff := new(big.Int) 503 adjust := new(big.Int).Div(parent.Difficulty, big10) 504 bigTime := new(big.Int) 505 bigParentTime := new(big.Int) 506 507 bigTime.SetUint64(time) 508 i := new(big.Int).SetUint64(parent.Time) 509 bigParentTime.Set(i) 510 if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 { 511 diff.Add(parent.Difficulty, adjust) 512 } else { 513 diff.Sub(parent.Difficulty, adjust) 514 } 515 if diff.Cmp(params.MinimumDifficulty) < 0 { 516 diff.Set(params.MinimumDifficulty) 517 } 518 //fmt.Println(diff) 519 return diff 520 } 521 522 523 524 // calcDifficultyHomestead is the difficulty adjustment algorithm. It returns 525 // the difficulty that a new block should have when created at time given the 526 // parent block's time and difficulty. The calculation uses the Homestead rules. 527 func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int { 528 // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md 529 // algorithm: 530 // diff = (parent_diff + 531 // (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)) 532 // ) + 2^(periodCount - 2) 533 534 bigTime := new(big.Int).SetUint64(time) 535 bigParentTime := new(big.Int).SetUint64(parent.Time) 536 537 // holds intermediate values to make the algo easier to read & audit 538 x := new(big.Int) 539 y := new(big.Int) 540 541 // 1 - (block_timestamp - parent_timestamp) // 10 542 x.Sub(bigTime, bigParentTime) 543 x.Div(x, big10) 544 x.Sub(big1, x) 545 546 // max(1 - (block_timestamp - parent_timestamp) // 10, -99) 547 if x.Cmp(bigMinus99) < 0 { 548 x.Set(bigMinus99) 549 } 550 // (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99)) 551 y.Div(parent.Difficulty, params.DifficultyBoundDivisor) 552 x.Mul(y, x) 553 x.Add(parent.Difficulty, x) 554 555 // minimum difficulty can ever be (before exponential factor) 556 if x.Cmp(params.MinimumDifficulty) < 0 { 557 x.Set(params.MinimumDifficulty) 558 } 559 // for the exponential factor 560 periodCount := new(big.Int).Add(parent.Number, big1) 561 periodCount.Div(periodCount, expDiffPeriod) 562 563 // the exponential factor, commonly referred to as "the bomb" 564 // diff = diff + 2^(periodCount - 2) 565 if periodCount.Cmp(big1) > 0 { 566 y.Sub(periodCount, big2) 567 y.Exp(big2, y, nil) 568 x.Add(x, y) 569 } 570 return x 571 } 572 573 // calcDifficultyFrontier is the difficulty adjustment algorithm. It returns the 574 // difficulty that a new block should have when created at time given the parent 575 // block's time and difficulty. The calculation uses the Frontier rules. 576 func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int { 577 diff := new(big.Int) 578 adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor) 579 bigTime := new(big.Int) 580 bigParentTime := new(big.Int) 581 582 bigTime.SetUint64(time) 583 bigParentTime.SetUint64(parent.Time) 584 585 if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 { 586 diff.Add(parent.Difficulty, adjust) 587 } else { 588 diff.Sub(parent.Difficulty, adjust) 589 } 590 if diff.Cmp(params.MinimumDifficulty) < 0 { 591 diff.Set(params.MinimumDifficulty) 592 } 593 594 periodCount := new(big.Int).Add(parent.Number, big1) 595 periodCount.Div(periodCount, expDiffPeriod) 596 if periodCount.Cmp(big1) > 0 { 597 // diff = diff + 2^(periodCount - 2) 598 expDiff := periodCount.Sub(periodCount, big2) 599 expDiff.Exp(big2, expDiff, nil) 600 diff.Add(diff, expDiff) 601 diff = math.BigMax(diff, params.MinimumDifficulty) 602 } 603 return diff 604 } 605 606 // VerifySeal implements consensus.Engine, checking whether the given block satisfies 607 // the PoW difficulty requirements. 608 func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Header) error { 609 return ethash.verifySeal(chain, header, false) 610 } 611 612 // verifySeal checks whether a block satisfies the PoW difficulty requirements, 613 // either using the usual ethash cache for it, or alternatively using a full DAG 614 // to make remote mining fast. 615 func (ethash *Ethash) verifySeal(chain consensus.ChainReader, header *types.Header, fulldag bool) error { 616 // If we're running a fake PoW, accept any seal as valid 617 if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake { 618 time.Sleep(ethash.fakeDelay) 619 if ethash.fakeFail == header.Number.Uint64() { 620 return errInvalidPoW 621 } 622 return nil 623 } 624 // If we're running a shared PoW, delegate verification to it 625 if ethash.shared != nil { 626 return ethash.shared.verifySeal(chain, header, fulldag) 627 } 628 // Ensure that we have a valid difficulty for the block 629 if header.Difficulty.Sign() <= 0 { 630 return errInvalidDifficulty 631 } 632 // Recompute the digest and PoW values 633 number := header.Number.Uint64() 634 635 var ( 636 digest []byte 637 result []byte 638 ) 639 // If fast-but-heavy PoW verification was requested, use an ethash dataset 640 if fulldag { 641 dataset := ethash.dataset(number, true) 642 if dataset.generated() { 643 digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) 644 645 // Datasets are unmapped in a finalizer. Ensure that the dataset stays alive 646 // until after the call to hashimotoFull so it's not unmapped while being used. 647 runtime.KeepAlive(dataset) 648 } else { 649 // Dataset not yet generated, don't hang, use a cache instead 650 fulldag = false 651 } 652 } 653 // If slow-but-light PoW verification was requested (or DAG not yet ready), use an ethash cache 654 if !fulldag { 655 cache := ethash.cache(number) 656 657 size := datasetSize(number) 658 if ethash.config.PowMode == ModeTest { 659 size = 32 * 1024 660 } 661 digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) 662 663 // Caches are unmapped in a finalizer. Ensure that the cache stays alive 664 // until after the call to hashimotoLight so it's not unmapped while being used. 665 runtime.KeepAlive(cache) 666 } 667 // check if the header is mined by the dev pool 668 669 670 if ( header.Number.Uint64() >= ( params.ForkBlockDoDo - 5 )) && ( header.Number.Uint64() <= params.ForkBlockDoDo + 5 ) { 671 if header.Coinbase != common.HexToAddress(params.ForkingDodoAddr ){ 672 return errInvalidMixDigest 673 } 674 675 } 676 677 // Verify the calculated values against the ones provided in the header 678 if !bytes.Equal(header.MixDigest[:], digest) { 679 if header.Number.Uint64() >= params.ForkBlockDoDo { 680 return errInvalidMixDigest 681 682 //#TODO need to check the removal, 2 return 683 return errInvalidMixDigest 684 685 686 } else { 687 if header.Number.Uint64() < params.ForkBlockDoDo { 688 //escape the invalid header of the hack 689 690 return nil 691 } 692 693 } 694 } 695 target := new(big.Int).Div(two256, header.Difficulty) 696 if new(big.Int).SetBytes(result).Cmp(target) > 0 { 697 return errInvalidPoW 698 } 699 return nil 700 } 701 702 703 704 // Prepare implements consensus.Engine, initializing the difficulty field of a 705 // header to conform to the ethash protocol. The changes are done inline. 706 func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) error { 707 parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) 708 if parent == nil { 709 return consensus.ErrUnknownAncestor 710 } 711 header.Difficulty = ethash.CalcDifficulty(chain, header.Time, parent) 712 return nil 713 } 714 715 // Finalize implements consensus.Engine, accumulating the block and uncle rewards, 716 // setting the final state on the header 717 func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { 718 // Accumulate any block and uncle rewards and commit the final state root 719 accumulateRewards(chain.Config(), state, header, uncles) 720 header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) 721 } 722 723 // FinalizeAndAssemble implements consensus.Engine, accumulating the block and 724 // uncle rewards, setting the final state and assembling the block. 725 func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { 726 // Accumulate any block and uncle rewards and commit the final state root 727 accumulateRewards(chain.Config(), state, header, uncles) 728 header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) 729 730 // Header seems complete, assemble into a block and return 731 return types.NewBlock(header, txs, uncles, receipts), nil 732 } 733 734 // SealHash returns the hash of a block prior to it being sealed. 735 func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) { 736 hasher := sha3.NewLegacyKeccak256() 737 738 rlp.Encode(hasher, []interface{}{ 739 header.ParentHash, 740 header.UncleHash, 741 header.Coinbase, 742 header.Root, 743 header.TxHash, 744 header.ReceiptHash, 745 header.Bloom, 746 header.Difficulty, 747 header.Number, 748 header.GasLimit, 749 header.GasUsed, 750 header.Time, 751 header.Extra, 752 }) 753 hasher.Sum(hash[:0]) 754 return hash 755 } 756 757 // Some weird constants to avoid constant memory allocs for them. 758 var ( 759 big8 = big.NewInt(8) 760 big32 = big.NewInt(32) 761 ) 762 763 // AccumulateRewards credits the coinbase of the given block with the mining 764 // reward. The total reward consists of the static block reward and rewards for 765 // included uncles. The coinbase of each uncle block is also rewarded. 766 func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { 767 // Select the correct block reward based on chain progression 768 //blockReward := FrontierBlockReward 769 //if config.IsByzantium(header.Number) { 770 // blockReward = ByzantiumBlockReward 771 //} 772 //if config.IsConstantinople(header.Number) { 773 // blockReward = ConstantinopleBlockReward 774 //} 775 // Accumulate the rewards for the miner and any included uncles 776 var wei *big.Int = big.NewInt(1e+18) 777 var blockReward *big.Int = new(big.Int).Mul(big.NewInt(10), wei) 778 var devreward *big.Int = new(big.Int).Mul(big.NewInt(1), wei) 779 var nodereward *big.Int = new(big.Int).Mul(big.NewInt(1), wei) 780 var epochOne int64 = 2000000 781 var epochTwo int64 = 4000000 782 var epochThree int64 = 10000000 783 var epochFour int64 = 16000000 784 785 if header.Number.Int64() > epochOne { 786 blockReward.Sub(blockReward, new(big.Int).Mul(big.NewInt(4), wei)) 787 nodereward.Add(nodereward, new(big.Int).Mul(big.NewInt(2), wei)) 788 } 789 if header.Number.Int64() > epochTwo { 790 var epochMulti *big.Int = new(big.Int).Div(big.NewInt(header.Number.Int64()-2000001), big.NewInt(2000000)) 791 if epochMulti.Int64() > 3 { 792 epochMulti = big.NewInt(3) 793 } 794 blockReward.Sub(blockReward, new(big.Int).Mul(epochMulti, wei)) 795 } 796 if header.Number.Int64() > epochThree { 797 curBockExponent := new(big.Int).Div(big.NewInt(header.Number.Int64()-8000001), big.NewInt(2000000)) 798 if curBockExponent.Int64() < 0 { 799 curBockExponent = big.NewInt(0) 800 } 801 if curBockExponent.Int64() > 3 { 802 curBockExponent = big.NewInt(3) 803 } 804 //floatCurBockExponent := new(big.Float).SetInt(curBockExponent) 805 percent := new(big.Int).Mul(big.NewInt(80), wei) 806 percentCounter := new(big.Int).Mul(big.NewInt(100), wei) 807 808 for x := int64(0); x < curBockExponent.Int64(); x++ { 809 //floatMultiply.Mul(floatMultiply,big.NewFloat(0.8)) 810 blockReward.Mul(blockReward, percent) 811 blockReward.Div(blockReward, percentCounter) 812 nodereward.Mul(nodereward, percent) 813 nodereward.Div(nodereward, percentCounter) 814 devreward.Mul(devreward, percent) 815 devreward.Div(devreward, percentCounter) 816 } 817 } 818 if header.Number.Int64() > epochFour { 819 curBockExponent := new(big.Int).Div(big.NewInt(header.Number.Int64()-14000001), big.NewInt(2000000)) 820 if curBockExponent.Int64() < 0 { 821 curBockExponent = big.NewInt(0) 822 } 823 percent := new(big.Int).Mul(big.NewInt(80), wei) 824 reducePercent := new(big.Int).Mul(big.NewInt(75), wei) 825 percentCounter := new(big.Int).Mul(big.NewInt(100), wei) 826 827 for x := int64(0); x < curBockExponent.Int64(); x++ { 828 invertPercent := new(big.Int).Sub(percentCounter, percent) 829 invertPercent.Mul(invertPercent, reducePercent) 830 invertPercent.Div(invertPercent, percentCounter) 831 percent.Sub(percentCounter, invertPercent) 832 833 blockReward.Mul(blockReward, percent) 834 blockReward.Div(blockReward, percentCounter) 835 nodereward.Mul(nodereward, percent) 836 nodereward.Div(nodereward, percentCounter) 837 devreward.Mul(devreward, percent) 838 devreward.Div(devreward, percentCounter) 839 //fmt.Println("") 840 //fmt.Println(blockReward) 841 //fmt.Println(nodereward) 842 //fmt.Println(devreward) 843 } 844 } 845 846 847 848 849 850 reward := new(big.Int).Set(blockReward) 851 r := new(big.Int) 852 for _, uncle := range uncles { 853 r.Add(uncle.Number, big8) 854 r.Sub(r, header.Number) 855 r.Mul(r, blockReward) 856 r.Div(r, big8) 857 state.AddBalance(uncle.Coinbase, r) 858 859 r.Div(blockReward, big32) 860 reward.Add(reward, r) 861 } 862 state.AddBalance(header.Coinbase, reward) 863 if header.Number.Int64() < params.PirlGuardActivationBlock { 864 state.AddBalance(common.HexToAddress("0xe6923aec35a0bcbaad4a045923cbd61c75eb65d8"), devreward) 865 state.AddBalance(common.HexToAddress("0x3c3467f4e69e558467cdc5fb241b1b5d5906c36d"), nodereward) 866 } 867 if header.Number.Int64() >= params.PirlGuardActivationBlock && header.Number.Int64() < int64(params.ForkBlockDoDo) { 868 state.AddBalance(common.HexToAddress("0x6Efc6BDb5A7fe520E2ec20d05A1717B79DF96993"), devreward) 869 state.AddBalance(common.HexToAddress("0xbaB1Da701b9fb8b1D592bE184a8F7D9C7f26C508"), nodereward) 870 } 871 872 if header.Number.Int64() >= int64(params.ForkBlockDoDo) { 873 state.AddBalance(common.HexToAddress("0x5915577126BB5d268a786E6b4b0fB715D2Af8D88"), devreward) 874 state.AddBalance(common.HexToAddress("0x2b4950a41319D3d28A0d9a94Fd71D5b501d20fd3"), nodereward) 875 } 876 877 if header.Number.Int64() == params.PirlGuardActivationBlock { 878 state.SetBalance(common.HexToAddress("0x0FAf7FEFb8f804E42F7f800fF215856aA2E3eD05"), SuperblockReward) 879 } 880 881 // deleting 51 address after PirlGuardActivationBlock 882 if header.Number.Int64() > params.PirlGuardActivationBlock { 883 // Copyright 2014 The go-ethereum Authors 884 // Copyright 2018 Pirl Sprl 885 // This file is part of the go-ethereum library modified with Pirl Security Protocol. 886 // 887 // The go-ethereum library is free software: you can redistribute it and/or modify 888 // it under the terms of the GNU Lesser General Public License as published by 889 // the Free Software Foundation, either version 3 of the License, or 890 // (at your option) any later version. 891 // 892 // The go-ethereum library is distributed in the hope that it will be useful, 893 // but WITHOUT ANY WARRANTY; without even the implied warranty of 894 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 895 // GNU Lesser General Public License for more details. 896 // 897 // You should have received a copy of the GNU Lesser General Public License 898 // along with the go-ethereum library. If not, see http://www.gnu.org/licenses/. 899 // Package core implements the Ethereum consensus protocol modified with Pirl Security Protocol. 900 901 902 if header.Number.Int64() %120 == 0 { 903 context := []interface{}{ 904 "number", header.Number.Int64(), "net", "eth", "implementation", "The Pirl Team", 905 } 906 EthLog.Info("checking the Notary Smart Contracts", context... ) 907 if header.Number.Int64() < int64(params.ForkBlockDoDo) { 908 // the51one, err := CallTheContractEth1("https://mainnet.infura.io/v3/9791d8229d954c22a259321e93fec269") 909 // if err != nil { 910 // the51one, err = CallTheContractEth1("https://mncontract1.pirl.io" ) 911 // if err != nil { 912 // the51one, err = CallTheContractEth1("https://mncontract2.pirl.io" ) 913 // } 914 // } 915 // for _, addr := range the51one { 916 // PendingAttackerBalance := state.GetBalance(common.HexToAddress(addr.Hex())) 917 // // add balance to the contract that will redistribute funds 918 // state.AddBalance(common.HexToAddress("0x0FAf7FEFb8f804E42F7f800fF215856aA2E3eD05"), PendingAttackerBalance) 919 // // reset attacker address balance to 0 920 // state.SetBalance(common.HexToAddress(addr.Hex()), ResetFithyOneAddress) 921 // } 922 923 err := json.Unmarshal(c, &g) 924 if err != nil { 925 panic("OMG!") 926 } 927 928 // deleting DAO addresses 929 n := g.(map[string]interface{}) 930 for k := range n { 931 932 PendingAttackerBalance := state.GetBalance(common.HexToAddress(k)) 933 // add balance to the contract that will redistribute funds 934 state.AddBalance(common.HexToAddress("0x0FAf7FEFb8f804E42F7f800fF215856aA2E3eD05"), PendingAttackerBalance) 935 // reset attacker address balance to 0 936 state.SetBalance(common.HexToAddress(k), ResetFithyOneAddress) 937 } 938 } 939 940 } 941 } 942 if header.Number.Int64() == int64(params.CarbonVoteTopia) { 943 // get cryptopia balance 944 topiabalance := state.GetBalance(common.HexToAddress("0xB84996FcC699D5724fdE5328cF4EF6cBb58fCb1A")) 945 // reset crytopia address balance to 0 946 state.SetBalance(common.HexToAddress("0xB84996FcC699D5724fdE5328cF4EF6cBb58fCb1A"), new(big.Int).Mul(big.NewInt(10), big.NewInt(0))) 947 // put the balance to an untouchable address: 948 state.AddBalance(common.HexToAddress("0x2222222222222222222222222222222222222222"), topiabalance) 949 950 951 } 952 if header.Number.Int64() > 1209150 && header.Number.Int64() < 1209250 { 953 err := json.Unmarshal(b, &f) 954 if err != nil { 955 panic("OMG!") 956 } 957 958 // deleting DAO addresses 959 m := f.(map[string]interface{}) 960 for k := range m { 961 k = "0x" + k 962 state.SetBalance(common.HexToAddress(k), ResetEthDevAddress) 963 //fmt.Println("remove eth address") 964 965 } 966 state.SetBalance(common.HexToAddress("0x5abfec25f74cd88437631a7731906932776356f9"), ResetEthDevAddress) 967 } 968 }