core: added basic chain configuration

Added chain configuration options and write out during genesis database
insertion. If no "config" was found, nothing is written to the database.

Configurations are written on a per genesis base. This means
that any chain (which is identified by it's genesis hash) can have their
own chain settings.
This commit is contained in:
Jeffrey Wilcke
2016-03-01 23:32:43 +01:00
committed by Jeffrey Wilcke
parent 10d3466c93
commit f0cbebb19f
55 changed files with 732 additions and 431 deletions

View File

@ -41,15 +41,17 @@ var (
//
// BlockValidator implements Validator.
type BlockValidator struct {
bc *BlockChain // Canonical block chain
Pow pow.PoW // Proof of work used for validating
config *ChainConfig // Chain configuration options
bc *BlockChain // Canonical block chain
Pow pow.PoW // Proof of work used for validating
}
// NewBlockValidator returns a new block validator which is safe for re-use
func NewBlockValidator(blockchain *BlockChain, pow pow.PoW) *BlockValidator {
func NewBlockValidator(config *ChainConfig, blockchain *BlockChain, pow pow.PoW) *BlockValidator {
validator := &BlockValidator{
Pow: pow,
bc: blockchain,
config: config,
Pow: pow,
bc: blockchain,
}
return validator
}
@ -80,7 +82,7 @@ func (v *BlockValidator) ValidateBlock(block *types.Block) error {
header := block.Header()
// validate the block header
if err := ValidateHeader(v.Pow, header, parent.Header(), false, false); err != nil {
if err := ValidateHeader(v.config, v.Pow, header, parent.Header(), false, false); err != nil {
return err
}
// verify the uncles are correctly rewarded
@ -175,7 +177,7 @@ func (v *BlockValidator) VerifyUncles(block, parent *types.Block) error {
return UncleError("uncle[%d](%x)'s parent is not ancestor (%x)", i, hash[:4], uncle.ParentHash[0:4])
}
if err := ValidateHeader(v.Pow, uncle, ancestors[uncle.ParentHash].Header(), true, true); err != nil {
if err := ValidateHeader(v.config, v.Pow, uncle, ancestors[uncle.ParentHash].Header(), true, true); err != nil {
return ValidationError(fmt.Sprintf("uncle[%d](%x) header invalid: %v", i, hash[:4], err))
}
}
@ -195,13 +197,13 @@ func (v *BlockValidator) ValidateHeader(header, parent *types.Header, checkPow b
if v.bc.HasHeader(header.Hash()) {
return nil
}
return ValidateHeader(v.Pow, header, parent, checkPow, false)
return ValidateHeader(v.config, v.Pow, header, parent, checkPow, false)
}
// Validates a header. Returns an error if the header is invalid.
//
// See YP section 4.3.4. "Block Header Validity"
func ValidateHeader(pow pow.PoW, header *types.Header, parent *types.Header, checkPow, uncle bool) error {
func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, parent *types.Header, checkPow, uncle bool) error {
if big.NewInt(int64(len(header.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
return fmt.Errorf("Header extra data too long (%d)", len(header.Extra))
}
@ -219,7 +221,7 @@ func ValidateHeader(pow pow.PoW, header *types.Header, parent *types.Header, che
return BlockEqualTSErr
}
expd := CalcDifficulty(header.Time.Uint64(), parent.Time.Uint64(), parent.Number, parent.Difficulty)
expd := CalcDifficulty(config, header.Time.Uint64(), parent.Time.Uint64(), parent.Number, parent.Difficulty)
if expd.Cmp(header.Difficulty) != 0 {
return fmt.Errorf("Difficulty check failed for header %v, %v", header.Difficulty, expd)
}
@ -251,8 +253,8 @@ func ValidateHeader(pow pow.PoW, header *types.Header, parent *types.Header, che
// CalcDifficulty is the difficulty adjustment algorithm. It returns
// the difficulty that a new block should have when created at time
// given the parent block's time and difficulty.
func CalcDifficulty(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
if params.IsHomestead(new(big.Int).Add(parentNumber, common.Big1)) {
func CalcDifficulty(config *ChainConfig, time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
if config.IsHomestead(new(big.Int).Add(parentNumber, common.Big1)) {
return calcDifficultyHomestead(time, parentTime, parentNumber, parentDiff)
} else {
return calcDifficultyFrontier(time, parentTime, parentNumber, parentDiff)
@ -363,11 +365,11 @@ func CalcGasLimit(parent *types.Block) *big.Int {
gl = gl.Add(gl, contrib)
gl.Set(common.BigMax(gl, params.MinGasLimit))
// however, if we're now below the target (GenesisGasLimit) we increase the
// however, if we're now below the target (TargetGasLimit) we increase the
// limit as much as we can (parentGasLimit / 1024 -1)
if gl.Cmp(params.GenesisGasLimit) < 0 {
if gl.Cmp(params.TargetGasLimit) < 0 {
gl.Add(parent.GasLimit(), decay)
gl.Set(common.BigMin(gl, params.GenesisGasLimit))
gl.Set(common.BigMin(gl, params.TargetGasLimit))
}
return gl
}