Documentation
¶
Overview ¶
Package testutil provides shared test infrastructure for the Shielded-Vote chain integration tests. It includes reusable message constructors, raw tx encoding helpers, and a TestApp that wraps SvoteApp for in-process ABCI testing.
Index ¶
- Constants
- func ActiveRoundFixture(roundID []byte) *types.VoteRound
- func DefaultOptions() []*types.VoteOption
- func ExpiredCreateVotingSessionAt(refTime time.Time) *types.MsgCreateVotingSession
- func FpLE(v uint64) []byte
- func MakeNullifier(seed byte) []byte
- func MustEncodeAckCeremonyTx(msg proto.Message) []byte
- func MustEncodeVoteTx(msg types.VoteMessage) []byte
- func SampleProposals() []*types.Proposal
- func ShuffleWithSeed[T any](in []T, seed uint64) []T
- func TestAccAddr(seed byte) string
- func TestValAddr(seed byte) string
- func ValidCastVote(roundID []byte, anchorHeight uint64, nullifierSeed byte) *types.MsgCastVote
- func ValidCastVoteN(roundID []byte, anchorHeight uint64, n int, seed uint64) []*types.MsgCastVote
- func ValidCreateVotingSession() *types.MsgCreateVotingSession
- func ValidCreateVotingSessionAt(refTime time.Time) *types.MsgCreateVotingSession
- func ValidCreateVotingSessionWithEndTime(endTime time.Time) *types.MsgCreateVotingSession
- func ValidDelegation(roundID []byte, nullifierSeed byte) *types.MsgDelegateVote
- func ValidDelegationN(roundID []byte, n int, seed uint64) []*types.MsgDelegateVote
- func ValidRevealShare(roundID []byte, anchorHeight uint64, nullifierSeed byte) *types.MsgRevealShare
- func ValidRevealShareReal(roundID []byte, anchorHeight uint64, nullifierSeed byte, proposalID uint32, ...) *types.MsgRevealShare
- func ValidSubmitTally(roundID []byte, creator string) *types.MsgSubmitTally
- func ValidSubmitTallyWithEntries(roundID []byte, creator string, entries []*types.TallyEntry) *types.MsgSubmitTally
- type NullifierConflictSet
- type TestApp
- func (ta *TestApp) CallPrepareProposal() *abci.ResponsePrepareProposal
- func (ta *TestApp) CallPrepareProposalWithTxs(txs [][]byte) *abci.ResponsePrepareProposal
- func (ta *TestApp) CallProcessProposal(txs [][]byte) *abci.ResponseProcessProposal
- func (ta *TestApp) CheckTxSync(txBytes []byte) *abci.ResponseCheckTx
- func (ta *TestApp) DeliverVoteTx(txBytes []byte) *abci.ExecTxResult
- func (ta *TestApp) DeliverVoteTxs(txs [][]byte) []*abci.ExecTxResult
- func (ta *TestApp) MustBuildSignedCeremonyTx(msg sdk.Msg) []byte
- func (ta *TestApp) NextBlock()
- func (ta *TestApp) NextBlockAtTime(t time.Time)
- func (ta *TestApp) NextBlockWithPrepareProposal()
- func (ta *TestApp) RecheckTxSync(txBytes []byte) *abci.ResponseCheckTx
- func (ta *TestApp) SeedConfirmedCeremony(_ []byte)
- func (ta *TestApp) SeedDealtCeremony(pallasPkBytes, eaPkBytes []byte, payloads []*types.DealerPayload, ...) []byte
- func (ta *TestApp) SeedDealtCeremonyThreshold(eaPkBytes []byte, payloads []*types.DealerPayload, ...) []byte
- func (ta *TestApp) SeedRegisteringCeremony(validators []*types.ValidatorPallasKey) []byte
- func (ta *TestApp) SeedTallyingRoundThreshold(roundID []byte, threshold uint32, proposals []*types.Proposal, ...) []byte
- func (ta *TestApp) SeedVoteManager(addr string)
- func (ta *TestApp) SeedVotingSession(msg *types.MsgCreateVotingSession) []byte
- func (ta *TestApp) ValidatorAccAddr() string
- func (ta *TestApp) ValidatorOperAddr() string
- func (ta *TestApp) VoteKeeper() *votekeeper.Keeper
- func (ta *TestApp) WriteEaSkForRound(roundID []byte, eaSkBytes []byte)
- func (ta *TestApp) WriteShareForRound(roundID []byte, shareBytes []byte)
Constants ¶
const TestAuthority = "sv1authority"
TestAuthority is the module authority address used by all keeper tests.
Variables ¶
This section is empty.
Functions ¶
func ActiveRoundFixture ¶
ActiveRoundFixture returns a VoteRound in ACTIVE status with sensible defaults. Used to seed keeper state directly in unit tests without going through CreateVotingSession.
func DefaultOptions ¶
func DefaultOptions() []*types.VoteOption
DefaultOptions returns the standard binary vote options (Support/Oppose).
func ExpiredCreateVotingSessionAt ¶
func ExpiredCreateVotingSessionAt(refTime time.Time) *types.MsgCreateVotingSession
ExpiredCreateVotingSessionAt returns a MsgCreateVotingSession with VoteEndTime in the past relative to the given reference time.
func FpLE ¶
FpLE returns a 32-byte little-endian encoding of v as a Pallas Fp element. Values 0 <= v < 2^64 are always canonical. Use for commitment tree leaves in tests.
func MakeNullifier ¶
MakeNullifier creates a deterministic 32-byte nullifier from a seed byte.
func MustEncodeAckCeremonyTx ¶
MustEncodeAckCeremonyTx encodes a MsgAckExecutiveAuthorityKey into the raw wire format [tag || protobuf_msg]. Only MsgAck uses the custom wire format; all other ceremony messages use standard Cosmos SDK transactions. Panics on encoding failure (safe for tests).
func MustEncodeVoteTx ¶
func MustEncodeVoteTx(msg types.VoteMessage) []byte
MustEncodeVoteTx encodes a VoteMessage into the raw wire format [tag || protobuf_msg] used by the custom ABCI pipeline. Panics on encoding failure (safe for tests).
func SampleProposals ¶
SampleProposals returns two sample proposals for test fixtures. Proposal IDs must be 1-indexed per ValidateBasic (expected 1, 2, ...).
func ShuffleWithSeed ¶
ShuffleWithSeed returns a deterministically shuffled copy of in.
func TestAccAddr ¶
TestAccAddr generates a deterministic valid bech32 account address from a seed byte.
func TestValAddr ¶
TestValAddr generates a deterministic valid bech32 validator operator address from a seed byte.
func ValidCastVote ¶
func ValidCastVote(roundID []byte, anchorHeight uint64, nullifierSeed byte) *types.MsgCastVote
ValidCastVote returns a MsgCastVote with mock data. VoteAuthorityNoteNew and VoteCommitment use canonical Fp encodings for the commitment tree. RVpkX and RVpkY are 32-byte stubs for condition 4 (Spend Authority). Sighash is computed on-chain by the ante handler from the message fields.
func ValidCastVoteN ¶
ValidCastVoteN returns n deterministic MsgCastVote messages with unique VAN nullifiers and commitment leaves. The seed controls reproducible generation.
func ValidCreateVotingSession ¶
func ValidCreateVotingSession() *types.MsgCreateVotingSession
ValidCreateVotingSession returns a MsgCreateVotingSession with all fields populated. The VoteEndTime is set 1 hour in the future from the reference time.
func ValidCreateVotingSessionAt ¶
func ValidCreateVotingSessionAt(refTime time.Time) *types.MsgCreateVotingSession
ValidCreateVotingSessionAt returns a MsgCreateVotingSession with VoteEndTime set relative to the given reference time. Use this when the block time is deterministic.
func ValidCreateVotingSessionWithEndTime ¶
func ValidCreateVotingSessionWithEndTime(endTime time.Time) *types.MsgCreateVotingSession
ValidCreateVotingSessionWithEndTime returns a MsgCreateVotingSession with an explicit VoteEndTime. Use when you need a specific end time (e.g. 10 seconds from block time).
func ValidDelegation ¶
func ValidDelegation(roundID []byte, nullifierSeed byte) *types.MsgDelegateVote
ValidDelegation returns a MsgDelegateVote with mock proof data. Each call returns unique gov nullifiers derived from the provided seed. CmxNew and VanCmx use canonical Fp encodings so the commitment tree FFI accepts them. Sighash is set to a dummy 32-byte value; chain only checks length + signature.
func ValidDelegationN ¶
func ValidDelegationN(roundID []byte, n int, seed uint64) []*types.MsgDelegateVote
ValidDelegationN returns n deterministic MsgDelegateVote messages with unique gov nullifiers and VAN commitments. The seed controls reproducible generation.
func ValidRevealShare ¶
func ValidRevealShare(roundID []byte, anchorHeight uint64, nullifierSeed byte) *types.MsgRevealShare
ValidRevealShare returns a MsgRevealShare with mock data. EncShare is a valid ElGamal identity ciphertext (two identity Pallas points) that passes keeper validation. The nullifierSeed only affects ShareNullifier.
func ValidRevealShareReal ¶
func ValidRevealShareReal(roundID []byte, anchorHeight uint64, nullifierSeed byte, proposalID uint32, decision uint32, encShare []byte, ) *types.MsgRevealShare
ValidRevealShareReal returns a MsgRevealShare with a real ElGamal ciphertext as the EncShare. Use this when testing end-to-end encryption/decryption.
func ValidSubmitTally ¶
func ValidSubmitTally(roundID []byte, creator string) *types.MsgSubmitTally
ValidSubmitTally returns a MsgSubmitTally for the given round ID and creator. By default it includes a single entry matching the default ValidRevealShare fixture (proposal_id=1, vote_decision=1, total_value=1000).
func ValidSubmitTallyWithEntries ¶
func ValidSubmitTallyWithEntries(roundID []byte, creator string, entries []*types.TallyEntry) *types.MsgSubmitTally
ValidSubmitTallyWithEntries returns a MsgSubmitTally with custom entries.
Types ¶
type NullifierConflictSet ¶
type NullifierConflictSet struct {
GovWinner *types.MsgDelegateVote
GovLoser *types.MsgDelegateVote
GovFresh *types.MsgDelegateVote
VanWinner *types.MsgCastVote
VanLoser *types.MsgCastVote
VanFresh *types.MsgCastVote
}
NullifierConflictSet contains conflicting/fresh tx fixtures for both delegation (gov nullifiers) and cast-vote (VAN nullifiers) race tests.
func BuildConflictingNullifierSet ¶
func BuildConflictingNullifierSet(roundID []byte, anchorHeight uint64, seed uint64) NullifierConflictSet
BuildConflictingNullifierSet builds deterministic tx fixtures where two txs intentionally conflict on the same nullifier and one tx is fresh.
type TestApp ¶
type TestApp struct {
*app.SvoteApp
Height int64
Time time.Time
// ProposerAddress is the consensus address of the genesis validator,
// passed in every FinalizeBlock request so the ante handler can verify
// that MsgSubmitTally creators match the block proposer.
ProposerAddress []byte
// ValPrivKey is the secp256k1 private key of the genesis validator's
// operator account. Used for signing ceremony messages in tests.
ValPrivKey *secp256k1.PrivKey
// EaSkDir is the directory for per-round ea_sk files, derived from
// the "vote.ea_sk_path" app option. Empty when no EA key is configured.
EaSkDir string
// EaPk is the EA public key (compressed Pallas point). When set, SeedVotingSession
// uses this instead of a zero placeholder.
EaPk []byte
// contains filtered or unexported fields
}
TestApp wraps SvoteApp with helpers for driving the ABCI lifecycle in integration tests. No CometBFT process or network is involved — tests call FinalizeBlock/Commit/CheckTx directly.
func SetupTestApp ¶
SetupTestApp creates a fresh SvoteApp backed by an in-memory database, initializes the chain with a proper genesis (including a genesis validator), and returns a TestApp ready for integration testing.
func SetupTestAppWithEAKey ¶
SetupTestAppWithEAKey creates a TestApp with a real ElGamal keypair for the EA (Election Authority). The secret key is written to a temp file and passed via the "vote.ea_sk_path" app option so that PrepareProposal can decrypt tallies. Returns both the TestApp and the public key for encrypting shares.
func SetupTestAppWithPallasKey ¶
func SetupTestAppWithPallasKey(t *testing.T) (ta *TestApp, pallasSk *elgamal.SecretKey, pallasPk *elgamal.PublicKey, eaSk *elgamal.SecretKey, eaPk *elgamal.PublicKey)
SetupTestAppWithPallasKey creates a TestApp with both an EA keypair and a Pallas keypair written to temp files and passed via app options. This enables testing the auto-ack PrepareProposal handler. Returns the TestApp, the validator's Pallas secret key, the EA secret key, and the EA public key.
func (*TestApp) CallPrepareProposal ¶
func (ta *TestApp) CallPrepareProposal() *abci.ResponsePrepareProposal
CallPrepareProposal builds a RequestPrepareProposal for the next block (current height+1, time+5s) and calls PrepareProposal on the app. Returns the response containing any auto-injected txs.
func (*TestApp) CallPrepareProposalWithTxs ¶
func (ta *TestApp) CallPrepareProposalWithTxs(txs [][]byte) *abci.ResponsePrepareProposal
CallPrepareProposalWithTxs builds a RequestPrepareProposal for the next block with the given mempool txs and calls PrepareProposal. Returns the response.
func (*TestApp) CallProcessProposal ¶
func (ta *TestApp) CallProcessProposal(txs [][]byte) *abci.ResponseProcessProposal
CallProcessProposal calls ProcessProposal with the given txs at the next block height (current height+1, time+5s). Returns the response.
func (*TestApp) CheckTxSync ¶
func (ta *TestApp) CheckTxSync(txBytes []byte) *abci.ResponseCheckTx
CheckTxSync runs CheckTx (type New) on raw tx bytes and returns the response.
func (*TestApp) DeliverVoteTx ¶
func (ta *TestApp) DeliverVoteTx(txBytes []byte) *abci.ExecTxResult
DeliverVoteTx submits a single raw vote tx through FinalizeBlock + Commit and returns the ExecTxResult. The block height and time are advanced.
func (*TestApp) DeliverVoteTxs ¶
func (ta *TestApp) DeliverVoteTxs(txs [][]byte) []*abci.ExecTxResult
DeliverVoteTxs submits multiple raw vote txs in a single block through FinalizeBlock + Commit and returns all ExecTxResults.
func (*TestApp) MustBuildSignedCeremonyTx ¶
MustBuildSignedCeremonyTx builds a standard Cosmos SDK transaction containing the ceremony message, signs it with the genesis validator's secp256k1 key, and returns the encoded tx bytes. Panics on failure (safe for tests).
func (*TestApp) NextBlock ¶
func (ta *TestApp) NextBlock()
NextBlock commits an empty block, advancing height and time by 5 seconds. Triggers EndBlocker (commitment tree root computation).
func (*TestApp) NextBlockAtTime ¶
NextBlockAtTime commits an empty block at a specific time, advancing height by 1. Triggers EndBlocker (commitment tree root computation, round status transitions).
func (*TestApp) NextBlockWithPrepareProposal ¶
func (ta *TestApp) NextBlockWithPrepareProposal()
NextBlockWithPrepareProposal calls PrepareProposal to collect any auto-injected txs, then feeds them into FinalizeBlock + Commit. This simulates a real block production cycle where PrepareProposal injects tally txs.
func (*TestApp) RecheckTxSync ¶
func (ta *TestApp) RecheckTxSync(txBytes []byte) *abci.ResponseCheckTx
RecheckTxSync runs CheckTx (type Recheck) on raw tx bytes and returns the response.
func (*TestApp) SeedConfirmedCeremony ¶
SeedConfirmedCeremony is a no-op retained for test compatibility. Ceremony state is now embedded per-round; rounds start PENDING and auto-confirm via deal/ack. Tests that need an ACTIVE round with ea_pk should use SeedVotingSession directly (which sets ea_pk on the round).
func (*TestApp) SeedDealtCeremony ¶
func (ta *TestApp) SeedDealtCeremony(pallasPkBytes, eaPkBytes []byte, payloads []*types.DealerPayload, validators []*types.ValidatorPallasKey) []byte
SeedDealtCeremony creates a PENDING round with DEALT ceremony fields. The round includes the given validators and ECIES payloads. Commits via an empty block. Returns the round ID.
func (*TestApp) SeedDealtCeremonyThreshold ¶
func (ta *TestApp) SeedDealtCeremonyThreshold( eaPkBytes []byte, payloads []*types.DealerPayload, validators []*types.ValidatorPallasKey, threshold uint32, verificationKeys [][]byte, ) []byte
SeedDealtCeremonyThreshold creates a PENDING round with DEALT ceremony fields in threshold mode. Callers supply pre-computed ECIES payloads, VK_i points, and the threshold t. This lets ack handler tests exercise threshold-mode verification (share_i * G == VK_i) without going through the full deal flow.
func (*TestApp) SeedRegisteringCeremony ¶
func (ta *TestApp) SeedRegisteringCeremony(validators []*types.ValidatorPallasKey) []byte
SeedRegisteringCeremony creates a PENDING round with REGISTERING ceremony status and the given validators. Commits via an empty block. Returns the round ID. Used for testing auto-deal and full ceremony cycle flows.
func (*TestApp) SeedTallyingRoundThreshold ¶
func (ta *TestApp) SeedTallyingRoundThreshold( roundID []byte, threshold uint32, proposals []*types.Proposal, validators []*types.ValidatorPallasKey, verificationKeys [][]byte, ) []byte
SeedTallyingRoundThreshold creates a TALLYING round in threshold mode directly in the KV store and commits via an empty block. Returns the round ID. Callers can subsequently use VoteKeeper().AddToTally to populate ciphertext accumulators, then call WriteShareForRound to put the share on disk before calling CallPrepareProposal.
If any validator has ShamirIndex == 0 (unset), this function assigns ShamirIndex = position+1, mirroring what CreateVotingSession does in production so that Lagrange interpolation uses the correct x-coordinates.
func (*TestApp) SeedVoteManager ¶
SeedVoteManager writes the vote manager address directly into the module's KV store and commits via an empty block. Must be called before any CreateVotingSession, since that handler requires the creator to be the vote manager.
func (*TestApp) SeedVotingSession ¶
func (ta *TestApp) SeedVotingSession(msg *types.MsgCreateVotingSession) []byte
SeedVotingSession creates a VoteRound directly in the KV store from a MsgCreateVotingSession, bypassing the ABCI pipeline. The round is committed via an empty block. Returns the derived vote_round_id.
MsgCreateVotingSession is now a standard Cosmos SDK tx (signed by the vote manager), so it can no longer be submitted via the custom vote tx wire format. For integration tests that need an active round to test other vote messages (delegation, cast, reveal, tally), this helper seeds the round directly — the session creation itself is not under test here.
func (*TestApp) ValidatorAccAddr ¶
ValidatorAccAddr returns the account (bech32 acc) address of the genesis validator's operator key. Same raw bytes as ValidatorOperAddr but encoded with the account prefix. Use this as the Creator field in ceremony messages that are handled by RegisterPallasKey and similar handlers which derive the valoper address internally from the account address.
func (*TestApp) ValidatorOperAddr ¶
ValidatorOperAddr returns the operator (valoper) address of the genesis validator. This queries the staking keeper for all validators and returns the first one's operator address.
func (*TestApp) VoteKeeper ¶
func (ta *TestApp) VoteKeeper() *votekeeper.Keeper
VoteKeeper returns the vote module keeper for querying state in tests.
func (*TestApp) WriteEaSkForRound ¶
WriteEaSkForRound writes the ea_sk bytes to the per-round file path so the tally PrepareProposal handler can load it. Call after creating a round.
func (*TestApp) WriteShareForRound ¶
WriteShareForRound writes a raw 32-byte Shamir share scalar to <EaSkDir>/share.<hex(round_id)>, the path the partial decrypt injector expects. Call after creating a TALLYING round in threshold mode.