github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/internal/state/validation.go (about) 1 package state 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 8 "github.com/ari-anchor/sei-tendermint/types" 9 ) 10 11 //----------------------------------------------------- 12 // Validate block 13 14 func validateBlock(state State, block *types.Block) error { 15 // Validate internal consistency. 16 if err := block.ValidateBasic(); err != nil { 17 return err 18 } 19 20 // Validate basic info. 21 if block.Version.App != state.Version.Consensus.App || 22 block.Version.Block != state.Version.Consensus.Block { 23 return fmt.Errorf("wrong Block.Header.Version. Expected %v, got %v", 24 state.Version.Consensus, 25 block.Version, 26 ) 27 } 28 if block.ChainID != state.ChainID { 29 return fmt.Errorf("wrong Block.Header.ChainID. Expected %v, got %v", 30 state.ChainID, 31 block.ChainID, 32 ) 33 } 34 if state.LastBlockHeight == 0 && block.Height != state.InitialHeight { 35 return fmt.Errorf("wrong Block.Header.Height. Expected %v for initial block, got %v", 36 block.Height, state.InitialHeight) 37 } 38 if state.LastBlockHeight > 0 && block.Height != state.LastBlockHeight+1 { 39 return fmt.Errorf("wrong Block.Header.Height. Expected %v, got %v", 40 state.LastBlockHeight+1, 41 block.Height, 42 ) 43 } 44 // Validate prev block info. 45 if !block.LastBlockID.Equals(state.LastBlockID) { 46 return fmt.Errorf("wrong Block.Header.LastBlockID. Expected %v, got %v", 47 state.LastBlockID, 48 block.LastBlockID, 49 ) 50 } 51 52 // Validate app info 53 if !bytes.Equal(block.AppHash, state.AppHash) { 54 return fmt.Errorf("wrong Block.Header.AppHash. Expected %X, got %v", 55 state.AppHash, 56 block.AppHash, 57 ) 58 } 59 hashCP := state.ConsensusParams.HashConsensusParams() 60 if !bytes.Equal(block.ConsensusHash, hashCP) { 61 return fmt.Errorf("wrong Block.Header.ConsensusHash. Expected %X, got %v", 62 hashCP, 63 block.ConsensusHash, 64 ) 65 } 66 if !bytes.Equal(block.LastResultsHash, state.LastResultsHash) { 67 return fmt.Errorf("wrong Block.Header.LastResultsHash. Expected %X, got %v", 68 state.LastResultsHash, 69 block.LastResultsHash, 70 ) 71 } 72 if !bytes.Equal(block.ValidatorsHash, state.Validators.Hash()) { 73 return fmt.Errorf("wrong Block.Header.ValidatorsHash. Expected %X, got %v", 74 state.Validators.Hash(), 75 block.ValidatorsHash, 76 ) 77 } 78 if !bytes.Equal(block.NextValidatorsHash, state.NextValidators.Hash()) { 79 return fmt.Errorf("wrong Block.Header.NextValidatorsHash. Expected %X, got %v", 80 state.NextValidators.Hash(), 81 block.NextValidatorsHash, 82 ) 83 } 84 85 // Validate block LastCommit. 86 if block.Height == state.InitialHeight { 87 if len(block.LastCommit.Signatures) != 0 { 88 return errors.New("initial block can't have LastCommit signatures") 89 } 90 } else { 91 // LastCommit.Signatures length is checked in VerifyCommit. 92 if err := state.LastValidators.VerifyCommit( 93 state.ChainID, state.LastBlockID, block.Height-1, block.LastCommit); err != nil { 94 return err 95 } 96 } 97 98 // NOTE: We can't actually verify it's the right proposer because we don't 99 // know what round the block was first proposed. So just check that it's 100 // a legit address and a known validator. 101 // The length is checked in ValidateBasic above. 102 if !state.Validators.HasAddress(block.ProposerAddress) { 103 return fmt.Errorf("block.Header.ProposerAddress %X is not a validator", 104 block.ProposerAddress, 105 ) 106 } 107 108 // Validate block Time 109 switch { 110 case block.Height > state.InitialHeight: 111 if !block.Time.After(state.LastBlockTime) { 112 return fmt.Errorf("block time %v not greater than last block time %v", 113 block.Time, 114 state.LastBlockTime, 115 ) 116 } 117 118 case block.Height == state.InitialHeight: 119 genesisTime := state.LastBlockTime 120 if block.Time.Before(genesisTime) { 121 return fmt.Errorf("block time %v is before genesis time %v", 122 block.Time, 123 genesisTime, 124 ) 125 } 126 127 default: 128 return fmt.Errorf("block height %v lower than initial height %v", 129 block.Height, state.InitialHeight) 130 } 131 132 // Check evidence doesn't exceed the limit amount of bytes. 133 if max, got := state.ConsensusParams.Evidence.MaxBytes, block.Evidence.ByteSize(); got > max { 134 return types.NewErrEvidenceOverflow(max, got) 135 } 136 137 return nil 138 }