|
|
@@ -39,11 +39,11 @@ import (
|
|
|
|
|
|
// Ethash proof-of-work protocol constants.
|
|
|
var (
|
|
|
- FrontierBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
|
|
|
- ByzantiumBlockReward = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
|
|
|
- ConstantinopleBlockReward = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople
|
|
|
- maxUncles = 2 // Maximum number of uncles allowed in a single block
|
|
|
- allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks
|
|
|
+ FrontierBlockReward = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
|
|
|
+ ByzantiumBlockReward = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Byzantium
|
|
|
+ ConstantinopleBlockReward = big.NewInt(2e+18) // Block reward in wei for successfully mining a block upward from Constantinople
|
|
|
+ maxUncles = 2 // Maximum number of uncles allowed in a single block
|
|
|
+ allowedFutureBlockTimeSeconds = int64(15) // Max seconds from current time allowed for blocks, before they're considered future blocks
|
|
|
|
|
|
// calcDifficultyEip2384 is the difficulty adjustment algorithm as specified by EIP 2384.
|
|
|
// It offsets the bomb 4M blocks from Constantinople, so in total 9M blocks.
|
|
|
@@ -102,7 +102,7 @@ func (ethash *Ethash) VerifyHeader(chain consensus.ChainHeaderReader, header *ty
|
|
|
return consensus.ErrUnknownAncestor
|
|
|
}
|
|
|
// Sanity checks passed, do a proper verification
|
|
|
- return ethash.verifyHeader(chain, header, parent, false, seal)
|
|
|
+ return ethash.verifyHeader(chain, header, parent, false, seal, time.Now().Unix())
|
|
|
}
|
|
|
|
|
|
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
|
|
|
@@ -126,15 +126,16 @@ func (ethash *Ethash) VerifyHeaders(chain consensus.ChainHeaderReader, headers [
|
|
|
|
|
|
// Create a task channel and spawn the verifiers
|
|
|
var (
|
|
|
- inputs = make(chan int)
|
|
|
- done = make(chan int, workers)
|
|
|
- errors = make([]error, len(headers))
|
|
|
- abort = make(chan struct{})
|
|
|
+ inputs = make(chan int)
|
|
|
+ done = make(chan int, workers)
|
|
|
+ errors = make([]error, len(headers))
|
|
|
+ abort = make(chan struct{})
|
|
|
+ unixNow = time.Now().Unix()
|
|
|
)
|
|
|
for i := 0; i < workers; i++ {
|
|
|
go func() {
|
|
|
for index := range inputs {
|
|
|
- errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index)
|
|
|
+ errors[index] = ethash.verifyHeaderWorker(chain, headers, seals, index, unixNow)
|
|
|
done <- index
|
|
|
}
|
|
|
}()
|
|
|
@@ -170,7 +171,7 @@ func (ethash *Ethash) VerifyHeaders(chain consensus.ChainHeaderReader, headers [
|
|
|
return abort, errorsOut
|
|
|
}
|
|
|
|
|
|
-func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainHeaderReader, headers []*types.Header, seals []bool, index int) error {
|
|
|
+func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainHeaderReader, headers []*types.Header, seals []bool, index int, unixNow int64) error {
|
|
|
var parent *types.Header
|
|
|
if index == 0 {
|
|
|
parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
|
|
|
@@ -180,10 +181,7 @@ func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainHeaderReader, head
|
|
|
if parent == nil {
|
|
|
return consensus.ErrUnknownAncestor
|
|
|
}
|
|
|
- if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil {
|
|
|
- return nil // known block
|
|
|
- }
|
|
|
- return ethash.verifyHeader(chain, headers[index], parent, false, seals[index])
|
|
|
+ return ethash.verifyHeader(chain, headers[index], parent, false, seals[index], unixNow)
|
|
|
}
|
|
|
|
|
|
// VerifyUncles verifies that the given block's uncles conform to the consensus
|
|
|
@@ -234,7 +232,7 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo
|
|
|
if ancestors[uncle.ParentHash] == nil || uncle.ParentHash == block.ParentHash() {
|
|
|
return errDanglingUncle
|
|
|
}
|
|
|
- if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true); err != nil {
|
|
|
+ if err := ethash.verifyHeader(chain, uncle, ancestors[uncle.ParentHash], true, true, time.Now().Unix()); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
}
|
|
|
@@ -244,14 +242,14 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo
|
|
|
// verifyHeader checks whether a header conforms to the consensus rules of the
|
|
|
// stock Ethereum ethash engine.
|
|
|
// See YP section 4.3.4. "Block Header Validity"
|
|
|
-func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header, uncle bool, seal bool) error {
|
|
|
+func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header, uncle bool, seal bool, unixNow int64) error {
|
|
|
// Ensure that the header's extra-data section is of a reasonable size
|
|
|
if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
|
|
|
return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize)
|
|
|
}
|
|
|
// Verify the header's timestamp
|
|
|
if !uncle {
|
|
|
- if header.Time > uint64(time.Now().Add(allowedFutureBlockTime).Unix()) {
|
|
|
+ if header.Time > uint64(unixNow+allowedFutureBlockTimeSeconds) {
|
|
|
return consensus.ErrFutureBlock
|
|
|
}
|
|
|
}
|