mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
Also lazily load the commits to only be run once when the benchmarks are activated, lest it slows down all the tests
154 lines
4.4 KiB
Go
154 lines
4.4 KiB
Go
package lite
|
|
|
|
import (
|
|
"time"
|
|
|
|
crypto "github.com/tendermint/go-crypto"
|
|
|
|
"github.com/tendermint/tendermint/types"
|
|
)
|
|
|
|
// ValKeys is a helper for testing.
|
|
//
|
|
// It lets us simulate signing with many keys, either ed25519 or secp256k1.
|
|
// The main use case is to create a set, and call GenCommit
|
|
// to get properly signed header for testing.
|
|
//
|
|
// You can set different weights of validators each time you call
|
|
// ToValidators, and can optionally extend the validator set later
|
|
// with Extend or ExtendSecp
|
|
type ValKeys []crypto.PrivKey
|
|
|
|
// GenValKeys produces an array of private keys to generate commits.
|
|
func GenValKeys(n int) ValKeys {
|
|
res := make(ValKeys, n)
|
|
for i := range res {
|
|
res[i] = crypto.GenPrivKeyEd25519().Wrap()
|
|
}
|
|
return res
|
|
}
|
|
|
|
// Change replaces the key at index i.
|
|
func (v ValKeys) Change(i int) ValKeys {
|
|
res := make(ValKeys, len(v))
|
|
copy(res, v)
|
|
res[i] = crypto.GenPrivKeyEd25519().Wrap()
|
|
return res
|
|
}
|
|
|
|
// Extend adds n more keys (to remove, just take a slice).
|
|
func (v ValKeys) Extend(n int) ValKeys {
|
|
extra := GenValKeys(n)
|
|
return append(v, extra...)
|
|
}
|
|
|
|
// GenSecpValKeys produces an array of secp256k1 private keys to generate commits.
|
|
func GenSecpValKeys(n int) ValKeys {
|
|
res := make(ValKeys, n)
|
|
for i := range res {
|
|
res[i] = crypto.GenPrivKeySecp256k1().Wrap()
|
|
}
|
|
return res
|
|
}
|
|
|
|
// ExtendSecp adds n more secp256k1 keys (to remove, just take a slice).
|
|
func (v ValKeys) ExtendSecp(n int) ValKeys {
|
|
extra := GenSecpValKeys(n)
|
|
return append(v, extra...)
|
|
}
|
|
|
|
// ToValidators produces a list of validators from the set of keys
|
|
// The first key has weight `init` and it increases by `inc` every step
|
|
// so we can have all the same weight, or a simple linear distribution
|
|
// (should be enough for testing).
|
|
func (v ValKeys) ToValidators(init, inc int64) *types.ValidatorSet {
|
|
res := make([]*types.Validator, len(v))
|
|
for i, k := range v {
|
|
res[i] = types.NewValidator(k.PubKey(), init+int64(i)*inc)
|
|
}
|
|
return types.NewValidatorSet(res)
|
|
}
|
|
|
|
// signHeader properly signs the header with all keys from first to last exclusive.
|
|
func (v ValKeys) signHeader(header *types.Header, first, last int) *types.Commit {
|
|
votes := make([]*types.Vote, len(v))
|
|
|
|
// we need this list to keep the ordering...
|
|
vset := v.ToValidators(1, 0)
|
|
|
|
// fill in the votes we want
|
|
for i := first; i < last && i < len(v); i++ {
|
|
vote := makeVote(header, vset, v[i])
|
|
votes[vote.ValidatorIndex] = vote
|
|
}
|
|
|
|
res := &types.Commit{
|
|
BlockID: types.BlockID{Hash: header.Hash()},
|
|
Precommits: votes,
|
|
}
|
|
return res
|
|
}
|
|
|
|
func makeVote(header *types.Header, vals *types.ValidatorSet, key crypto.PrivKey) *types.Vote {
|
|
addr := key.PubKey().Address()
|
|
idx, _ := vals.GetByAddress(addr)
|
|
vote := &types.Vote{
|
|
ValidatorAddress: addr,
|
|
ValidatorIndex: idx,
|
|
Height: header.Height,
|
|
Round: 1,
|
|
Timestamp: time.Now().UTC(),
|
|
Type: types.VoteTypePrecommit,
|
|
BlockID: types.BlockID{Hash: header.Hash()},
|
|
}
|
|
// Sign it
|
|
signBytes := types.SignBytes(header.ChainID, vote)
|
|
vote.Signature = key.Sign(signBytes)
|
|
return vote
|
|
}
|
|
|
|
// Silences warning that vals can also be merkle.Hashable
|
|
// nolint: interfacer
|
|
func genHeader(chainID string, height int64, txs types.Txs,
|
|
vals *types.ValidatorSet, appHash, consHash, resHash []byte) *types.Header {
|
|
|
|
return &types.Header{
|
|
ChainID: chainID,
|
|
Height: height,
|
|
Time: time.Now(),
|
|
NumTxs: int64(len(txs)),
|
|
TotalTxs: int64(len(txs)),
|
|
// LastBlockID
|
|
// LastCommitHash
|
|
ValidatorsHash: vals.Hash(),
|
|
DataHash: txs.Hash(),
|
|
AppHash: appHash,
|
|
ConsensusHash: consHash,
|
|
LastResultsHash: resHash,
|
|
}
|
|
}
|
|
|
|
// GenCommit calls genHeader and signHeader and combines them into a Commit.
|
|
func (v ValKeys) GenCommit(chainID string, height int64, txs types.Txs,
|
|
vals *types.ValidatorSet, appHash, consHash, resHash []byte, first, last int) Commit {
|
|
|
|
header := genHeader(chainID, height, txs, vals, appHash, consHash, resHash)
|
|
check := Commit{
|
|
Header: header,
|
|
Commit: v.signHeader(header, first, last),
|
|
}
|
|
return check
|
|
}
|
|
|
|
// GenFullCommit calls genHeader and signHeader and combines them into a Commit.
|
|
func (v ValKeys) GenFullCommit(chainID string, height int64, txs types.Txs,
|
|
vals *types.ValidatorSet, appHash, consHash, resHash []byte, first, last int) FullCommit {
|
|
|
|
header := genHeader(chainID, height, txs, vals, appHash, consHash, resHash)
|
|
commit := Commit{
|
|
Header: header,
|
|
Commit: v.signHeader(header, first, last),
|
|
}
|
|
return NewFullCommit(commit, vals)
|
|
}
|