github.com/aakash4dev/cometbft@v0.38.2/types/params.go (about)

     1  package types
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/aakash4dev/cometbft/crypto/ed25519"
     9  	"github.com/aakash4dev/cometbft/crypto/secp256k1"
    10  	"github.com/aakash4dev/cometbft/crypto/tmhash"
    11  	cmtproto "github.com/aakash4dev/cometbft/proto/tendermint/types"
    12  )
    13  
    14  const (
    15  	// MaxBlockSizeBytes is the maximum permitted size of the blocks.
    16  	MaxBlockSizeBytes = 104857600 // 100MB
    17  
    18  	// BlockPartSizeBytes is the size of one block part.
    19  	BlockPartSizeBytes uint32 = 65536 // 64kB
    20  
    21  	// MaxBlockPartsCount is the maximum number of block parts.
    22  	MaxBlockPartsCount = (MaxBlockSizeBytes / BlockPartSizeBytes) + 1
    23  
    24  	ABCIPubKeyTypeEd25519   = ed25519.KeyType
    25  	ABCIPubKeyTypeSecp256k1 = secp256k1.KeyType
    26  )
    27  
    28  var ABCIPubKeyTypesToNames = map[string]string{
    29  	ABCIPubKeyTypeEd25519:   ed25519.PubKeyName,
    30  	ABCIPubKeyTypeSecp256k1: secp256k1.PubKeyName,
    31  }
    32  
    33  // ConsensusParams contains consensus critical parameters that determine the
    34  // validity of blocks.
    35  type ConsensusParams struct {
    36  	Block     BlockParams     `json:"block"`
    37  	Evidence  EvidenceParams  `json:"evidence"`
    38  	Validator ValidatorParams `json:"validator"`
    39  	Version   VersionParams   `json:"version"`
    40  	ABCI      ABCIParams      `json:"abci"`
    41  }
    42  
    43  // BlockParams define limits on the block size and gas plus minimum time
    44  // between blocks.
    45  type BlockParams struct {
    46  	MaxBytes int64 `json:"max_bytes"`
    47  	MaxGas   int64 `json:"max_gas"`
    48  }
    49  
    50  // EvidenceParams determine how we handle evidence of malfeasance.
    51  type EvidenceParams struct {
    52  	MaxAgeNumBlocks int64         `json:"max_age_num_blocks"` // only accept new evidence more recent than this
    53  	MaxAgeDuration  time.Duration `json:"max_age_duration"`
    54  	MaxBytes        int64         `json:"max_bytes"`
    55  }
    56  
    57  // ValidatorParams restrict the public key types validators can use.
    58  // NOTE: uses ABCI pubkey naming, not Amino names.
    59  type ValidatorParams struct {
    60  	PubKeyTypes []string `json:"pub_key_types"`
    61  }
    62  
    63  type VersionParams struct {
    64  	App uint64 `json:"app"`
    65  }
    66  
    67  // ABCIParams configure ABCI functionality specific to the Application Blockchain
    68  // Interface.
    69  type ABCIParams struct {
    70  	VoteExtensionsEnableHeight int64 `json:"vote_extensions_enable_height"`
    71  }
    72  
    73  // VoteExtensionsEnabled returns true if vote extensions are enabled at height h
    74  // and false otherwise.
    75  func (a ABCIParams) VoteExtensionsEnabled(h int64) bool {
    76  	if h < 1 {
    77  		panic(fmt.Errorf("cannot check if vote extensions enabled for height %d (< 1)", h))
    78  	}
    79  	if a.VoteExtensionsEnableHeight == 0 {
    80  		return false
    81  	}
    82  	return a.VoteExtensionsEnableHeight <= h
    83  }
    84  
    85  // DefaultConsensusParams returns a default ConsensusParams.
    86  func DefaultConsensusParams() *ConsensusParams {
    87  	return &ConsensusParams{
    88  		Block:     DefaultBlockParams(),
    89  		Evidence:  DefaultEvidenceParams(),
    90  		Validator: DefaultValidatorParams(),
    91  		Version:   DefaultVersionParams(),
    92  		ABCI:      DefaultABCIParams(),
    93  	}
    94  }
    95  
    96  // DefaultBlockParams returns a default BlockParams.
    97  func DefaultBlockParams() BlockParams {
    98  	return BlockParams{
    99  		MaxBytes: 22020096, // 21MB
   100  		MaxGas:   -1,
   101  	}
   102  }
   103  
   104  // DefaultEvidenceParams returns a default EvidenceParams.
   105  func DefaultEvidenceParams() EvidenceParams {
   106  	return EvidenceParams{
   107  		MaxAgeNumBlocks: 100000, // 27.8 hrs at 1block/s
   108  		MaxAgeDuration:  48 * time.Hour,
   109  		MaxBytes:        1048576, // 1MB
   110  	}
   111  }
   112  
   113  // DefaultValidatorParams returns a default ValidatorParams, which allows
   114  // only ed25519 pubkeys.
   115  func DefaultValidatorParams() ValidatorParams {
   116  	return ValidatorParams{
   117  		PubKeyTypes: []string{ABCIPubKeyTypeEd25519},
   118  	}
   119  }
   120  
   121  func DefaultVersionParams() VersionParams {
   122  	return VersionParams{
   123  		App: 0,
   124  	}
   125  }
   126  
   127  func DefaultABCIParams() ABCIParams {
   128  	return ABCIParams{
   129  		// When set to 0, vote extensions are not required.
   130  		VoteExtensionsEnableHeight: 0,
   131  	}
   132  }
   133  
   134  func IsValidPubkeyType(params ValidatorParams, pubkeyType string) bool {
   135  	for i := 0; i < len(params.PubKeyTypes); i++ {
   136  		if params.PubKeyTypes[i] == pubkeyType {
   137  			return true
   138  		}
   139  	}
   140  	return false
   141  }
   142  
   143  // Validate validates the ConsensusParams to ensure all values are within their
   144  // allowed limits, and returns an error if they are not.
   145  func (params ConsensusParams) ValidateBasic() error {
   146  	if params.Block.MaxBytes == 0 {
   147  		return fmt.Errorf("block.MaxBytes cannot be 0")
   148  	}
   149  	if params.Block.MaxBytes < -1 {
   150  		return fmt.Errorf("block.MaxBytes must be -1 or greater than 0. Got %d",
   151  
   152  			params.Block.MaxBytes)
   153  	}
   154  	if params.Block.MaxBytes > MaxBlockSizeBytes {
   155  		return fmt.Errorf("block.MaxBytes is too big. %d > %d",
   156  			params.Block.MaxBytes, MaxBlockSizeBytes)
   157  	}
   158  
   159  	if params.Block.MaxGas < -1 {
   160  		return fmt.Errorf("block.MaxGas must be greater or equal to -1. Got %d",
   161  			params.Block.MaxGas)
   162  	}
   163  
   164  	if params.Evidence.MaxAgeNumBlocks <= 0 {
   165  		return fmt.Errorf("evidence.MaxAgeNumBlocks must be greater than 0. Got %d",
   166  			params.Evidence.MaxAgeNumBlocks)
   167  	}
   168  
   169  	if params.Evidence.MaxAgeDuration <= 0 {
   170  		return fmt.Errorf("evidence.MaxAgeDuration must be grater than 0 if provided, Got %v",
   171  			params.Evidence.MaxAgeDuration)
   172  	}
   173  
   174  	maxBytes := params.Block.MaxBytes
   175  	if maxBytes == -1 {
   176  		maxBytes = int64(MaxBlockSizeBytes)
   177  	}
   178  	if params.Evidence.MaxBytes > maxBytes {
   179  		return fmt.Errorf("evidence.MaxBytesEvidence is greater than upper bound, %d > %d",
   180  			params.Evidence.MaxBytes, params.Block.MaxBytes)
   181  	}
   182  
   183  	if params.Evidence.MaxBytes < 0 {
   184  		return fmt.Errorf("evidence.MaxBytes must be non negative. Got: %d",
   185  			params.Evidence.MaxBytes)
   186  	}
   187  
   188  	if params.ABCI.VoteExtensionsEnableHeight < 0 {
   189  		return fmt.Errorf("ABCI.VoteExtensionsEnableHeight cannot be negative. Got: %d", params.ABCI.VoteExtensionsEnableHeight)
   190  	}
   191  
   192  	if len(params.Validator.PubKeyTypes) == 0 {
   193  		return errors.New("len(Validator.PubKeyTypes) must be greater than 0")
   194  	}
   195  
   196  	// Check if keyType is a known ABCIPubKeyType
   197  	for i := 0; i < len(params.Validator.PubKeyTypes); i++ {
   198  		keyType := params.Validator.PubKeyTypes[i]
   199  		if _, ok := ABCIPubKeyTypesToNames[keyType]; !ok {
   200  			return fmt.Errorf("params.Validator.PubKeyTypes[%d], %s, is an unknown pubkey type",
   201  				i, keyType)
   202  		}
   203  	}
   204  
   205  	return nil
   206  }
   207  
   208  func (params ConsensusParams) ValidateUpdate(updated *cmtproto.ConsensusParams, h int64) error {
   209  	if updated.Abci == nil {
   210  		return nil
   211  	}
   212  	if params.ABCI.VoteExtensionsEnableHeight == updated.Abci.VoteExtensionsEnableHeight {
   213  		return nil
   214  	}
   215  	if params.ABCI.VoteExtensionsEnableHeight != 0 && updated.Abci.VoteExtensionsEnableHeight == 0 {
   216  		return errors.New("vote extensions cannot be disabled once enabled")
   217  	}
   218  	if updated.Abci.VoteExtensionsEnableHeight <= h {
   219  		return fmt.Errorf("VoteExtensionsEnableHeight cannot be updated to a past height, "+
   220  			"initial height: %d, current height %d",
   221  			params.ABCI.VoteExtensionsEnableHeight, h)
   222  	}
   223  	if params.ABCI.VoteExtensionsEnableHeight <= h {
   224  		return fmt.Errorf("VoteExtensionsEnableHeight cannot be modified once"+
   225  			"the initial height has occurred, "+
   226  			"initial height: %d, current height %d",
   227  			params.ABCI.VoteExtensionsEnableHeight, h)
   228  	}
   229  	return nil
   230  }
   231  
   232  // Hash returns a hash of a subset of the parameters to store in the block header.
   233  // Only the Block.MaxBytes and Block.MaxGas are included in the hash.
   234  // This allows the ConsensusParams to evolve more without breaking the block
   235  // protocol. No need for a Merkle tree here, just a small struct to hash.
   236  func (params ConsensusParams) Hash() []byte {
   237  	hasher := tmhash.New()
   238  
   239  	hp := cmtproto.HashedParams{
   240  		BlockMaxBytes: params.Block.MaxBytes,
   241  		BlockMaxGas:   params.Block.MaxGas,
   242  	}
   243  
   244  	bz, err := hp.Marshal()
   245  	if err != nil {
   246  		panic(err)
   247  	}
   248  
   249  	_, err = hasher.Write(bz)
   250  	if err != nil {
   251  		panic(err)
   252  	}
   253  	return hasher.Sum(nil)
   254  }
   255  
   256  // Update returns a copy of the params with updates from the non-zero fields of p2.
   257  // NOTE: note: must not modify the original
   258  func (params ConsensusParams) Update(params2 *cmtproto.ConsensusParams) ConsensusParams {
   259  	res := params // explicit copy
   260  
   261  	if params2 == nil {
   262  		return res
   263  	}
   264  
   265  	// we must defensively consider any structs may be nil
   266  	if params2.Block != nil {
   267  		res.Block.MaxBytes = params2.Block.MaxBytes
   268  		res.Block.MaxGas = params2.Block.MaxGas
   269  	}
   270  	if params2.Evidence != nil {
   271  		res.Evidence.MaxAgeNumBlocks = params2.Evidence.MaxAgeNumBlocks
   272  		res.Evidence.MaxAgeDuration = params2.Evidence.MaxAgeDuration
   273  		res.Evidence.MaxBytes = params2.Evidence.MaxBytes
   274  	}
   275  	if params2.Validator != nil {
   276  		// Copy params2.Validator.PubkeyTypes, and set result's value to the copy.
   277  		// This avoids having to initialize the slice to 0 values, and then write to it again.
   278  		res.Validator.PubKeyTypes = append([]string{}, params2.Validator.PubKeyTypes...)
   279  	}
   280  	if params2.Version != nil {
   281  		res.Version.App = params2.Version.App
   282  	}
   283  	if params2.Abci != nil {
   284  		res.ABCI.VoteExtensionsEnableHeight = params2.Abci.GetVoteExtensionsEnableHeight()
   285  	}
   286  	return res
   287  }
   288  
   289  func (params *ConsensusParams) ToProto() cmtproto.ConsensusParams {
   290  	return cmtproto.ConsensusParams{
   291  		Block: &cmtproto.BlockParams{
   292  			MaxBytes: params.Block.MaxBytes,
   293  			MaxGas:   params.Block.MaxGas,
   294  		},
   295  		Evidence: &cmtproto.EvidenceParams{
   296  			MaxAgeNumBlocks: params.Evidence.MaxAgeNumBlocks,
   297  			MaxAgeDuration:  params.Evidence.MaxAgeDuration,
   298  			MaxBytes:        params.Evidence.MaxBytes,
   299  		},
   300  		Validator: &cmtproto.ValidatorParams{
   301  			PubKeyTypes: params.Validator.PubKeyTypes,
   302  		},
   303  		Version: &cmtproto.VersionParams{
   304  			App: params.Version.App,
   305  		},
   306  		Abci: &cmtproto.ABCIParams{
   307  			VoteExtensionsEnableHeight: params.ABCI.VoteExtensionsEnableHeight,
   308  		},
   309  	}
   310  }
   311  
   312  func ConsensusParamsFromProto(pbParams cmtproto.ConsensusParams) ConsensusParams {
   313  	c := ConsensusParams{
   314  		Block: BlockParams{
   315  			MaxBytes: pbParams.Block.MaxBytes,
   316  			MaxGas:   pbParams.Block.MaxGas,
   317  		},
   318  		Evidence: EvidenceParams{
   319  			MaxAgeNumBlocks: pbParams.Evidence.MaxAgeNumBlocks,
   320  			MaxAgeDuration:  pbParams.Evidence.MaxAgeDuration,
   321  			MaxBytes:        pbParams.Evidence.MaxBytes,
   322  		},
   323  		Validator: ValidatorParams{
   324  			PubKeyTypes: pbParams.Validator.PubKeyTypes,
   325  		},
   326  		Version: VersionParams{
   327  			App: pbParams.Version.App,
   328  		},
   329  	}
   330  	if pbParams.Abci != nil {
   331  		c.ABCI.VoteExtensionsEnableHeight = pbParams.Abci.GetVoteExtensionsEnableHeight()
   332  	}
   333  	return c
   334  }