Skip to content

Commit

Permalink
go/governance: Support for allowing voting without an entity
Browse files Browse the repository at this point in the history
  • Loading branch information
kostko committed Apr 18, 2024
1 parent bc0a401 commit ffd8c8b
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 23 deletions.
1 change: 1 addition & 0 deletions .changelog/5644.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
go/governance: Support for allowing voting without an entity
43 changes: 22 additions & 21 deletions go/consensus/cometbft/apps/governance/governance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,33 +55,34 @@ func initValidatorsEscrowState(
nodeSigner := memorySigner.NewTestSigner(fmt.Sprintf("consensus/cometbft/apps/governance: node signer: %d", i))
entitySigner := memorySigner.NewTestSigner(fmt.Sprintf("consensus/cometbft/apps/governance: entity signer: %d", i))
signers = append(signers, entitySigner)

ent := entity.Entity{
Versioned: cbor.NewVersioned(entity.LatestDescriptorVersion),
ID: entitySigner.Public(),
Nodes: []signature.PublicKey{nodeSigner.Public()},
}
sigEnt, entErr := entity.SignEntity(entitySigner, registry.RegisterEntitySignatureContext, &ent)
require.NoError(entErr, "SignEntity")
err = registryState.SetEntity(ctx, &ent, sigEnt)
require.NoError(err, "SetEntity")
addr := staking.NewAddress(entitySigner.Public())
addresses = append(addresses, addr)

nod := &node.Node{
Versioned: cbor.NewVersioned(node.LatestNodeDescriptorVersion),
ID: nodeSigner.Public(),
Consensus: node.ConsensusInfo{ID: nodeSigner.Public()},
EntityID: entitySigner.Public(),
}
sigNode, nErr := node.MultiSignNode([]signature.Signer{nodeSigner}, registry.RegisterNodeSignatureContext, nod)
require.NoError(nErr, "MultiSignNode")
err = registryState.SetNode(ctx, nil, nod, sigNode)
require.NoError(err, "SetNode")

switch {
case i < numValidators:
// First `numValidator` nodes are validators.
ent := entity.Entity{
Versioned: cbor.NewVersioned(entity.LatestDescriptorVersion),
ID: entitySigner.Public(),
Nodes: []signature.PublicKey{nodeSigner.Public()},
}
sigEnt, entErr := entity.SignEntity(entitySigner, registry.RegisterEntitySignatureContext, &ent)
require.NoError(entErr, "SignEntity")

err = registryState.SetEntity(ctx, &ent, sigEnt)
require.NoError(err, "SetEntity")

nod := &node.Node{
Versioned: cbor.NewVersioned(node.LatestNodeDescriptorVersion),
ID: nodeSigner.Public(),
Consensus: node.ConsensusInfo{ID: nodeSigner.Public()},
EntityID: entitySigner.Public(),
}
sigNode, nErr := node.MultiSignNode([]signature.Signer{nodeSigner}, registry.RegisterNodeSignatureContext, nod)
require.NoError(nErr, "MultiSignNode")
err = registryState.SetNode(ctx, nil, nod, sigNode)
require.NoError(err, "SetNode")

validatorSet[nod.Consensus.ID] = &scheduler.Validator{
ID: nodeSigner.Public(),
EntityID: nod.EntityID,
Expand Down
9 changes: 7 additions & 2 deletions go/consensus/cometbft/apps/governance/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,17 @@ func (app *governanceApplication) castVote(
}

// Query signer entity descriptor.
var submitterNodes []signature.PublicKey
registryState := registryState.NewMutableState(ctx.State())
submitterEntity, err := registryState.Entity(ctx, ctx.TxSigner())
switch err {
case nil:
submitterNodes = submitterEntity.Nodes
case registryAPI.ErrNoSuchEntity:
return governance.ErrNotEligible
if !params.AllowVoteWithoutEntity {
return governance.ErrNotEligible
}
// Default to an empty set of nodes so delegators without entities can vote.
default:
return fmt.Errorf("governance: failed to query entity: %w", err)
}
Expand All @@ -268,7 +273,7 @@ func (app *governanceApplication) castVote(

// Submitter is eligible if any of its nodes are a current validator.
var eligible bool
for _, nID := range submitterEntity.Nodes {
for _, nID := range submitterNodes {
if _, ok := currentValidatorsByNodeID[nID]; ok {
eligible = true
break
Expand Down
1 change: 1 addition & 0 deletions go/consensus/cometbft/apps/governance/transactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ func TestCastVote(t *testing.T) {
UpgradeCancelMinEpochDiff: beacon.EpochTime(100),
UpgradeMinEpochDiff: beacon.EpochTime(100),
VotingPeriod: beacon.EpochTime(50),
AllowVoteWithoutEntity: true,
}
err = state.SetConsensusParameters(ctx, params)
require.NoError(err, "setting governance consensus parameters should not error")
Expand Down
3 changes: 3 additions & 0 deletions go/governance/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ type ConsensusParameters struct {

// EnableChangeParametersProposal is true iff change parameters proposals are allowed.
EnableChangeParametersProposal bool `json:"enable_change_parameters_proposal,omitempty"`

// AllowVoteWithoutEntity is true iff casting votes without a registered entity is allowed.
AllowVoteWithoutEntity bool `json:"allow_vote_without_entity,omitempty"`
}

// ConsensusParameterChanges are allowed governance consensus parameter changes.
Expand Down
18 changes: 18 additions & 0 deletions go/oasis-test-runner/scenario/e2e/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ func (c *upgrade240Checker) PreUpgradeFn(ctx context.Context, ctrl *oasis.Contro
return fmt.Errorf("key manager CHURP consensus parameters shouldn't be set: %w", err)
}

// Check governance parameters.
govParams, err := ctrl.Governance.ConsensusParameters(ctx, consensus.HeightLatest)
if err != nil {
return fmt.Errorf("can't get governance consensus parameters: %w", err)
}
if govParams.AllowVoteWithoutEntity {
return fmt.Errorf("voting without entity is allowed")
}

return nil
}

Expand Down Expand Up @@ -140,6 +149,15 @@ func (c *upgrade240Checker) PostUpgradeFn(ctx context.Context, ctrl *oasis.Contr
return fmt.Errorf("key manager CHURP consensus parameters are not default")
}

// Check updated governance parameters.
govParams, err := ctrl.Governance.ConsensusParameters(ctx, consensus.HeightLatest)
if err != nil {
return fmt.Errorf("can't get governance consensus parameters: %w", err)
}
if !govParams.AllowVoteWithoutEntity {
return fmt.Errorf("voting without entity is not allowed")
}

return nil
}

Expand Down
14 changes: 14 additions & 0 deletions go/upgrade/migrations/consensus_240.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

consensusState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/abci/state"
abciAPI "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/api"
governanceState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/governance/state"
churpState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/keymanager/churp/state"
registryState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/registry/state"
"github.com/oasisprotocol/oasis-core/go/keymanager/churp"
Expand Down Expand Up @@ -69,6 +70,19 @@ func (h *Handler240) ConsensusUpgrade(privateCtx interface{}) error {
if err = state.SetConsensusParameters(abciCtx, &churp.DefaultConsensusParameters); err != nil {
return fmt.Errorf("failed to set CHURP consensus parameters: %w", err)
}

// Governance.
govState := governanceState.NewMutableState(abciCtx.State())

govParams, err := govState.ConsensusParameters(abciCtx)
if err != nil {
return fmt.Errorf("failed to load governance consensus parameters: %w", err)
}
govParams.AllowVoteWithoutEntity = true

if err = govState.SetConsensusParameters(abciCtx, govParams); err != nil {
return fmt.Errorf("failed to update governance consensus parameters: %w", err)
}
default:
return fmt.Errorf("upgrade handler called in unexpected context: %s", abciCtx.Mode())
}
Expand Down

0 comments on commit ffd8c8b

Please sign in to comment.