tmconsensustest

package
v0.0.0-...-434d902 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 7, 2025 License: Apache-2.0 Imports: 16 Imported by: 2

Documentation

Overview

Package tmconsensustest contains utilities helpful for interacting with tmconsensus types in tests.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func TestHashSchemeCompliance

TestHashSchemeCompliance runs the compliance tests for a hashing scheme.

makeDefaultHeader should only be set if the hash scheme has specific restrictions on block headers, such as expecting certain values to have exact lengths. It is acceptable for makeDefaultHeader to panic on error. If makeDefaultHeader is nil, a default header maker function is used.

We currently assume that a hashing scheme value is stateless, and so a single value can be used for all tests.

Types

type AnnotationTestCase

type AnnotationTestCase struct {
	Name        string
	Annotations tmconsensus.Annotations
}

AnnotationTestCase is a name and an Annotations value. See AnnotationCombinations for more details.

func AnnotationCombinations

func AnnotationCombinations() []AnnotationTestCase

AnnotationCombinations returns a slice of AnnotationTestCase with every combination of nil, 0-length slice, and populated User and Driver fields set on the Annotations.

These are useful in tests involving annotations, to avoid repetition and to be sure that all cases are covered.

type ChannelConsensusHandler

type ChannelConsensusHandler struct {
	// contains filtered or unexported fields
}

ChannelConsensusHandler is a tmconsensus.ConsensusHandler that emits messages to a set of channels.

This is useful in tests where you have a "client-only" connection and you want to observe messages sent to the network, without interfering with any individual engine.

func NewChannelConsensusHandler

func NewChannelConsensusHandler(bufSize int) *ChannelConsensusHandler

NewChannelConsensusHandler returns a ChannelConsensusHandler whose channels are all sized according to bufSize.

func (*ChannelConsensusHandler) Close

func (h *ChannelConsensusHandler) Close()

Close closes h. It is safe to call Close multiple times.

func (*ChannelConsensusHandler) HandlePrecommitProofs

func (*ChannelConsensusHandler) HandlePrevoteProofs

func (*ChannelConsensusHandler) HandleProposedHeader

HandleProposedProposedHeader implements tmconsensus.ConsensusHandler.

func (*ChannelConsensusHandler) IncomingPrecommitProofs

func (h *ChannelConsensusHandler) IncomingPrecommitProofs() <-chan tmconsensus.PrecommitSparseProof

IncomingPrecommitProofs returns a channel of the values that were passed to HandlePrecommitProof.

func (*ChannelConsensusHandler) IncomingPrevoteProofs

func (h *ChannelConsensusHandler) IncomingPrevoteProofs() <-chan tmconsensus.PrevoteSparseProof

IncomingPrevoteProofs returns a channel of the values that were passed to HandlePrevoteProof.

func (*ChannelConsensusHandler) IncomingProposals

func (h *ChannelConsensusHandler) IncomingProposals() <-chan tmconsensus.ProposedHeader

IncomingProposals returns a channel of the values that were passed to HandleProposedHeader.

type ChooseProposedBlockRequest

type ChooseProposedBlockRequest struct {
	Input       []tmconsensus.ProposedHeader
	ChoiceHash  chan string
	ChoiceError chan error
}

ChooseProposedBlockRequest is sent on [MockConsensusStrategy.ChooseProposedBlockRequests] upon a call to ChooseProposedBlock.

The test must send one value on either of the 1-buffered ChoiceHash or ChoiceError channels in order for the ChooseProposedBlock method to return (or cancel the context passed to the method).

type ConsiderProposedBlocksRequest

type ConsiderProposedBlocksRequest struct {
	PHs         []tmconsensus.ProposedHeader
	Reason      tmconsensus.ConsiderProposedBlocksReason
	ChoiceHash  chan string
	ChoiceError chan error
}

ConsiderProposedBlocksRequest is sent on [MockConsensusStrategy.ConsiderProposedBlocksRequest] upon a call to ConsiderProposedBlocks.

The test must send one value on either of the 1-buffered ChoiceHash or ChoiceError channels in order for the ChooseProposedBlock method to return (or cancel the context passed to the method).

type DecidePrecommitRequest

type DecidePrecommitRequest struct {
	Input       tmconsensus.VoteSummary
	ChoiceHash  chan string
	ChoiceError chan error
}

type EnterRoundCall

type EnterRoundCall struct {
	RV          tmconsensus.RoundView
	ProposalOut chan<- tmconsensus.Proposal
}

