|
|
|
@ -20,6 +20,7 @@ package clique |
|
|
|
|
import ( |
|
|
|
|
"bytes" |
|
|
|
|
"errors" |
|
|
|
|
"fmt" |
|
|
|
|
"io" |
|
|
|
|
"math/big" |
|
|
|
|
"math/rand" |
|
|
|
@ -293,6 +294,15 @@ func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.H |
|
|
|
|
return errInvalidDifficulty |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Verify that the gas limit is <= 2^63-1
|
|
|
|
|
cap := uint64(0x7fffffffffffffff) |
|
|
|
|
if header.GasLimit > cap { |
|
|
|
|
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap) |
|
|
|
|
} |
|
|
|
|
// Verify that the gasUsed is <= gasLimit
|
|
|
|
|
if header.GasUsed > header.GasLimit { |
|
|
|
|
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) |
|
|
|
|
} |
|
|
|
|
// If all checks passed, validate any special fields for hard forks
|
|
|
|
|
if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil { |
|
|
|
|
return err |
|
|
|
@ -324,6 +334,15 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header |
|
|
|
|
if parent.Time+c.config.Period > header.Time { |
|
|
|
|
return errInvalidTimestamp |
|
|
|
|
} |
|
|
|
|
// Verify that the gas limit remains within allowed bounds
|
|
|
|
|
diff := int64(parent.GasLimit) - int64(header.GasLimit) |
|
|
|
|
if diff < 0 { |
|
|
|
|
diff *= -1 |
|
|
|
|
} |
|
|
|
|
limit := parent.GasLimit / params.GasLimitBoundDivisor |
|
|
|
|
if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit { |
|
|
|
|
return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) |
|
|
|
|
} |
|
|
|
|
// Retrieve the snapshot needed to verify this header and cache it
|
|
|
|
|
snap, err := c.snapshot(chain, number-1, header.ParentHash, parents) |
|
|
|
|
if err != nil { |
|
|
|
|