github.com/evdatsion/aphelion-dpos-bft@v0.32.1/types/params.go (about)

     1  package types
     2  
     3  import (
     4  	abci "github.com/evdatsion/aphelion-dpos-bft/abci/types"
     5  	"github.com/evdatsion/aphelion-dpos-bft/crypto/tmhash"
     6  	cmn "github.com/evdatsion/aphelion-dpos-bft/libs/common"
     7  )
     8  
     9  const (
    10  	// MaxBlockSizeBytes is the maximum permitted size of the blocks.
    11  	MaxBlockSizeBytes = 104857600 // 100MB
    12  
    13  	// BlockPartSizeBytes is the size of one block part.
    14  	BlockPartSizeBytes = 65536 // 64kB
    15  )
    16  
    17  // ConsensusParams contains consensus critical parameters that determine the
    18  // validity of blocks.
    19  type ConsensusParams struct {
    20  	Block     BlockParams     `json:"block"`
    21  	Evidence  EvidenceParams  `json:"evidence"`
    22  	Validator ValidatorParams `json:"validator"`
    23  }
    24  
    25  // HashedParams is a subset of ConsensusParams.
    26  // It is amino encoded and hashed into
    27  // the Header.ConsensusHash.
    28  type HashedParams struct {
    29  	BlockMaxBytes int64
    30  	BlockMaxGas   int64
    31  }
    32  
    33  // BlockParams define limits on the block size and gas plus minimum time
    34  // between blocks.
    35  type BlockParams struct {
    36  	MaxBytes int64 `json:"max_bytes"`
    37  	MaxGas   int64 `json:"max_gas"`
    38  	// Minimum time increment between consecutive blocks (in milliseconds)
    39  	// Not exposed to the application.
    40  	TimeIotaMs int64 `json:"time_iota_ms"`
    41  }
    42  
    43  // EvidenceParams determine how we handle evidence of malfeasance.
    44  type EvidenceParams struct {
    45  	MaxAge int64 `json:"max_age"` // only accept new evidence more recent than this
    46  }
    47  
    48  // ValidatorParams restrict the public key types validators can use.
    49  // NOTE: uses ABCI pubkey naming, not Amino names.
    50  type ValidatorParams struct {
    51  	PubKeyTypes []string `json:"pub_key_types"`
    52  }
    53  
    54  // DefaultConsensusParams returns a default ConsensusParams.
    55  func DefaultConsensusParams() *ConsensusParams {
    56  	return &ConsensusParams{
    57  		DefaultBlockParams(),
    58  		DefaultEvidenceParams(),
    59  		DefaultValidatorParams(),
    60  	}
    61  }
    62  
    63  // DefaultBlockParams returns a default BlockParams.
    64  func DefaultBlockParams() BlockParams {
    65  	return BlockParams{
    66  		MaxBytes:   22020096, // 21MB
    67  		MaxGas:     -1,
    68  		TimeIotaMs: 1000, // 1s
    69  	}
    70  }
    71  
    72  // DefaultEvidenceParams Params returns a default EvidenceParams.
    73  func DefaultEvidenceParams() EvidenceParams {
    74  	return EvidenceParams{
    75  		MaxAge: 100000, // 27.8 hrs at 1block/s
    76  	}
    77  }
    78  
    79  // DefaultValidatorParams returns a default ValidatorParams, which allows
    80  // only ed25519 pubkeys.
    81  func DefaultValidatorParams() ValidatorParams {
    82  	return ValidatorParams{[]string{ABCIPubKeyTypeEd25519}}
    83  }
    84  
    85  func (params *ValidatorParams) IsValidPubkeyType(pubkeyType string) bool {
    86  	for i := 0; i < len(params.PubKeyTypes); i++ {
    87  		if params.PubKeyTypes[i] == pubkeyType {
    88  			return true
    89  		}
    90  	}
    91  	return false
    92  }
    93  
    94  // Validate validates the ConsensusParams to ensure all values are within their
    95  // allowed limits, and returns an error if they are not.
    96  func (params *ConsensusParams) Validate() error {
    97  	if params.Block.MaxBytes <= 0 {
    98  		return cmn.NewError("Block.MaxBytes must be greater than 0. Got %d",
    99  			params.Block.MaxBytes)
   100  	}
   101  	if params.Block.MaxBytes > MaxBlockSizeBytes {
   102  		return cmn.NewError("Block.MaxBytes is too big. %d > %d",
   103  			params.Block.MaxBytes, MaxBlockSizeBytes)
   104  	}
   105  
   106  	if params.Block.MaxGas < -1 {
   107  		return cmn.NewError("Block.MaxGas must be greater or equal to -1. Got %d",
   108  			params.Block.MaxGas)
   109  	}
   110  
   111  	if params.Block.TimeIotaMs <= 0 {
   112  		return cmn.NewError("Block.TimeIotaMs must be greater than 0. Got %v",
   113  			params.Block.TimeIotaMs)
   114  	}
   115  
   116  	if params.Evidence.MaxAge <= 0 {
   117  		return cmn.NewError("EvidenceParams.MaxAge must be greater than 0. Got %d",
   118  			params.Evidence.MaxAge)
   119  	}
   120  
   121  	if len(params.Validator.PubKeyTypes) == 0 {
   122  		return cmn.NewError("len(Validator.PubKeyTypes) must be greater than 0")
   123  	}
   124  
   125  	// Check if keyType is a known ABCIPubKeyType
   126  	for i := 0; i < len(params.Validator.PubKeyTypes); i++ {
   127  		keyType := params.Validator.PubKeyTypes[i]
   128  		if _, ok := ABCIPubKeyTypesToAminoNames[keyType]; !ok {
   129  			return cmn.NewError("params.Validator.PubKeyTypes[%d], %s, is an unknown pubkey type",
   130  				i, keyType)
   131  		}
   132  	}
   133  
   134  	return nil
   135  }
   136  
   137  // Hash returns a hash of a subset of the parameters to store in the block header.
   138  // Only the Block.MaxBytes and Block.MaxGas are included in the hash.
   139  // This allows the ConsensusParams to evolve more without breaking the block
   140  // protocol. No need for a Merkle tree here, just a small struct to hash.
   141  func (params *ConsensusParams) Hash() []byte {
   142  	hasher := tmhash.New()
   143  	bz := cdcEncode(HashedParams{
   144  		params.Block.MaxBytes,
   145  		params.Block.MaxGas,
   146  	})
   147  	if bz == nil {
   148  		panic("cannot fail to encode ConsensusParams")
   149  	}
   150  	hasher.Write(bz)
   151  	return hasher.Sum(nil)
   152  }
   153  
   154  func (params *ConsensusParams) Equals(params2 *ConsensusParams) bool {
   155  	return params.Block == params2.Block &&
   156  		params.Evidence == params2.Evidence &&
   157  		cmn.StringSliceEqual(params.Validator.PubKeyTypes, params2.Validator.PubKeyTypes)
   158  }
   159  
   160  // Update returns a copy of the params with updates from the non-zero fields of p2.
   161  // NOTE: note: must not modify the original
   162  func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusParams {
   163  	res := params // explicit copy
   164  
   165  	if params2 == nil {
   166  		return res
   167  	}
   168  
   169  	// we must defensively consider any structs may be nil
   170  	if params2.Block != nil {
   171  		res.Block.MaxBytes = params2.Block.MaxBytes
   172  		res.Block.MaxGas = params2.Block.MaxGas
   173  	}
   174  	if params2.Evidence != nil {
   175  		res.Evidence.MaxAge = params2.Evidence.MaxAge
   176  	}
   177  	if params2.Validator != nil {
   178  		// Copy params2.Validator.PubkeyTypes, and set result's value to the copy.
   179  		// This avoids having to initialize the slice to 0 values, and then write to it again.
   180  		res.Validator.PubKeyTypes = append([]string{}, params2.Validator.PubKeyTypes...)
   181  	}
   182  	return res
   183  }