EnterRoundCall holds the arguments provided to a call to tmconsensus.ConsensusStrategy.EnterRound. The test may send a value to the ProposalOut channel in order to simulate the application proposing data to be included in a block.

type Fixture

type Fixture struct {
	PrivVals PrivVals

	SignatureScheme tmconsensus.SignatureScheme

	HashScheme tmconsensus.HashScheme

	CommonMessageSignatureProofScheme gcrypto.CommonMessageSignatureProofScheme

	Genesis tmconsensus.Genesis

	Registry gcrypto.Registry
	// contains filtered or unexported fields
}

Fixture is a set of values used for typical test flows involving validators and voting, with some convenience methods for common test actions.

Most Gordian core tests will use the NewEd25519Fixture method. This type is uncoupled from any particular concrete implementations in order to facilitate tests with external signer types.

func NewBareFixture

func NewBareFixture() *Fixture

NewBareFixture returns a Fixture with the default testing schemes, and with appropriately initialized unexported fields.

Callers must still set the Registry and PrivVals fields, and they may optionally override any of the Scheme fields.

This function is preferred over direct instantiation of a Fixture due to the unexported fields.

func NewEd25519Fixture

func NewEd25519Fixture(numVals int) *Fixture

NewEd25519Fixture returns an initialized Fixture with the given number of determinstic ed25519 validators, a SimpleSignatureScheme, and a SimpleHashScheme.

See the Fixture docs for other fields that have default values but which may be overridden before use.

func (*Fixture) CommitBlock

func (f *Fixture) CommitBlock(h tmconsensus.Header, appStateHash []byte, round uint32, commit map[string]gcrypto.CommonMessageSignatureProof)

CommitBlock uses the input arguments to set up the next call to NextProposedHeader. The commit parameter is the set of precommits to associate with the block being committed, which will then be used as the previous commit details.

func (*Fixture) DefaultGenesis

func (f *Fixture) DefaultGenesis() tmconsensus.Genesis

DefaultGenesis returns a simple genesis suitable for basic tests.

func (*Fixture) NewMemValidatorStore

func (f *Fixture) NewMemValidatorStore() *tmmemstore.ValidatorStore

func (*Fixture) NextProposedHeader

func (f *Fixture) NextProposedHeader(appDataID []byte, valIdx int) tmconsensus.ProposedHeader

NextProposedHeader returns a proposed header, with height set to the last committed height + 1, at Round zero, and with the previous block hash set to the last committed block's height.

The valIdx parameter indicates which of f's validators to set as ProposerID. The returned proposal is unsigned; use f.SignProposal to set a valid signature.

Both Validators and NextValidators are set to f.Vals(). These and other fields may be overridden, in which case you should call f.RecalculateHash and f.SignProposal again.

func (*Fixture) PrecommitProofMap

func (f *Fixture) PrecommitProofMap(
	ctx context.Context,
	height uint64,
	round uint32,
	voteMap map[string][]int,
) map[string]gcrypto.CommonMessageSignatureProof

PrecommitProofMap creates a map of precommit signatures that can be passed directly to [tmstore.ConsensusStore.OverwritePrecommitProof].

func (*Fixture) PrecommitSignature

func (f *Fixture) PrecommitSignature(
	ctx context.Context,
	vt tmconsensus.VoteTarget,
	valIdx int,
) []byte

PrecommitSignature returns the signature for the validator at valIdx against the given vote target, respecting vt.BlockHash in deciding whether the vote is active or nil.

func (*Fixture) PrecommitSignatureProof

func (f *Fixture) PrecommitSignatureProof(
	ctx context.Context,
	vt tmconsensus.VoteTarget,
	blockVals []tmconsensus.Validator,
	valIdxs []int,
) gcrypto.CommonMessageSignatureProof

PrecommitSignatureProof returns a CommonMessageSignatureProof for a precommit represented by the VoteTarget.

If blockVals is nil, use f's Validators. If the block has a different set of validators from f, explicitly set blockVals.

valIdxs is the set of indices of f's Validators, whose signatures should be part of the proof. These indices refer to f's Validators, and are not necessarily related to blockVals.

func (*Fixture) PrevoteProofMap

func (f *Fixture) PrevoteProofMap(
	ctx context.Context,
	height uint64,
	round uint32,
	voteMap map[string][]int,
) map[string]gcrypto.CommonMessageSignatureProof

PrevoteProofMap creates a map of prevote signatures that can be passed directly to [tmstore.ConsensusStore.OverwritePrevoteProof].

func (*Fixture) PrevoteSignature

