|
@ -12,68 +12,68 @@ import ( |
|
|
//-----------------------------------------------------
|
|
|
//-----------------------------------------------------
|
|
|
// Validate block
|
|
|
// Validate block
|
|
|
|
|
|
|
|
|
func validateBlock(stateDB dbm.DB, state State, b *types.Block) error { |
|
|
|
|
|
|
|
|
func validateBlock(stateDB dbm.DB, state State, block *types.Block) error { |
|
|
// validate internal consistency
|
|
|
// validate internal consistency
|
|
|
if err := b.ValidateBasic(); err != nil { |
|
|
|
|
|
|
|
|
if err := block.ValidateBasic(); err != nil { |
|
|
return err |
|
|
return err |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// validate basic info
|
|
|
// validate basic info
|
|
|
if b.ChainID != state.ChainID { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.ChainID. Expected %v, got %v", state.ChainID, b.ChainID) |
|
|
|
|
|
|
|
|
if block.ChainID != state.ChainID { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.ChainID. Expected %v, got %v", state.ChainID, block.ChainID) |
|
|
} |
|
|
} |
|
|
if b.Height != state.LastBlockHeight+1 { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.Height. Expected %v, got %v", state.LastBlockHeight+1, b.Height) |
|
|
|
|
|
|
|
|
if block.Height != state.LastBlockHeight+1 { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.Height. Expected %v, got %v", state.LastBlockHeight+1, block.Height) |
|
|
} |
|
|
} |
|
|
/* TODO: Determine bounds for Time |
|
|
/* TODO: Determine bounds for Time |
|
|
See blockchain/reactor "stopSyncingDurationMinutes" |
|
|
See blockchain/reactor "stopSyncingDurationMinutes" |
|
|
|
|
|
|
|
|
if !b.Time.After(lastBlockTime) { |
|
|
|
|
|
|
|
|
if !block.Time.After(lastBlockTime) { |
|
|
return errors.New("Invalid Block.Header.Time") |
|
|
return errors.New("Invalid Block.Header.Time") |
|
|
} |
|
|
} |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
// validate prev block info
|
|
|
// validate prev block info
|
|
|
if !b.LastBlockID.Equals(state.LastBlockID) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.LastBlockID. Expected %v, got %v", state.LastBlockID, b.LastBlockID) |
|
|
|
|
|
|
|
|
if !block.LastBlockID.Equals(state.LastBlockID) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.LastBlockID. Expected %v, got %v", state.LastBlockID, block.LastBlockID) |
|
|
} |
|
|
} |
|
|
newTxs := int64(len(b.Data.Txs)) |
|
|
|
|
|
if b.TotalTxs != state.LastBlockTotalTx+newTxs { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.TotalTxs. Expected %v, got %v", state.LastBlockTotalTx+newTxs, b.TotalTxs) |
|
|
|
|
|
|
|
|
newTxs := int64(len(block.Data.Txs)) |
|
|
|
|
|
if block.TotalTxs != state.LastBlockTotalTx+newTxs { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.TotalTxs. Expected %v, got %v", state.LastBlockTotalTx+newTxs, block.TotalTxs) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// validate app info
|
|
|
// validate app info
|
|
|
if !bytes.Equal(b.AppHash, state.AppHash) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.AppHash. Expected %X, got %v", state.AppHash, b.AppHash) |
|
|
|
|
|
|
|
|
if !bytes.Equal(block.AppHash, state.AppHash) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.AppHash. Expected %X, got %v", state.AppHash, block.AppHash) |
|
|
} |
|
|
} |
|
|
if !bytes.Equal(b.ConsensusHash, state.ConsensusParams.Hash()) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.ConsensusHash. Expected %X, got %v", state.ConsensusParams.Hash(), b.ConsensusHash) |
|
|
|
|
|
|
|
|
if !bytes.Equal(block.ConsensusHash, state.ConsensusParams.Hash()) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.ConsensusHash. Expected %X, got %v", state.ConsensusParams.Hash(), block.ConsensusHash) |
|
|
} |
|
|
} |
|
|
if !bytes.Equal(b.LastResultsHash, state.LastResultsHash) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.LastResultsHash. Expected %X, got %v", state.LastResultsHash, b.LastResultsHash) |
|
|
|
|
|
|
|
|
if !bytes.Equal(block.LastResultsHash, state.LastResultsHash) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.LastResultsHash. Expected %X, got %v", state.LastResultsHash, block.LastResultsHash) |
|
|
} |
|
|
} |
|
|
if !bytes.Equal(b.ValidatorsHash, state.Validators.Hash()) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.ValidatorsHash. Expected %X, got %v", state.Validators.Hash(), b.ValidatorsHash) |
|
|
|
|
|
|
|
|
if !bytes.Equal(block.ValidatorsHash, state.Validators.Hash()) { |
|
|
|
|
|
return fmt.Errorf("Wrong Block.Header.ValidatorsHash. Expected %X, got %v", state.Validators.Hash(), block.ValidatorsHash) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Validate block LastCommit.
|
|
|
// Validate block LastCommit.
|
|
|
if b.Height == 1 { |
|
|
|
|
|
if len(b.LastCommit.Precommits) != 0 { |
|
|
|
|
|
|
|
|
if block.Height == 1 { |
|
|
|
|
|
if len(block.LastCommit.Precommits) != 0 { |
|
|
return errors.New("Block at height 1 (first block) should have no LastCommit precommits") |
|
|
return errors.New("Block at height 1 (first block) should have no LastCommit precommits") |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
if len(b.LastCommit.Precommits) != state.LastValidators.Size() { |
|
|
|
|
|
|
|
|
if len(block.LastCommit.Precommits) != state.LastValidators.Size() { |
|
|
return fmt.Errorf("Invalid block commit size. Expected %v, got %v", |
|
|
return fmt.Errorf("Invalid block commit size. Expected %v, got %v", |
|
|
state.LastValidators.Size(), len(b.LastCommit.Precommits)) |
|
|
|
|
|
|
|
|
state.LastValidators.Size(), len(block.LastCommit.Precommits)) |
|
|
} |
|
|
} |
|
|
err := state.LastValidators.VerifyCommit( |
|
|
err := state.LastValidators.VerifyCommit( |
|
|
state.ChainID, state.LastBlockID, b.Height-1, b.LastCommit) |
|
|
|
|
|
|
|
|
state.ChainID, state.LastBlockID, block.Height-1, block.LastCommit) |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
return err |
|
|
return err |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for _, ev := range b.Evidence.Evidence { |
|
|
|
|
|
|
|
|
for _, ev := range block.Evidence.Evidence { |
|
|
if err := VerifyEvidence(stateDB, state, ev); err != nil { |
|
|
if err := VerifyEvidence(stateDB, state, ev); err != nil { |
|
|
return types.NewEvidenceInvalidErr(ev, err) |
|
|
return types.NewEvidenceInvalidErr(ev, err) |
|
|
} |
|
|
} |
|
|