diff options
author | obscuren <geffobscura@gmail.com> | 2015-06-18 17:37:30 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-06-18 17:47:50 +0800 |
commit | 15e169e5b6566b77aba23cc04c2f19a94ff23738 (patch) | |
tree | 978abe20851f73ff614a9746d22db20ddc469685 /core | |
parent | f5abc9f188fb684e3601314b8ae454ac5abbf0e9 (diff) | |
download | dexon-15e169e5b6566b77aba23cc04c2f19a94ff23738.tar.gz dexon-15e169e5b6566b77aba23cc04c2f19a94ff23738.tar.zst dexon-15e169e5b6566b77aba23cc04c2f19a94ff23738.zip |
core: ValidatedHeader (method => function)
Changed header validation method to function in preparation of
@karalabe's PR.
Diffstat (limited to 'core')
-rw-r--r-- | core/block_processor.go | 126 | ||||
-rw-r--r-- | core/block_processor_test.go | 8 |
2 files changed, 68 insertions, 66 deletions
diff --git a/core/block_processor.go b/core/block_processor.go index c6df2d0f4..c78d419ce 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -185,7 +185,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st state := state.New(parent.Root(), sm.db) // Block validation - if err = sm.ValidateHeader(block.Header(), parent.Header(), false); err != nil { + if err = ValidateHeader(sm.Pow, block.Header(), parent.Header(), false); err != nil { return } @@ -260,67 +260,6 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st return state.Logs(), nil } -// See YP section 4.3.4. "Block Header Validity" -// Validates a block. Returns an error if the block is invalid. -func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow bool) error { - if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 { - return fmt.Errorf("Block extra data too long (%d)", len(block.Extra)) - } - - expd := CalcDifficulty(block, parent) - if expd.Cmp(block.Difficulty) != 0 { - return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd) - } - - a := new(big.Int).Sub(block.GasLimit, parent.GasLimit) - a.Abs(a) - b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor) - if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) { - return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b) - } - - if int64(block.Time) > time.Now().Unix() { - return BlockFutureErr - } - - if new(big.Int).Sub(block.Number, parent.Number).Cmp(big.NewInt(1)) != 0 { - return BlockNumberErr - } - - if block.Time <= parent.Time { - return BlockEqualTSErr //ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time) - } - - if checkPow { - // Verify the nonce of the block. Return an error if it's not valid - if !sm.Pow.Verify(types.NewBlockWithHeader(block)) { - return ValidationError("Block's nonce is invalid (= %x)", block.Nonce) - } - } - - return nil -} - -func AccumulateRewards(statedb *state.StateDB, block *types.Block) { - reward := new(big.Int).Set(BlockReward) - - for _, uncle := range block.Uncles() { - num := new(big.Int).Add(big.NewInt(8), uncle.Number) - num.Sub(num, block.Number()) - - r := new(big.Int) - r.Mul(BlockReward, num) - r.Div(r, big.NewInt(8)) - - statedb.AddBalance(uncle.Coinbase, r) - - reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32))) - } - - // Get the account associated with the coinbase - statedb.AddBalance(block.Header().Coinbase, reward) -} - func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *types.Block) error { ancestors := set.New() uncles := set.New() @@ -358,7 +297,7 @@ func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *ty return UncleError("uncle[%d](%x)'s parent is not ancestor (%x)", i, hash[:4], uncle.ParentHash[0:4]) } - if err := sm.ValidateHeader(uncle, ancestorHeaders[uncle.ParentHash], true); err != nil { + if err := ValidateHeader(sm.Pow, uncle, ancestorHeaders[uncle.ParentHash], true); err != nil { return ValidationError(fmt.Sprintf("uncle[%d](%x) header invalid: %v", i, hash[:4], err)) } } @@ -395,6 +334,67 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro return state.Logs(), nil } +// See YP section 4.3.4. "Block Header Validity" +// Validates a block. Returns an error if the block is invalid. +func ValidateHeader(pow pow.PoW, block, parent *types.Header, checkPow bool) error { + if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 { + return fmt.Errorf("Block extra data too long (%d)", len(block.Extra)) + } + + expd := CalcDifficulty(block, parent) + if expd.Cmp(block.Difficulty) != 0 { + return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd) + } + + a := new(big.Int).Sub(block.GasLimit, parent.GasLimit) + a.Abs(a) + b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor) + if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) { + return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b) + } + + if int64(block.Time) > time.Now().Unix() { + return BlockFutureErr + } + + if new(big.Int).Sub(block.Number, parent.Number).Cmp(big.NewInt(1)) != 0 { + return BlockNumberErr + } + + if block.Time <= parent.Time { + return BlockEqualTSErr //ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time) + } + + if checkPow { + // Verify the nonce of the block. Return an error if it's not valid + if !pow.Verify(types.NewBlockWithHeader(block)) { + return ValidationError("Block's nonce is invalid (= %x)", block.Nonce) + } + } + + return nil +} + +func AccumulateRewards(statedb *state.StateDB, block *types.Block) { + reward := new(big.Int).Set(BlockReward) + + for _, uncle := range block.Uncles() { + num := new(big.Int).Add(big.NewInt(8), uncle.Number) + num.Sub(num, block.Number()) + + r := new(big.Int) + r.Mul(BlockReward, num) + r.Div(r, big.NewInt(8)) + + statedb.AddBalance(uncle.Coinbase, r) + + reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32))) + } + + // Get the account associated with the coinbase + statedb.AddBalance(block.Header().Coinbase, reward) +} + func getBlockReceipts(db common.Database, bhash common.Hash) (receipts types.Receipts, err error) { var rdata []byte rdata, err = db.Get(append(receiptsPre, bhash[:]...)) diff --git a/core/block_processor_test.go b/core/block_processor_test.go index 97b80038d..e38c815ef 100644 --- a/core/block_processor_test.go +++ b/core/block_processor_test.go @@ -26,18 +26,20 @@ func proc() (*BlockProcessor, *ChainManager) { } func TestNumber(t *testing.T) { - bp, chain := proc() + _, chain := proc() block1 := chain.NewBlock(common.Address{}) block1.Header().Number = big.NewInt(3) block1.Header().Time-- - err := bp.ValidateHeader(block1.Header(), chain.Genesis().Header(), false) + pow := ezp.New() + + err := ValidateHeader(pow, block1.Header(), chain.Genesis().Header(), false) if err != BlockNumberErr { t.Errorf("expected block number error %v", err) } block1 = chain.NewBlock(common.Address{}) - err = bp.ValidateHeader(block1.Header(), chain.Genesis().Header(), false) + err = ValidateHeader(pow, block1.Header(), chain.Genesis().Header(), false) if err == BlockNumberErr { t.Errorf("didn't expect block number error") } |