diff --git a/types/params.go b/types/params.go index 322cba61..c17196be 100644 --- a/types/params.go +++ b/types/params.go @@ -2,6 +2,8 @@ package types import ( "github.com/pkg/errors" + + "github.com/tendermint/tmlibs/merkle" ) const ( @@ -85,3 +87,16 @@ func (params *ConsensusParams) Validate() error { } return nil } + +// Hash returns a merkle hash of the parameters to store +// in the block header +func (params *ConsensusParams) Hash() []byte { + return merkle.SimpleHashFromMap(map[string]interface{}{ + "block_gossip_part_size_bytes": params.BlockGossipParams.BlockPartSizeBytes, + "block_size_max_bytes": params.BlockSizeParams.MaxBytes, + "block_size_max_gas": params.BlockSizeParams.MaxGas, + "block_size_max_txs": params.BlockSizeParams.MaxTxs, + "tx_size_max_bytes": params.TxSizeParams.MaxBytes, + "tx_size_max_gas": params.TxSizeParams.MaxGas, + }) +} diff --git a/types/params_test.go b/types/params_test.go index 507c8513..899ca8e1 100644 --- a/types/params_test.go +++ b/types/params_test.go @@ -1,6 +1,8 @@ package types import ( + "bytes" + "sort" "testing" "github.com/stretchr/testify/assert" @@ -38,3 +40,49 @@ func TestConsensusParamsValidation(t *testing.T) { } } } + +func makeParams(blockBytes, blockTx, blockGas, txBytes, + txGas, partSize int) ConsensusParams { + + return ConsensusParams{ + BlockSizeParams: BlockSizeParams{ + MaxBytes: blockBytes, + MaxTxs: blockTx, + MaxGas: blockGas, + }, + TxSizeParams: TxSizeParams{ + MaxBytes: txBytes, + MaxGas: txGas, + }, + BlockGossipParams: BlockGossipParams{ + BlockPartSizeBytes: partSize, + }, + } +} + +func TestConsensusParamsHash(t *testing.T) { + params := []ConsensusParams{ + makeParams(1, 2, 3, 4, 5, 6), + makeParams(7, 2, 3, 4, 5, 6), + makeParams(1, 7, 3, 4, 5, 6), + makeParams(1, 2, 7, 4, 5, 6), + makeParams(1, 2, 3, 7, 5, 6), + makeParams(1, 2, 3, 4, 7, 6), + makeParams(1, 2, 3, 4, 5, 7), + makeParams(6, 5, 4, 3, 2, 1), + } + + hashes := make([][]byte, len(params)) + for i := range params { + hashes[i] = params[i].Hash() + } + + // make sure there are no duplicates... + // sort, then check in order for matches + sort.Slice(hashes, func(i, j int) bool { + return bytes.Compare(hashes[i], hashes[j]) < 0 + }) + for i := 0; i < len(hashes)-1; i++ { + assert.NotEqual(t, hashes[i], hashes[i+1]) + } +}