func (f *Fixture) PrevoteSignature(
	ctx context.Context,
	vt tmconsensus.VoteTarget,
	valIdx int,
) []byte

PrevoteSignature returns the signature for the validator at valIdx against the given vote target, respecting vt.BlockHash in deciding whether the vote is active or nil.

func (*Fixture) PrevoteSignatureProof

func (f *Fixture) PrevoteSignatureProof(
	ctx context.Context,
	vt tmconsensus.VoteTarget,
	blockVals []tmconsensus.Validator,
	valIdxs []int,
) gcrypto.CommonMessageSignatureProof

PrevoteSignatureProof returns a CommonMessageSignatureProof for a prevote represented by the VoteTarget.

If blockVals is nil, use f's Validators. If the block has a different set of validators from f, explicitly set blockVals.

valIdxs is the set of indices of f's Validators, whose signatures should be part of the proof. These indices refer to f's Validators, and are not necessarily related to blockVals.

func (*Fixture) RecalculateHash

func (f *Fixture) RecalculateHash(h *tmconsensus.Header)

RecalculateHash modifies h.Hash using f.HashScheme. This is useful if a block is modified by hand for any reason. If calculating the hash results in an error, this method panics.

func (*Fixture) SignProposal

func (f *Fixture) SignProposal(ctx context.Context, ph *tmconsensus.ProposedHeader, valIdx int)

SignProposal sets the signature on the proposed header ph, using the validator at f.PrivVals[valIdx]. On error, SignProposal panics.

func (*Fixture) SparsePrecommitProofMap

func (f *Fixture) SparsePrecommitProofMap(
	ctx context.Context,
	height uint64,
	round uint32,
	voteMap map[string][]int,
) map[string][]gcrypto.SparseSignature

SparsePrecommitProofMap returns a map of block hashes to sparse signature lists, which can be used to populate a CommitProof.

func (*Fixture) SparsePrecommitSignatureCollection

func (f *Fixture) SparsePrecommitSignatureCollection(
	ctx context.Context,
	height uint64,
	round uint32,
	voteMap map[string][]int,
) tmconsensus.SparseSignatureCollection

func (*Fixture) SparsePrevoteProofMap

func (f *Fixture) SparsePrevoteProofMap(
	ctx context.Context,
	height uint64,
	round uint32,
	voteMap map[string][]int,
) map[string][]gcrypto.SparseSignature

SparsePrevoteProofMap returns a map of block hashes to sparse signature lists, which can be used to populate a PrevoteSparseProof.

func (*Fixture) SparsePrevoteSignatureCollection

func (f *Fixture) SparsePrevoteSignatureCollection(
	ctx context.Context,
	height uint64,
	round uint32,
	voteMap map[string][]int,
) tmconsensus.SparseSignatureCollection

func (*Fixture) UpdateVRVPrecommits

func (f *Fixture) UpdateVRVPrecommits(
	ctx context.Context,
	vrv tmconsensus.VersionedRoundView,
	voteMap map[string][]int,
) tmconsensus.VersionedRoundView

UpdateVRVPrecommits returns a clone of vrv, with its version incremented and with all its precommit information updated to match the provided voteMap (which is a map of block hashes to voting validator indices).

func (*Fixture) UpdateVRVPrevotes

func (f *Fixture) UpdateVRVPrevotes(
	ctx context.Context,
	vrv tmconsensus.VersionedRoundView,
	voteMap map[string][]int,
) tmconsensus.VersionedRoundView

UpdateVRVPrevotes returns a clone of vrv, with its version incremented and with all its prevote information updated to match the provided voteMap (which is a map of block hashes to voting validator indices).

func (*Fixture) ValSet

func (f *Fixture) ValSet() tmconsensus.ValidatorSet

func (*Fixture) ValidatorHashes

func (f *Fixture) ValidatorHashes() (pubKeyHash, powHash string)

func (*Fixture) ValidatorPubKey

func (f *Fixture) ValidatorPubKey(idx int) gcrypto.PubKey

func (*Fixture) ValidatorPubKeyString

func (f *Fixture) ValidatorPubKeyString(idx int) string

func (*Fixture) Vals

func (f *Fixture) Vals() []tmconsensus.Validator

type MockConsensusStrategy

type MockConsensusStrategy struct {
	ConsiderProposedBlocksRequests <-chan ConsiderProposedBlocksRequest // Exported receive-only.

	ChooseProposedBlockRequests <-chan ChooseProposedBlockRequest // Exported receive-only.

	DecidePrecommitRequests <-chan DecidePrecommitRequest // Exported receive-only.
	// contains filtered or unexported fields
}

