diff --git a/state/state.go b/state/state.go index ca4e8ffd1..74504f0a3 100644 --- a/state/state.go +++ b/state/state.go @@ -273,8 +273,8 @@ func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader typ // Update validator accums and set state variables nextValSet.IncrementAccum(1) - nextParams := applyUpdates(s.ConsensusParams, - abciResponses.EndBlock.ConsensusParamUpdates) + // NOTE: must not mutate s.ConsensusParams + nextParams := s.ConsensusParams.Update(abciResponses.EndBlock.ConsensusParamUpdates) err := nextParams.Validate() if err != nil { s.logger.Error("Error updating consensus params", "err", err) @@ -291,45 +291,6 @@ func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader typ } -// applyUpdates returns new ConsensusParams -// whose fields are set to any non-zero fields of c. -// If c is nil, it returns p unmodified, as it was passed in. -func applyUpdates(p types.ConsensusParams, - c *abci.ConsensusParams) types.ConsensusParams { - - if c == nil { - return p - } - res := p - // we must defensively consider any structs may be nil - if c.BlockSize != nil { - - if c.BlockSize.MaxBytes != 0 { - res.BlockSize.MaxBytes = int(c.BlockSize.MaxBytes) - } - if c.BlockSize.MaxTxs != 0 { - res.BlockSize.MaxTxs = int(c.BlockSize.MaxTxs) - } - if c.BlockSize.MaxGas != 0 { - res.BlockSize.MaxGas = int(c.BlockSize.MaxGas) - } - } - if c.TxSize != nil { - if c.TxSize.MaxBytes != 0 { - res.TxSize.MaxBytes = int(c.TxSize.MaxBytes) - } - if c.TxSize.MaxGas != 0 { - res.TxSize.MaxGas = int(c.TxSize.MaxGas) - } - } - if c.BlockGossip != nil { - if c.BlockGossip.BlockPartSizeBytes != 0 { - res.BlockGossip.BlockPartSizeBytes = int(c.BlockGossip.BlockPartSizeBytes) - } - } - return res -} - func (s *State) setBlockAndValidators(height int64, newTxs int64, blockID types.BlockID, blockTime time.Time, valSet *types.ValidatorSet, diff --git a/types/params.go b/types/params.go index e7c32f48f..19e86d449 100644 --- a/types/params.go +++ b/types/params.go @@ -3,6 +3,7 @@ package types import ( "github.com/pkg/errors" + abci "github.com/tendermint/abci/types" "github.com/tendermint/tmlibs/merkle" ) @@ -20,15 +21,15 @@ type ConsensusParams struct { // BlockSize contain limits on the block size. type BlockSize struct { - MaxBytes int `json:"max_bytes"` // NOTE: must not be 0 nor greater than 100MB - MaxTxs int `json:"max_txs"` - MaxGas int `json:"max_gas"` + MaxBytes int `json:"max_bytes"` // NOTE: must not be 0 nor greater than 100MB + MaxTxs int `json:"max_txs"` + MaxGas int64 `json:"max_gas"` } // TxSize contain limits on the tx size. type TxSize struct { - MaxBytes int `json:"max_bytes"` - MaxGas int `json:"max_gas"` + MaxBytes int `json:"max_bytes"` + MaxGas int64 `json:"max_gas"` } // BlockGossip determine consensus critical elements of how blocks are gossiped @@ -100,3 +101,42 @@ func (params *ConsensusParams) Hash() []byte { "tx_size_max_gas": params.TxSize.MaxGas, }) } + +// Update returns a copy of the params with updates from the non-zero fields of p2. +// NOTE: note: must not modify the original +func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusParams { + res := params // explicit copy + + if params2 == nil { + return res + } + + // we must defensively consider any structs may be nil + // XXX: it's cast city over here. It's ok because we only do int32->int + // but still, watch it champ. + if params2.BlockSize != nil { + if params2.BlockSize.MaxBytes > 0 { + res.BlockSize.MaxBytes = int(params2.BlockSize.MaxBytes) + } + if params2.BlockSize.MaxTxs > 0 { + res.BlockSize.MaxTxs = int(params2.BlockSize.MaxTxs) + } + if params2.BlockSize.MaxGas > 0 { + res.BlockSize.MaxGas = params2.BlockSize.MaxGas + } + } + if params2.TxSize != nil { + if params2.TxSize.MaxBytes > 0 { + res.TxSize.MaxBytes = int(params2.TxSize.MaxBytes) + } + if params2.TxSize.MaxGas > 0 { + res.TxSize.MaxGas = params2.TxSize.MaxGas + } + } + if params2.BlockGossip != nil { + if params2.BlockGossip.BlockPartSizeBytes > 0 { + res.BlockGossip.BlockPartSizeBytes = int(params2.BlockGossip.BlockPartSizeBytes) + } + } + return res +}