github.com/badrootd/celestia-core@v0.0.0-20240305091328-aa4207a4b25d/types/params.go (about)

     1  package types
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/badrootd/celestia-core/crypto/ed25519"
     9  	"github.com/badrootd/celestia-core/crypto/secp256k1"
    10  	"github.com/badrootd/celestia-core/crypto/tmhash"
    11  	cmtproto "github.com/badrootd/celestia-core/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  }
    41  
    42  // BlockParams define limits on the block size and gas plus minimum time
    43  // between blocks.
    44  type BlockParams struct {
    45  	MaxBytes int64 `json:"max_bytes"`
    46  	MaxGas   int64 `json:"max_gas"`
    47  }
    48  
    49  // EvidenceParams determine how we handle evidence of malfeasance.
    50  type EvidenceParams struct {
    51  	MaxAgeNumBlocks int64         `json:"max_age_num_blocks"` // only accept new evidence more recent than this
    52  	MaxAgeDuration  time.Duration `json:"max_age_duration"`
    53  	MaxBytes        int64         `json:"max_bytes"`
    54  }
    55  
    56  // ValidatorParams restrict the public key types validators can use.
    57  // NOTE: uses ABCI pubkey naming, not Amino names.
    58  type ValidatorParams struct {
    59  	PubKeyTypes []string `json:"pub_key_types"`
    60  }
    61  
    62  type VersionParams struct {
    63  	App uint64 `json:"app"`
    64  }
    65  
    66  // DefaultConsensusParams returns a default ConsensusParams.
    67  func DefaultConsensusParams() *ConsensusParams {
    68  	return &ConsensusParams{
    69  		Block:     DefaultBlockParams(),
    70  		Evidence:  DefaultEvidenceParams(),
    71  		Validator: DefaultValidatorParams(),
    72  		Version:   DefaultVersionParams(),
    73  	}
    74  }
    75  
    76  // DefaultBlockParams returns a default BlockParams.
    77  func DefaultBlockParams() BlockParams {
    78  	return BlockParams{
    79  		MaxBytes: 22020096, // 21MB
    80  		MaxGas:   -1,
    81  	}
    82  }
    83  
    84  // DefaultEvidenceParams returns a default EvidenceParams.
    85  func DefaultEvidenceParams() EvidenceParams {
    86  	return EvidenceParams{
    87  		MaxAgeNumBlocks: 100000, // 27.8 hrs at 1block/s
    88  		MaxAgeDuration:  48 * time.Hour,
    89  		MaxBytes:        1048576, // 1MB
    90  	}
    91  }
    92  
    93  // DefaultValidatorParams returns a default ValidatorParams, which allows
    94  // only ed25519 pubkeys.
    95  func DefaultValidatorParams() ValidatorParams {
    96  	return ValidatorParams{
    97  		PubKeyTypes: []string{ABCIPubKeyTypeEd25519},
    98  	}
    99  }
   100  
   101  func DefaultVersionParams() VersionParams {
   102  	return VersionParams{
   103  		App: 0,
   104  	}
   105  }
   106  
   107  func IsValidPubkeyType(params ValidatorParams, pubkeyType string) bool {
   108  	for i := 0; i < len(params.PubKeyTypes); i++ {
   109  		if params.PubKeyTypes[i] == pubkeyType {
   110  			return true
   111  		}
   112  	}
   113  	return false
   114  }
   115  
   116  // Validate validates the ConsensusParams to ensure all values are within their
   117  // allowed limits, and returns an error if they are not.
   118  func (params ConsensusParams) ValidateBasic() error {
   119  	if params.Block.MaxBytes <= 0 {
   120  		return fmt.Errorf("block.MaxBytes must be greater than 0. Got %d",
   121  			params.Block.MaxBytes)
   122  	}
   123  	if params.Block.MaxBytes > MaxBlockSizeBytes {
   124  		return fmt.Errorf("block.MaxBytes is too big. %d > %d",
   125  			params.Block.MaxBytes, MaxBlockSizeBytes)
   126  	}
   127  
   128  	if params.Block.MaxGas < -1 {
   129  		return fmt.Errorf("block.MaxGas must be greater or equal to -1. Got %d",
   130  			params.Block.MaxGas)
   131  	}
   132  
   133  	if params.Evidence.MaxAgeNumBlocks <= 0 {
   134  		return fmt.Errorf("evidence.MaxAgeNumBlocks must be greater than 0. Got %d",
   135  			params.Evidence.MaxAgeNumBlocks)
   136  	}
   137  
   138  	if params.Evidence.MaxAgeDuration <= 0 {
   139  		return fmt.Errorf("evidence.MaxAgeDuration must be grater than 0 if provided, Got %v",
   140  			params.Evidence.MaxAgeDuration)
   141  	}
   142  
   143  	if params.Evidence.MaxBytes > params.Block.MaxBytes {
   144  		return fmt.Errorf("evidence.MaxBytesEvidence is greater than upper bound, %d > %d",
   145  			params.Evidence.MaxBytes, params.Block.MaxBytes)
   146  	}
   147  
   148  	if params.Evidence.MaxBytes < 0 {
   149  		return fmt.Errorf("evidence.MaxBytes must be non negative. Got: %d",
   150  			params.Evidence.MaxBytes)
   151  	}
   152  
   153  	if len(params.Validator.PubKeyTypes) == 0 {
   154  		return errors.New("len(Validator.PubKeyTypes) must be greater than 0")
   155  	}
   156  
   157  	// Check if keyType is a known ABCIPubKeyType
   158  	for i := 0; i < len(params.Validator.PubKeyTypes); i++ {
   159  		keyType := params.Validator.PubKeyTypes[i]
   160  		if _, ok := ABCIPubKeyTypesToNames[keyType]; !ok {
   161  			return fmt.Errorf("params.Validator.PubKeyTypes[%d], %s, is an unknown pubkey type",
   162  				i, keyType)
   163  		}
   164  	}
   165  
   166  	return nil
   167  }
   168  
   169  // Hash returns a hash of a subset of the parameters to store in the block header.
   170  // Only the Block.MaxBytes and Block.MaxGas are included in the hash.
   171  // This allows the ConsensusParams to evolve more without breaking the block
   172  // protocol. No need for a Merkle tree here, just a small struct to hash.
   173  func (params ConsensusParams) Hash() []byte {
   174  	hasher := tmhash.New()
   175  
   176  	hp := cmtproto.HashedParams{
   177  		BlockMaxBytes: params.Block.MaxBytes,
   178  		BlockMaxGas:   params.Block.MaxGas,
   179  	}
   180  
   181  	bz, err := hp.Marshal()
   182  	if err != nil {
   183  		panic(err)
   184  	}
   185  
   186  	_, err = hasher.Write(bz)
   187  	if err != nil {
   188  		panic(err)
   189  	}
   190  	return hasher.Sum(nil)
   191  }
   192  
   193  // Update returns a copy of the params with updates from the non-zero fields of p2.
   194  // NOTE: note: must not modify the original
   195  func (params ConsensusParams) Update(params2 *cmtproto.ConsensusParams) ConsensusParams {
   196  	res := params // explicit copy
   197  
   198  	if params2 == nil {
   199  		return res
   200  	}
   201  
   202  	// we must defensively consider any structs may be nil
   203  	if params2.Block != nil {
   204  		res.Block.MaxBytes = params2.Block.MaxBytes
   205  		res.Block.MaxGas = params2.Block.MaxGas
   206  	}
   207  	if params2.Evidence != nil {
   208  		res.Evidence.MaxAgeNumBlocks = params2.Evidence.MaxAgeNumBlocks
   209  		res.Evidence.MaxAgeDuration = params2.Evidence.MaxAgeDuration
   210  		res.Evidence.MaxBytes = params2.Evidence.MaxBytes
   211  	}
   212  	if params2.Validator != nil {
   213  		// Copy params2.Validator.PubkeyTypes, and set result's value to the copy.
   214  		// This avoids having to initialize the slice to 0 values, and then write to it again.
   215  		res.Validator.PubKeyTypes = append([]string{}, params2.Validator.PubKeyTypes...)
   216  	}
   217  	if params2.Version != nil {
   218  		res.Version.App = params2.Version.App
   219  	}
   220  	return res
   221  }
   222  
   223  func (params *ConsensusParams) ToProto() cmtproto.ConsensusParams {
   224  	return cmtproto.ConsensusParams{
   225  		Block: &cmtproto.BlockParams{
   226  			MaxBytes: params.Block.MaxBytes,
   227  			MaxGas:   params.Block.MaxGas,
   228  		},
   229  		Evidence: &cmtproto.EvidenceParams{
   230  			MaxAgeNumBlocks: params.Evidence.MaxAgeNumBlocks,
   231  			MaxAgeDuration:  params.Evidence.MaxAgeDuration,
   232  			MaxBytes:        params.Evidence.MaxBytes,
   233  		},
   234  		Validator: &cmtproto.ValidatorParams{
   235  			PubKeyTypes: params.Validator.PubKeyTypes,
   236  		},
   237  		Version: &cmtproto.VersionParams{
   238  			App: params.Version.App,
   239  		},
   240  	}
   241  }
   242  
   243  func ConsensusParamsFromProto(pbParams cmtproto.ConsensusParams) ConsensusParams {
   244  	return ConsensusParams{
   245  		Block: BlockParams{
   246  			MaxBytes: pbParams.Block.MaxBytes,
   247  			MaxGas:   pbParams.Block.MaxGas,
   248  		},
   249  		Evidence: EvidenceParams{
   250  			MaxAgeNumBlocks: pbParams.Evidence.MaxAgeNumBlocks,
   251  			MaxAgeDuration:  pbParams.Evidence.MaxAgeDuration,
   252  			MaxBytes:        pbParams.Evidence.MaxBytes,
   253  		},
   254  		Validator: ValidatorParams{
   255  			PubKeyTypes: pbParams.Validator.PubKeyTypes,
   256  		},
   257  		Version: VersionParams{
   258  			App: pbParams.Version.App,
   259  		},
   260  	}
   261  }