MockConsensusStrategy is an implementation of tmconsensus.ConsensusStrategy for ease of testing.

func NewMockConsensusStrategy

func NewMockConsensusStrategy() *MockConsensusStrategy

func (*MockConsensusStrategy) ChooseProposedBlock

func (s *MockConsensusStrategy) ChooseProposedBlock(
	ctx context.Context, phs []tmconsensus.ProposedHeader,
) (string, error)

func (*MockConsensusStrategy) ConsiderProposedBlocks

func (*MockConsensusStrategy) DecidePrecommit

func (s *MockConsensusStrategy) DecidePrecommit(
	ctx context.Context, vs tmconsensus.VoteSummary,
) (string, error)

func (*MockConsensusStrategy) EnterRound

func (s *MockConsensusStrategy) EnterRound(
	ctx context.Context,
	rv tmconsensus.RoundView,
	proposalOut chan<- tmconsensus.Proposal,
) error

func (*MockConsensusStrategy) ExpectEnterRound

func (s *MockConsensusStrategy) ExpectEnterRound(
	height uint64, round uint32,
	returnErr error,
) <-chan EnterRoundCall

ExpectEnterRound returns a channel that receives the RoundView value once there is a call to EnterRound with a block matching the given height and round.

type NopConsensusStrategy

type NopConsensusStrategy struct{}

NopConsensusStrategy is a tmconsensus.ConsensusStrategy that always prevotes and precommits nil.

This should only be used as a placeholder in tests that require the presence of, but do not interact with, a consensus strategy.

func (NopConsensusStrategy) ChooseProposedBlock

func (NopConsensusStrategy) ChooseProposedBlock(ctx context.Context, phs []tmconsensus.ProposedHeader) (string, error)

func (NopConsensusStrategy) ConsiderProposedBlocks

func (NopConsensusStrategy) DecidePrecommit

func (NopConsensusStrategy) EnterRound

type PrivVal

type PrivVal struct {
	// The plain consensus validator.
	Val tmconsensus.Validator

	Signer gcrypto.Signer
}

PrivVal is the "private" view of the validators for use in the Fixture type, so that tests have access to the Signers backing the validators too.

type PrivVals

type PrivVals []PrivVal

func DeterministicValidatorsEd25519

func DeterministicValidatorsEd25519(n int) PrivVals

DeterministicValidatorsEd25519 returns a deterministic set of validators with ed25519 keys.

Each validator will have its VotingPower set to 1.

There are two advantages to using deterministic keys. First, subsequent runs of the same test will use the same keys, so logs involving keys or IDs will not change across runs, simplifying the debugging process. Second, the generated keys are cached, so there is effectively zero CPU time cost for additional tests calling this function, beyond the first call.

func (PrivVals) PubKeys

func (vs PrivVals) PubKeys() []gcrypto.PubKey

func (PrivVals) Vals

func (vs PrivVals) Vals() []tmconsensus.Validator

type SimpleHashScheme

type SimpleHashScheme struct{}

func (SimpleHashScheme) Block

func (SimpleHashScheme) PubKeys

func (SimpleHashScheme) PubKeys(keys []gcrypto.PubKey) ([]byte, error)

func (SimpleHashScheme) VotePowers

func (SimpleHashScheme) VotePowers(pows []uint64) ([]byte, error)

type SimpleSignatureScheme

type SimpleSignatureScheme struct{}

SimpleSignatureScheme is a very basic signature scheme used for tests. Its produced signing content is intended to be human-readable and delimited across multiple lines, so that if unexpected content is being signed, it ought to be straightforward to determine what incorrect content was used.

If this scheme were used in production, it could be used for replay attacks on other chains that reuse the same validator private keys; at a minimum, the chain ID would need to be included.

func (SimpleSignatureScheme) WritePrecommitSigningContent

func (s SimpleSignatureScheme) WritePrecommitSigningContent(w io.Writer, vt tmconsensus.VoteTarget) (int, error)

func (SimpleSignatureScheme) WritePrevoteSigningContent

func (s SimpleSignatureScheme) WritePrevoteSigningContent(w io.Writer, vt tmconsensus.VoteTarget) (int, error)

func (SimpleSignatureScheme) WriteProposalSigningContent

func (s SimpleSignatureScheme) WriteProposalSigningContent(
	w io.Writer, h tmconsensus.Header, round uint32, pbAnnotations tmconsensus.Annotations,
) (int, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL