refactor(group): Distinguish Voting period and Execution period for group policies (#11198)
## Description Closes: #11092 ## TODOs I'm thinking to do the 2 todos in a separate PR, or else this PR is too big. WDYT? - [ ] #11246 This involves adding a new index ProposalsByVotingPeriodEnd, so might be better to do in another PR - [ ] #11245 Also should be done in a separate PR (as it needs the above index) ### Main change 1: Group policy proto defs have `voting_period` and `min_execution_period` For group policies: ```diff - // Within this times votes and exec messages can be submitted. - // timeout is the duration from submission of a proposal to the end of voting period - google.protobuf.Duration timeout = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; + // voting_period is the duration from submission of a proposal to the end of voting period + // Within this times votes can be submitted with MsgVote. + google.protobuf.Duration voting_period = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; + // min_execution_period is the minimum duration after the proposal submission + // where members can start sending MsgExec. This means that the window for + // sending a MsgExec transaction is: + // `[ submission + min_execution_period ; submission + voting_period + max_execution_period]` + // where max_execution_period is a app-specific config, defined in the keeper. + // If not set, min_execution_period will default to 0. + google.protobuf.Duration min_execution_period = 3 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; ``` ### Main Change 2: We don't update proposal's FinalTallyResult result on MsgVote/MsgSubmitProposal Unless the msg has TryExec set to true, in which case the FinalTallyResult is updated ONLY if the tally is final. ### Main Change 3: Add a keeper-level `MaxExecutionPeriod` MsgExecs will be rejected if they are sent after `voting_period_end + MaxExecutionPeriod` --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
This commit is contained in:
parent
26c9a2d06d
commit
da36c46f3a
|
@ -3,15 +3,14 @@ package appv1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
fmt "fmt"
|
fmt "fmt"
|
||||||
io "io"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
|
|
||||||
runtime "github.com/cosmos/cosmos-proto/runtime"
|
runtime "github.com/cosmos/cosmos-proto/runtime"
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
||||||
|
io "io"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ protoreflect.List = (*_ModuleDescriptor_2_list)(nil)
|
var _ protoreflect.List = (*_ModuleDescriptor_2_list)(nil)
|
||||||
|
|
|
@ -4078,7 +4078,9 @@ type SnapshotIAVLItem struct {
|
||||||
|
|
||||||
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||||
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||||
|
// version is block height
|
||||||
Version int64 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`
|
Version int64 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`
|
||||||
|
// height is depth of the tree.
|
||||||
Height int32 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"`
|
Height int32 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,16 +3,14 @@ package modulev1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
fmt "fmt"
|
fmt "fmt"
|
||||||
io "io"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
|
|
||||||
runtime "github.com/cosmos/cosmos-proto/runtime"
|
runtime "github.com/cosmos/cosmos-proto/runtime"
|
||||||
|
_ "github.com/cosmos/cosmos-sdk/api/cosmos/app/v1alpha1"
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
io "io"
|
||||||
_ "github.com/cosmos/cosmos-sdk/api/cosmos/app/v1alpha1"
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -3,15 +3,14 @@ package ormv1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
fmt "fmt"
|
fmt "fmt"
|
||||||
io "io"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
|
|
||||||
runtime "github.com/cosmos/cosmos-proto/runtime"
|
runtime "github.com/cosmos/cosmos-proto/runtime"
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
||||||
|
io "io"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ protoreflect.List = (*_TableDescriptor_2_list)(nil)
|
var _ protoreflect.List = (*_TableDescriptor_2_list)(nil)
|
||||||
|
|
|
@ -3,15 +3,14 @@ package ormv1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
fmt "fmt"
|
fmt "fmt"
|
||||||
io "io"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
|
|
||||||
runtime "github.com/cosmos/cosmos-proto/runtime"
|
runtime "github.com/cosmos/cosmos-proto/runtime"
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
||||||
|
io "io"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ protoreflect.List = (*_ModuleSchemaDescriptor_1_list)(nil)
|
var _ protoreflect.List = (*_ModuleSchemaDescriptor_1_list)(nil)
|
||||||
|
|
|
@ -41,9 +41,8 @@ message ThresholdDecisionPolicy {
|
||||||
// threshold is the minimum weighted sum of yes votes that must be met or exceeded for a proposal to succeed.
|
// threshold is the minimum weighted sum of yes votes that must be met or exceeded for a proposal to succeed.
|
||||||
string threshold = 1;
|
string threshold = 1;
|
||||||
|
|
||||||
// timeout is the duration from submission of a proposal to the end of voting period
|
// windows defines the different windows for voting and execution.
|
||||||
// Within this times votes and exec messages can be submitted.
|
DecisionPolicyWindows windows = 2;
|
||||||
google.protobuf.Duration timeout = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PercentageDecisionPolicy implements the DecisionPolicy interface
|
// PercentageDecisionPolicy implements the DecisionPolicy interface
|
||||||
|
@ -53,9 +52,28 @@ message PercentageDecisionPolicy {
|
||||||
// percentage is the minimum percentage the weighted sum of yes votes must meet for a proposal to succeed.
|
// percentage is the minimum percentage the weighted sum of yes votes must meet for a proposal to succeed.
|
||||||
string percentage = 1;
|
string percentage = 1;
|
||||||
|
|
||||||
// timeout is the duration from submission of a proposal to the end of voting period
|
// windows defines the different windows for voting and execution.
|
||||||
// Within these times votes and exec messages can be submitted.
|
DecisionPolicyWindows windows = 2;
|
||||||
google.protobuf.Duration timeout = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];
|
}
|
||||||
|
|
||||||
|
// DecisionPolicyWindows defines the different windows for voting and execution.
|
||||||
|
message DecisionPolicyWindows {
|
||||||
|
// voting_period is the duration from submission of a proposal to the end of voting period
|
||||||
|
// Within this times votes can be submitted with MsgVote.
|
||||||
|
google.protobuf.Duration voting_period = 1 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];
|
||||||
|
|
||||||
|
// min_execution_period is the minimum duration after the proposal submission
|
||||||
|
// where members can start sending MsgExec. This means that the window for
|
||||||
|
// sending a MsgExec transaction is:
|
||||||
|
// `[ submission + min_execution_period ; submission + voting_period + max_execution_period]`
|
||||||
|
// where max_execution_period is a app-specific config, defined in the keeper.
|
||||||
|
// If not set, min_execution_period will default to 0.
|
||||||
|
//
|
||||||
|
// Please make sure to set a `min_execution_period` that is smaller than
|
||||||
|
// `voting_period + max_execution_period`, or else the above execution window
|
||||||
|
// is empty, meaning that all proposals created with this decision policy
|
||||||
|
// won't be able to be executed.
|
||||||
|
google.protobuf.Duration min_execution_period = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
// VoteOption enumerates the valid vote options for a given proposal.
|
// VoteOption enumerates the valid vote options for a given proposal.
|
||||||
|
@ -184,11 +202,12 @@ message Proposal {
|
||||||
// has ended.
|
// has ended.
|
||||||
TallyResult final_tally_result = 10 [(gogoproto.nullable) = false];
|
TallyResult final_tally_result = 10 [(gogoproto.nullable) = false];
|
||||||
|
|
||||||
// timeout is the timestamp before which both voting and execution must be
|
// voting_period_end is the timestamp before which voting must be done.
|
||||||
// done. If this timestamp is passed, then the proposal cannot be executed
|
// Unless a successfull MsgExec is called before (to execute a proposal whose
|
||||||
// anymore and should be considered pending delete. This timestamp is checked
|
// tally is successful before the voting period ends), tallying will be done
|
||||||
// against the block header's timestamp.
|
// at this point, and the `final_tally_result`, as well
|
||||||
google.protobuf.Timestamp timeout = 11 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
|
// as `status` and `result` fields will be accordingly updated.
|
||||||
|
google.protobuf.Timestamp voting_period_end = 11 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
|
||||||
|
|
||||||
// executor_result is the final result based on the votes and election rule. Initial value is NotRun.
|
// executor_result is the final result based on the votes and election rule. Initial value is NotRun.
|
||||||
ProposalExecutorResult executor_result = 12;
|
ProposalExecutorResult executor_result = 12;
|
||||||
|
|
|
@ -295,7 +295,7 @@ func NewSimApp(
|
||||||
|
|
||||||
app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.msgSvcRouter, app.AccountKeeper)
|
app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.msgSvcRouter, app.AccountKeeper)
|
||||||
|
|
||||||
groupConfig := groupkeeper.DefaultConfig()
|
groupConfig := group.DefaultConfig()
|
||||||
/*
|
/*
|
||||||
Example of setting group params:
|
Example of setting group params:
|
||||||
groupConfig.MaxMetadataLen = 1000
|
groupConfig.MaxMetadataLen = 1000
|
||||||
|
|
|
@ -308,7 +308,9 @@ func (m *SnapshotStoreItem) GetName() string {
|
||||||
type SnapshotIAVLItem struct {
|
type SnapshotIAVLItem struct {
|
||||||
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||||
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||||
|
// version is block height
|
||||||
Version int64 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`
|
Version int64 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`
|
||||||
|
// height is depth of the tree.
|
||||||
Height int32 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"`
|
Height int32 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -553,6 +553,8 @@ func (m *GetTxResponse) GetTxResponse() *types.TxResponse {
|
||||||
|
|
||||||
// GetBlockWithTxsRequest is the request type for the Service.GetBlockWithTxs
|
// GetBlockWithTxsRequest is the request type for the Service.GetBlockWithTxs
|
||||||
// RPC method.
|
// RPC method.
|
||||||
|
//
|
||||||
|
// Since: cosmos-sdk 0.45.2
|
||||||
type GetBlockWithTxsRequest struct {
|
type GetBlockWithTxsRequest struct {
|
||||||
// height is the height of the block to query.
|
// height is the height of the block to query.
|
||||||
Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
|
Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
|
||||||
|
@ -608,6 +610,8 @@ func (m *GetBlockWithTxsRequest) GetPagination() *query.PageRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs method.
|
// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs method.
|
||||||
|
//
|
||||||
|
// Since: cosmos-sdk 0.45.2
|
||||||
type GetBlockWithTxsResponse struct {
|
type GetBlockWithTxsResponse struct {
|
||||||
// txs are the transactions in the block.
|
// txs are the transactions in the block.
|
||||||
Txs []*Tx `protobuf:"bytes,1,rep,name=txs,proto3" json:"txs,omitempty"`
|
Txs []*Tx `protobuf:"bytes,1,rep,name=txs,proto3" json:"txs,omitempty"`
|
||||||
|
|
|
@ -120,7 +120,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
||||||
val.Address.String(),
|
val.Address.String(),
|
||||||
"1",
|
"1",
|
||||||
validMetadata,
|
validMetadata,
|
||||||
fmt.Sprintf("{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"%d\", \"timeout\":\"30000s\"}", threshold),
|
fmt.Sprintf("{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"%d\", \"windows\":{\"voting_period\":\"30000s\"}}", threshold),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -140,7 +140,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
||||||
val.Address.String(),
|
val.Address.String(),
|
||||||
"1",
|
"1",
|
||||||
validMetadata,
|
validMetadata,
|
||||||
fmt.Sprintf("{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"%f\", \"timeout\":\"30000s\"}", percentage),
|
fmt.Sprintf("{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"%f\", \"windows\":{\"voting_period\":\"30000s\"}}", percentage),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -746,7 +746,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupWithPolicy() {
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMembersFile.Name(),
|
validMembersFile.Name(),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
|
@ -764,7 +764,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupWithPolicy() {
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMembersFile.Name(),
|
validMembersFile.Name(),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, true),
|
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, true),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
|
@ -782,7 +782,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupWithPolicy() {
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMembersFile.Name(),
|
validMembersFile.Name(),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
||||||
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
||||||
},
|
},
|
||||||
|
@ -801,7 +801,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupWithPolicy() {
|
||||||
strings.Repeat("a", 256),
|
strings.Repeat("a", 256),
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMembersFile.Name(),
|
validMembersFile.Name(),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
|
@ -819,7 +819,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupWithPolicy() {
|
||||||
validMetadata,
|
validMetadata,
|
||||||
strings.Repeat("a", 256),
|
strings.Repeat("a", 256),
|
||||||
validMembersFile.Name(),
|
validMembersFile.Name(),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
|
@ -837,7 +837,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupWithPolicy() {
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMetadata,
|
validMetadata,
|
||||||
invalidMembersAddressFile.Name(),
|
invalidMembersAddressFile.Name(),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
|
@ -855,7 +855,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupWithPolicy() {
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMetadata,
|
validMetadata,
|
||||||
invalidMembersWeightFile.Name(),
|
invalidMembersWeightFile.Name(),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
|
@ -873,7 +873,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupWithPolicy() {
|
||||||
validMetadata,
|
validMetadata,
|
||||||
validMetadata,
|
validMetadata,
|
||||||
invalidMembersMetadataFile.Name(),
|
invalidMembersMetadataFile.Name(),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
fmt.Sprintf("--%s=%v", client.FlagGroupPolicyAsAdmin, false),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
|
@ -932,7 +932,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupPolicy() {
|
||||||
val.Address.String(),
|
val.Address.String(),
|
||||||
fmt.Sprintf("%v", groupID),
|
fmt.Sprintf("%v", groupID),
|
||||||
validMetadata,
|
validMetadata,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -948,7 +948,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupPolicy() {
|
||||||
val.Address.String(),
|
val.Address.String(),
|
||||||
fmt.Sprintf("%v", groupID),
|
fmt.Sprintf("%v", groupID),
|
||||||
validMetadata,
|
validMetadata,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"0.5\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"0.5\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -964,7 +964,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupPolicy() {
|
||||||
val.Address.String(),
|
val.Address.String(),
|
||||||
fmt.Sprintf("%v", groupID),
|
fmt.Sprintf("%v", groupID),
|
||||||
validMetadata,
|
validMetadata,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
|
@ -981,7 +981,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupPolicy() {
|
||||||
wrongAdmin.String(),
|
wrongAdmin.String(),
|
||||||
fmt.Sprintf("%v", groupID),
|
fmt.Sprintf("%v", groupID),
|
||||||
validMetadata,
|
validMetadata,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -997,7 +997,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupPolicy() {
|
||||||
val.Address.String(),
|
val.Address.String(),
|
||||||
fmt.Sprintf("%v", groupID),
|
fmt.Sprintf("%v", groupID),
|
||||||
strings.Repeat("a", 500),
|
strings.Repeat("a", 500),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -1013,7 +1013,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupPolicy() {
|
||||||
val.Address.String(),
|
val.Address.String(),
|
||||||
"10",
|
"10",
|
||||||
validMetadata,
|
validMetadata,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -1029,7 +1029,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupPolicy() {
|
||||||
val.Address.String(),
|
val.Address.String(),
|
||||||
fmt.Sprintf("%v", groupID),
|
fmt.Sprintf("%v", groupID),
|
||||||
validMetadata,
|
validMetadata,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"-0.5\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"-0.5\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -1045,7 +1045,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroupPolicy() {
|
||||||
val.Address.String(),
|
val.Address.String(),
|
||||||
fmt.Sprintf("%v", groupID),
|
fmt.Sprintf("%v", groupID),
|
||||||
validMetadata,
|
validMetadata,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"2\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"2\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -1205,7 +1205,7 @@ func (s *IntegrationTestSuite) TestTxUpdateGroupPolicyDecisionPolicy() {
|
||||||
[]string{
|
[]string{
|
||||||
groupPolicy.Admin,
|
groupPolicy.Admin,
|
||||||
groupPolicy.Address,
|
groupPolicy.Address,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"40000s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"40000s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -1220,7 +1220,7 @@ func (s *IntegrationTestSuite) TestTxUpdateGroupPolicyDecisionPolicy() {
|
||||||
[]string{
|
[]string{
|
||||||
groupPolicy.Admin,
|
groupPolicy.Admin,
|
||||||
groupPolicy.Address,
|
groupPolicy.Address,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"0.5\", \"timeout\":\"40000s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"0.5\", \"windows\":{\"voting_period\":\"40000s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -1235,7 +1235,7 @@ func (s *IntegrationTestSuite) TestTxUpdateGroupPolicyDecisionPolicy() {
|
||||||
[]string{
|
[]string{
|
||||||
groupPolicy.Admin,
|
groupPolicy.Admin,
|
||||||
groupPolicy.Address,
|
groupPolicy.Address,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"50000s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"50000s\"}}",
|
||||||
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
|
@ -1251,7 +1251,7 @@ func (s *IntegrationTestSuite) TestTxUpdateGroupPolicyDecisionPolicy() {
|
||||||
[]string{
|
[]string{
|
||||||
newAdmin.String(),
|
newAdmin.String(),
|
||||||
groupPolicy.Address,
|
groupPolicy.Address,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -1266,7 +1266,7 @@ func (s *IntegrationTestSuite) TestTxUpdateGroupPolicyDecisionPolicy() {
|
||||||
[]string{
|
[]string{
|
||||||
groupPolicy.Admin,
|
groupPolicy.Admin,
|
||||||
newAdmin.String(),
|
newAdmin.String(),
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.ThresholdDecisionPolicy\", \"threshold\":\"1\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -1281,7 +1281,7 @@ func (s *IntegrationTestSuite) TestTxUpdateGroupPolicyDecisionPolicy() {
|
||||||
[]string{
|
[]string{
|
||||||
groupPolicy.Admin,
|
groupPolicy.Admin,
|
||||||
groupPolicy.Address,
|
groupPolicy.Address,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"-0.5\", \"timeout\":\"1s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"-0.5\", \"windows\":{\"voting_period\":\"1s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
@ -1296,7 +1296,7 @@ func (s *IntegrationTestSuite) TestTxUpdateGroupPolicyDecisionPolicy() {
|
||||||
[]string{
|
[]string{
|
||||||
groupPolicy.Admin,
|
groupPolicy.Admin,
|
||||||
groupPolicy.Address,
|
groupPolicy.Address,
|
||||||
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"2\", \"timeout\":\"40000s\"}",
|
"{\"@type\":\"/cosmos.group.v1beta1.PercentageDecisionPolicy\", \"percentage\":\"2\", \"windows\":{\"voting_period\":\"40000s\"}}",
|
||||||
},
|
},
|
||||||
commonFlags...,
|
commonFlags...,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
package keeper
|
package group
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
// Config is a config struct used for intialising the group module to avoid using globals.
|
// Config is a config struct used for intialising the group module to avoid using globals.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
// MaxExecutionPeriod defines the max duration after a proposal's voting
|
||||||
|
// period ends that members can send a MsgExec to execute the proposal.
|
||||||
|
MaxExecutionPeriod time.Duration
|
||||||
// MaxMetadataLen defines the max length of the metadata bytes field for various entities within the group module. Defaults to 255 if not explicitly set.
|
// MaxMetadataLen defines the max length of the metadata bytes field for various entities within the group module. Defaults to 255 if not explicitly set.
|
||||||
MaxMetadataLen uint64
|
MaxMetadataLen uint64
|
||||||
}
|
}
|
||||||
|
@ -9,6 +14,7 @@ type Config struct {
|
||||||
// DefaultConfig returns the default config for group.
|
// DefaultConfig returns the default config for group.
|
||||||
func DefaultConfig() Config {
|
func DefaultConfig() Config {
|
||||||
return Config{
|
return Config{
|
||||||
|
MaxExecutionPeriod: 2 * time.Hour * 24 * 7, // Two weeks.
|
||||||
MaxMetadataLen: 255,
|
MaxMetadataLen: 255,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -31,7 +31,9 @@ func TestGenesisStateValidate(t *testing.T) {
|
||||||
}
|
}
|
||||||
err := groupPolicy.SetDecisionPolicy(&ThresholdDecisionPolicy{
|
err := groupPolicy.SetDecisionPolicy(&ThresholdDecisionPolicy{
|
||||||
Threshold: "1",
|
Threshold: "1",
|
||||||
Timeout: time.Second,
|
Windows: &DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -45,7 +47,9 @@ func TestGenesisStateValidate(t *testing.T) {
|
||||||
}
|
}
|
||||||
err = groupPolicy2.SetDecisionPolicy(&ThresholdDecisionPolicy{
|
err = groupPolicy2.SetDecisionPolicy(&ThresholdDecisionPolicy{
|
||||||
Threshold: "1",
|
Threshold: "1",
|
||||||
Timeout: 0,
|
Windows: &DecisionPolicyWindows{
|
||||||
|
VotingPeriod: 0,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -67,7 +71,7 @@ func TestGenesisStateValidate(t *testing.T) {
|
||||||
AbstainCount: "0",
|
AbstainCount: "0",
|
||||||
NoWithVetoCount: "0",
|
NoWithVetoCount: "0",
|
||||||
},
|
},
|
||||||
Timeout: timeout,
|
VotingPeriodEnd: timeout,
|
||||||
ExecutorResult: PROPOSAL_EXECUTOR_RESULT_SUCCESS,
|
ExecutorResult: PROPOSAL_EXECUTOR_RESULT_SUCCESS,
|
||||||
}
|
}
|
||||||
err = proposal.SetMsgs([]sdk.Msg{&banktypes.MsgSend{
|
err = proposal.SetMsgs([]sdk.Msg{&banktypes.MsgSend{
|
||||||
|
|
|
@ -73,7 +73,9 @@ func (s *GenesisTestSuite) TestInitExportGenesis() {
|
||||||
}
|
}
|
||||||
err := groupPolicy.SetDecisionPolicy(&group.ThresholdDecisionPolicy{
|
err := groupPolicy.SetDecisionPolicy(&group.ThresholdDecisionPolicy{
|
||||||
Threshold: "1",
|
Threshold: "1",
|
||||||
Timeout: time.Second,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
@ -95,7 +97,7 @@ func (s *GenesisTestSuite) TestInitExportGenesis() {
|
||||||
AbstainCount: "0",
|
AbstainCount: "0",
|
||||||
NoWithVetoCount: "0",
|
NoWithVetoCount: "0",
|
||||||
},
|
},
|
||||||
Timeout: timeout,
|
VotingPeriodEnd: timeout,
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_SUCCESS,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_SUCCESS,
|
||||||
}
|
}
|
||||||
err = proposal.SetMsgs([]sdk.Msg{&banktypes.MsgSend{
|
err = proposal.SetMsgs([]sdk.Msg{&banktypes.MsgSend{
|
||||||
|
@ -216,7 +218,7 @@ func (s *GenesisTestSuite) assertProposalsEqual(g *group.Proposal, other *group.
|
||||||
require.Equal(g.Status, other.Status)
|
require.Equal(g.Status, other.Status)
|
||||||
require.Equal(g.Result, other.Result)
|
require.Equal(g.Result, other.Result)
|
||||||
require.Equal(g.FinalTallyResult, other.FinalTallyResult)
|
require.Equal(g.FinalTallyResult, other.FinalTallyResult)
|
||||||
require.Equal(g.Timeout, other.Timeout)
|
require.Equal(g.VotingPeriodEnd, other.VotingPeriodEnd)
|
||||||
require.Equal(g.ExecutorResult, other.ExecutorResult)
|
require.Equal(g.ExecutorResult, other.ExecutorResult)
|
||||||
require.Equal(g.GetMsgs(), other.GetMsgs())
|
require.Equal(g.GetMsgs(), other.GetMsgs())
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
"github.com/cosmos/cosmos-sdk/types/query"
|
"github.com/cosmos/cosmos-sdk/types/query"
|
||||||
"github.com/cosmos/cosmos-sdk/x/group"
|
"github.com/cosmos/cosmos-sdk/x/group"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/group/errors"
|
||||||
"github.com/cosmos/cosmos-sdk/x/group/internal/orm"
|
"github.com/cosmos/cosmos-sdk/x/group/internal/orm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -303,3 +304,55 @@ func (q Keeper) getVotesByProposal(ctx sdk.Context, proposalID uint64, pageReque
|
||||||
func (q Keeper) getVotesByVoter(ctx sdk.Context, voter sdk.AccAddress, pageRequest *query.PageRequest) (orm.Iterator, error) {
|
func (q Keeper) getVotesByVoter(ctx sdk.Context, voter sdk.AccAddress, pageRequest *query.PageRequest) (orm.Iterator, error) {
|
||||||
return q.voteByVoterIndex.GetPaginated(ctx.KVStore(q.key), voter.Bytes(), pageRequest)
|
return q.voteByVoterIndex.GetPaginated(ctx.KVStore(q.key), voter.Bytes(), pageRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tally is a function that tallies a proposal by iterating through its votes,
|
||||||
|
// and returns the tally result without modifying the proposal or any state.
|
||||||
|
// TODO Merge with https://github.com/cosmos/cosmos-sdk/issues/11151
|
||||||
|
func (q Keeper) Tally(ctx sdk.Context, p group.Proposal, groupId uint64) (group.TallyResult, error) {
|
||||||
|
// If proposal has already been tallied and updated, then its status is
|
||||||
|
// closed, in which case we just return the previously stored result.
|
||||||
|
if p.Status == group.PROPOSAL_STATUS_CLOSED {
|
||||||
|
return p.FinalTallyResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
it, err := q.voteByProposalIndex.Get(ctx.KVStore(q.key), p.Id)
|
||||||
|
if err != nil {
|
||||||
|
return group.TallyResult{}, err
|
||||||
|
}
|
||||||
|
defer it.Close()
|
||||||
|
|
||||||
|
tallyResult := group.DefaultTallyResult()
|
||||||
|
|
||||||
|
var vote group.Vote
|
||||||
|
for {
|
||||||
|
_, err = it.LoadNext(&vote)
|
||||||
|
if errors.ErrORMIteratorDone.Is(err) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return group.TallyResult{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var member group.GroupMember
|
||||||
|
err := q.groupMemberTable.GetOne(ctx.KVStore(q.key), orm.PrimaryKey(&group.GroupMember{
|
||||||
|
GroupId: groupId,
|
||||||
|
Member: &group.Member{Address: vote.Voter},
|
||||||
|
}), &member)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case sdkerrors.ErrNotFound.Is(err):
|
||||||
|
// If the member left the group after voting, then we simply skip the
|
||||||
|
// vote.
|
||||||
|
continue
|
||||||
|
case err != nil:
|
||||||
|
// For any other errors, we stop and return the error.
|
||||||
|
return group.TallyResult{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tallyResult.Add(vote, member.Member.Weight); err != nil {
|
||||||
|
return group.TallyResult{}, sdkerrors.Wrap(err, "add new vote")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tallyResult, nil
|
||||||
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ type invariantTestSuite struct {
|
||||||
ctx sdk.Context
|
ctx sdk.Context
|
||||||
cdc *codec.ProtoCodec
|
cdc *codec.ProtoCodec
|
||||||
key *storetypes.KVStoreKey
|
key *storetypes.KVStoreKey
|
||||||
blockTime time.Time
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvariantTestSuite(t *testing.T) {
|
func TestInvariantTestSuite(t *testing.T) {
|
||||||
|
@ -81,7 +80,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "1", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "1", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
||||||
Timeout: prevCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: prevCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -95,7 +94,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "2", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "2", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
||||||
Timeout: curCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: curCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -110,7 +109,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "2", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "2", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
||||||
Timeout: prevCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: prevCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
curProposal: &group.Proposal{
|
curProposal: &group.Proposal{
|
||||||
|
@ -123,7 +122,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "1", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "1", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
||||||
Timeout: curCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: curCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
expBroken: true,
|
expBroken: true,
|
||||||
|
@ -139,7 +138,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "2", AbstainCount: "0", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "2", AbstainCount: "0", NoWithVetoCount: "0"},
|
||||||
Timeout: prevCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: prevCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
curProposal: &group.Proposal{
|
curProposal: &group.Proposal{
|
||||||
|
@ -152,7 +151,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "1", AbstainCount: "0", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "1", AbstainCount: "0", NoWithVetoCount: "0"},
|
||||||
Timeout: curCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: curCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
expBroken: true,
|
expBroken: true,
|
||||||
|
@ -168,7 +167,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "0", AbstainCount: "2", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "0", AbstainCount: "2", NoWithVetoCount: "0"},
|
||||||
Timeout: prevCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: prevCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
curProposal: &group.Proposal{
|
curProposal: &group.Proposal{
|
||||||
|
@ -181,7 +180,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "0", AbstainCount: "1", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "0", AbstainCount: "1", NoWithVetoCount: "0"},
|
||||||
Timeout: curCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: curCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
expBroken: true,
|
expBroken: true,
|
||||||
|
@ -197,7 +196,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "2"},
|
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "2"},
|
||||||
Timeout: prevCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: prevCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
curProposal: &group.Proposal{
|
curProposal: &group.Proposal{
|
||||||
|
@ -210,7 +209,7 @@ func (s *invariantTestSuite) TestTallyVotesInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "1"},
|
FinalTallyResult: group.TallyResult{YesCount: "0", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "1"},
|
||||||
Timeout: curCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: curCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
expBroken: true,
|
expBroken: true,
|
||||||
|
@ -413,7 +412,7 @@ func (s *invariantTestSuite) TestTallyVotesSumInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "4", NoCount: "3", AbstainCount: "0", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "4", NoCount: "3", AbstainCount: "0", NoWithVetoCount: "0"},
|
||||||
Timeout: curCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: curCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
votes: []*group.Vote{
|
votes: []*group.Vote{
|
||||||
|
@ -471,7 +470,7 @@ func (s *invariantTestSuite) TestTallyVotesSumInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "6", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "6", NoCount: "0", AbstainCount: "0", NoWithVetoCount: "0"},
|
||||||
Timeout: curCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: curCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
votes: []*group.Vote{
|
votes: []*group.Vote{
|
||||||
|
@ -529,7 +528,7 @@ func (s *invariantTestSuite) TestTallyVotesSumInvariant() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{YesCount: "4", NoCount: "3", AbstainCount: "0", NoWithVetoCount: "0"},
|
FinalTallyResult: group.TallyResult{YesCount: "4", NoCount: "3", AbstainCount: "0", NoWithVetoCount: "0"},
|
||||||
Timeout: curCtx.BlockTime().Add(time.Second * 600),
|
VotingPeriodEnd: curCtx.BlockTime().Add(time.Second * 600),
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
},
|
},
|
||||||
votes: []*group.Vote{
|
votes: []*group.Vote{
|
||||||
|
@ -561,7 +560,7 @@ func (s *invariantTestSuite) TestTallyVotesSumInvariant() {
|
||||||
_, err := groupTable.Create(cacheCurCtx.KVStore(key), groupsInfo)
|
_, err := groupTable.Create(cacheCurCtx.KVStore(key), groupsInfo)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
err = groupPolicy.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Second))
|
err = groupPolicy.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Second, 0))
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
err = groupPolicyTable.Create(cacheCurCtx.KVStore(key), groupPolicy)
|
err = groupPolicyTable.Create(cacheCurCtx.KVStore(key), groupPolicy)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
|
@ -74,10 +74,10 @@ type Keeper struct {
|
||||||
|
|
||||||
router *authmiddleware.MsgServiceRouter
|
router *authmiddleware.MsgServiceRouter
|
||||||
|
|
||||||
config Config
|
config group.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKeeper(storeKey storetypes.StoreKey, cdc codec.Codec, router *authmiddleware.MsgServiceRouter, accKeeper group.AccountKeeper, config Config) Keeper {
|
func NewKeeper(storeKey storetypes.StoreKey, cdc codec.Codec, router *authmiddleware.MsgServiceRouter, accKeeper group.AccountKeeper, config group.Config) Keeper {
|
||||||
k := Keeper{
|
k := Keeper{
|
||||||
key: storeKey,
|
key: storeKey,
|
||||||
router: router,
|
router: router,
|
||||||
|
@ -207,7 +207,10 @@ func NewKeeper(storeKey storetypes.StoreKey, cdc codec.Codec, router *authmiddle
|
||||||
k.voteTable = *voteTable
|
k.voteTable = *voteTable
|
||||||
|
|
||||||
if config.MaxMetadataLen == 0 {
|
if config.MaxMetadataLen == 0 {
|
||||||
config.MaxMetadataLen = DefaultConfig().MaxMetadataLen
|
config.MaxMetadataLen = group.DefaultConfig().MaxMetadataLen
|
||||||
|
}
|
||||||
|
if config.MaxExecutionPeriod == 0 {
|
||||||
|
config.MaxExecutionPeriod = group.DefaultConfig().MaxExecutionPeriod
|
||||||
}
|
}
|
||||||
k.config = config
|
k.config = config
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ func (s *TestSuite) SetupTest() {
|
||||||
policy := group.NewThresholdDecisionPolicy(
|
policy := group.NewThresholdDecisionPolicy(
|
||||||
"2",
|
"2",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
policyReq := &group.MsgCreateGroupPolicy{
|
policyReq := &group.MsgCreateGroupPolicy{
|
||||||
Admin: s.addrs[0].String(),
|
Admin: s.addrs[0].String(),
|
||||||
|
@ -693,6 +694,7 @@ func (s *TestSuite) TestCreateGroupWithPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
"group policy as admin is true": {
|
"group policy as admin is true": {
|
||||||
|
@ -704,6 +706,7 @@ func (s *TestSuite) TestCreateGroupWithPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
"group metadata too long": {
|
"group metadata too long": {
|
||||||
|
@ -716,6 +719,7 @@ func (s *TestSuite) TestCreateGroupWithPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: true,
|
expErr: true,
|
||||||
expErrMsg: "limit exceeded",
|
expErrMsg: "limit exceeded",
|
||||||
|
@ -730,6 +734,7 @@ func (s *TestSuite) TestCreateGroupWithPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: true,
|
expErr: true,
|
||||||
expErrMsg: "limit exceeded",
|
expErrMsg: "limit exceeded",
|
||||||
|
@ -747,6 +752,7 @@ func (s *TestSuite) TestCreateGroupWithPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: true,
|
expErr: true,
|
||||||
expErrMsg: "limit exceeded",
|
expErrMsg: "limit exceeded",
|
||||||
|
@ -763,6 +769,7 @@ func (s *TestSuite) TestCreateGroupWithPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: true,
|
expErr: true,
|
||||||
expErrMsg: "expected a positive decimal",
|
expErrMsg: "expected a positive decimal",
|
||||||
|
@ -776,6 +783,7 @@ func (s *TestSuite) TestCreateGroupWithPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"10",
|
"10",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: false,
|
expErr: false,
|
||||||
},
|
},
|
||||||
|
@ -876,6 +884,7 @@ func (s *TestSuite) TestCreateGroupPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
"all good with percentage decision policy": {
|
"all good with percentage decision policy": {
|
||||||
|
@ -886,6 +895,7 @@ func (s *TestSuite) TestCreateGroupPolicy() {
|
||||||
policy: group.NewPercentageDecisionPolicy(
|
policy: group.NewPercentageDecisionPolicy(
|
||||||
"0.5",
|
"0.5",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
"decision policy threshold > total group weight": {
|
"decision policy threshold > total group weight": {
|
||||||
|
@ -896,6 +906,7 @@ func (s *TestSuite) TestCreateGroupPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"10",
|
"10",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
"group id does not exists": {
|
"group id does not exists": {
|
||||||
|
@ -906,6 +917,7 @@ func (s *TestSuite) TestCreateGroupPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: true,
|
expErr: true,
|
||||||
expErrMsg: "not found",
|
expErrMsg: "not found",
|
||||||
|
@ -918,6 +930,7 @@ func (s *TestSuite) TestCreateGroupPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: true,
|
expErr: true,
|
||||||
expErrMsg: "not group admin",
|
expErrMsg: "not group admin",
|
||||||
|
@ -931,6 +944,7 @@ func (s *TestSuite) TestCreateGroupPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: true,
|
expErr: true,
|
||||||
expErrMsg: "limit exceeded",
|
expErrMsg: "limit exceeded",
|
||||||
|
@ -943,6 +957,7 @@ func (s *TestSuite) TestCreateGroupPolicy() {
|
||||||
policy: group.NewPercentageDecisionPolicy(
|
policy: group.NewPercentageDecisionPolicy(
|
||||||
"-0.5",
|
"-0.5",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: true,
|
expErr: true,
|
||||||
expErrMsg: "expected a positive decimal",
|
expErrMsg: "expected a positive decimal",
|
||||||
|
@ -955,6 +970,7 @@ func (s *TestSuite) TestCreateGroupPolicy() {
|
||||||
policy: group.NewPercentageDecisionPolicy(
|
policy: group.NewPercentageDecisionPolicy(
|
||||||
"2",
|
"2",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expErr: true,
|
expErr: true,
|
||||||
expErrMsg: "percentage must be > 0 and <= 1",
|
expErrMsg: "percentage must be > 0 and <= 1",
|
||||||
|
@ -1194,6 +1210,7 @@ func (s *TestSuite) TestUpdateGroupPolicyDecisionPolicy() {
|
||||||
policy: group.NewThresholdDecisionPolicy(
|
policy: group.NewThresholdDecisionPolicy(
|
||||||
"2",
|
"2",
|
||||||
time.Duration(2)*time.Second,
|
time.Duration(2)*time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expGroupPolicy: &group.GroupPolicyInfo{
|
expGroupPolicy: &group.GroupPolicyInfo{
|
||||||
Admin: admin.String(),
|
Admin: admin.String(),
|
||||||
|
@ -1216,6 +1233,7 @@ func (s *TestSuite) TestUpdateGroupPolicyDecisionPolicy() {
|
||||||
policy: group.NewPercentageDecisionPolicy(
|
policy: group.NewPercentageDecisionPolicy(
|
||||||
"0.5",
|
"0.5",
|
||||||
time.Duration(2)*time.Second,
|
time.Duration(2)*time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
expGroupPolicy: &group.GroupPolicyInfo{
|
expGroupPolicy: &group.GroupPolicyInfo{
|
||||||
Admin: admin.String(),
|
Admin: admin.String(),
|
||||||
|
@ -1278,14 +1296,17 @@ func (s *TestSuite) TestGroupPoliciesByAdminOrGroup() {
|
||||||
group.NewThresholdDecisionPolicy(
|
group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
group.NewThresholdDecisionPolicy(
|
group.NewThresholdDecisionPolicy(
|
||||||
"10",
|
"10",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
group.NewPercentageDecisionPolicy(
|
group.NewPercentageDecisionPolicy(
|
||||||
"0.5",
|
"0.5",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1376,6 +1397,7 @@ func (s *TestSuite) TestSubmitProposal() {
|
||||||
policy := group.NewThresholdDecisionPolicy(
|
policy := group.NewThresholdDecisionPolicy(
|
||||||
"100",
|
"100",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
err := policyReq.SetDecisionPolicy(policy)
|
err := policyReq.SetDecisionPolicy(policy)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
@ -1523,7 +1545,7 @@ func (s *TestSuite) TestSubmitProposal() {
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
FinalTallyResult: group.TallyResult{
|
FinalTallyResult: group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "0", // Since tally doesn't pass Allow(), we consider the proposal not final
|
||||||
NoCount: "0",
|
NoCount: "0",
|
||||||
AbstainCount: "0",
|
AbstainCount: "0",
|
||||||
NoWithVetoCount: "0",
|
NoWithVetoCount: "0",
|
||||||
|
@ -1562,7 +1584,7 @@ func (s *TestSuite) TestSubmitProposal() {
|
||||||
s.Assert().Equal(spec.expProposal.Result, proposal.Result)
|
s.Assert().Equal(spec.expProposal.Result, proposal.Result)
|
||||||
s.Assert().Equal(spec.expProposal.FinalTallyResult, proposal.FinalTallyResult)
|
s.Assert().Equal(spec.expProposal.FinalTallyResult, proposal.FinalTallyResult)
|
||||||
s.Assert().Equal(spec.expProposal.ExecutorResult, proposal.ExecutorResult)
|
s.Assert().Equal(spec.expProposal.ExecutorResult, proposal.ExecutorResult)
|
||||||
s.Assert().Equal(s.blockTime.Add(time.Second), proposal.Timeout)
|
s.Assert().Equal(s.blockTime.Add(time.Second), proposal.VotingPeriodEnd)
|
||||||
|
|
||||||
if spec.msgs == nil { // then empty list is ok
|
if spec.msgs == nil { // then empty list is ok
|
||||||
s.Assert().Len(proposal.GetMsgs(), 0)
|
s.Assert().Len(proposal.GetMsgs(), 0)
|
||||||
|
@ -1684,6 +1706,7 @@ func (s *TestSuite) TestVote() {
|
||||||
policy := group.NewThresholdDecisionPolicy(
|
policy := group.NewThresholdDecisionPolicy(
|
||||||
"2",
|
"2",
|
||||||
time.Duration(2),
|
time.Duration(2),
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
policyReq := &group.MsgCreateGroupPolicy{
|
policyReq := &group.MsgCreateGroupPolicy{
|
||||||
Admin: addr1.String(),
|
Admin: addr1.String(),
|
||||||
|
@ -1732,22 +1755,18 @@ func (s *TestSuite) TestVote() {
|
||||||
s.Assert().Equal(uint64(1), proposals[0].GroupPolicyVersion)
|
s.Assert().Equal(uint64(1), proposals[0].GroupPolicyVersion)
|
||||||
s.Assert().Equal(group.PROPOSAL_STATUS_SUBMITTED, proposals[0].Status)
|
s.Assert().Equal(group.PROPOSAL_STATUS_SUBMITTED, proposals[0].Status)
|
||||||
s.Assert().Equal(group.PROPOSAL_RESULT_UNFINALIZED, proposals[0].Result)
|
s.Assert().Equal(group.PROPOSAL_RESULT_UNFINALIZED, proposals[0].Result)
|
||||||
s.Assert().Equal(group.TallyResult{
|
s.Assert().Equal(group.DefaultTallyResult(), proposals[0].FinalTallyResult)
|
||||||
YesCount: "0",
|
|
||||||
NoCount: "0",
|
|
||||||
AbstainCount: "0",
|
|
||||||
NoWithVetoCount: "0",
|
|
||||||
}, proposals[0].FinalTallyResult)
|
|
||||||
|
|
||||||
specs := map[string]struct {
|
specs := map[string]struct {
|
||||||
srcCtx sdk.Context
|
srcCtx sdk.Context
|
||||||
expFinalTallyResult group.TallyResult
|
expTallyResult group.TallyResult // expected after tallying
|
||||||
|
isFinal bool // is the tally result final?
|
||||||
req *group.MsgVote
|
req *group.MsgVote
|
||||||
doBefore func(ctx context.Context)
|
doBefore func(ctx context.Context)
|
||||||
postRun func(sdkCtx sdk.Context)
|
postRun func(sdkCtx sdk.Context)
|
||||||
expProposalStatus group.ProposalStatus
|
expProposalStatus group.ProposalStatus // expected after tallying
|
||||||
expResult group.ProposalResult
|
expResult group.ProposalResult // expected after tallying
|
||||||
expExecutorResult group.ProposalExecutorResult
|
expExecutorResult group.ProposalExecutorResult // expected after tallying
|
||||||
expErr bool
|
expErr bool
|
||||||
}{
|
}{
|
||||||
"vote yes": {
|
"vote yes": {
|
||||||
|
@ -1756,7 +1775,7 @@ func (s *TestSuite) TestVote() {
|
||||||
Voter: addr4.String(),
|
Voter: addr4.String(),
|
||||||
Option: group.VOTE_OPTION_YES,
|
Option: group.VOTE_OPTION_YES,
|
||||||
},
|
},
|
||||||
expFinalTallyResult: group.TallyResult{
|
expTallyResult: group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "1",
|
||||||
NoCount: "0",
|
NoCount: "0",
|
||||||
AbstainCount: "0",
|
AbstainCount: "0",
|
||||||
|
@ -1774,12 +1793,13 @@ func (s *TestSuite) TestVote() {
|
||||||
Option: group.VOTE_OPTION_YES,
|
Option: group.VOTE_OPTION_YES,
|
||||||
Exec: group.Exec_EXEC_TRY,
|
Exec: group.Exec_EXEC_TRY,
|
||||||
},
|
},
|
||||||
expFinalTallyResult: group.TallyResult{
|
expTallyResult: group.TallyResult{
|
||||||
YesCount: "2",
|
YesCount: "2",
|
||||||
NoCount: "0",
|
NoCount: "0",
|
||||||
AbstainCount: "0",
|
AbstainCount: "0",
|
||||||
NoWithVetoCount: "0",
|
NoWithVetoCount: "0",
|
||||||
},
|
},
|
||||||
|
isFinal: true,
|
||||||
expProposalStatus: group.PROPOSAL_STATUS_CLOSED,
|
expProposalStatus: group.PROPOSAL_STATUS_CLOSED,
|
||||||
expResult: group.PROPOSAL_RESULT_ACCEPTED,
|
expResult: group.PROPOSAL_RESULT_ACCEPTED,
|
||||||
expExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_SUCCESS,
|
expExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_SUCCESS,
|
||||||
|
@ -1797,7 +1817,7 @@ func (s *TestSuite) TestVote() {
|
||||||
Option: group.VOTE_OPTION_YES,
|
Option: group.VOTE_OPTION_YES,
|
||||||
Exec: group.Exec_EXEC_TRY,
|
Exec: group.Exec_EXEC_TRY,
|
||||||
},
|
},
|
||||||
expFinalTallyResult: group.TallyResult{
|
expTallyResult: group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "1",
|
||||||
NoCount: "0",
|
NoCount: "0",
|
||||||
AbstainCount: "0",
|
AbstainCount: "0",
|
||||||
|
@ -1814,7 +1834,7 @@ func (s *TestSuite) TestVote() {
|
||||||
Voter: addr4.String(),
|
Voter: addr4.String(),
|
||||||
Option: group.VOTE_OPTION_NO,
|
Option: group.VOTE_OPTION_NO,
|
||||||
},
|
},
|
||||||
expFinalTallyResult: group.TallyResult{
|
expTallyResult: group.TallyResult{
|
||||||
YesCount: "0",
|
YesCount: "0",
|
||||||
NoCount: "1",
|
NoCount: "1",
|
||||||
AbstainCount: "0",
|
AbstainCount: "0",
|
||||||
|
@ -1831,7 +1851,7 @@ func (s *TestSuite) TestVote() {
|
||||||
Voter: addr4.String(),
|
Voter: addr4.String(),
|
||||||
Option: group.VOTE_OPTION_ABSTAIN,
|
Option: group.VOTE_OPTION_ABSTAIN,
|
||||||
},
|
},
|
||||||
expFinalTallyResult: group.TallyResult{
|
expTallyResult: group.TallyResult{
|
||||||
YesCount: "0",
|
YesCount: "0",
|
||||||
NoCount: "0",
|
NoCount: "0",
|
||||||
AbstainCount: "1",
|
AbstainCount: "1",
|
||||||
|
@ -1848,7 +1868,7 @@ func (s *TestSuite) TestVote() {
|
||||||
Voter: addr4.String(),
|
Voter: addr4.String(),
|
||||||
Option: group.VOTE_OPTION_NO_WITH_VETO,
|
Option: group.VOTE_OPTION_NO_WITH_VETO,
|
||||||
},
|
},
|
||||||
expFinalTallyResult: group.TallyResult{
|
expTallyResult: group.TallyResult{
|
||||||
YesCount: "0",
|
YesCount: "0",
|
||||||
NoCount: "0",
|
NoCount: "0",
|
||||||
AbstainCount: "0",
|
AbstainCount: "0",
|
||||||
|
@ -1865,7 +1885,7 @@ func (s *TestSuite) TestVote() {
|
||||||
Voter: addr3.String(),
|
Voter: addr3.String(),
|
||||||
Option: group.VOTE_OPTION_YES,
|
Option: group.VOTE_OPTION_YES,
|
||||||
},
|
},
|
||||||
expFinalTallyResult: group.TallyResult{
|
expTallyResult: group.TallyResult{
|
||||||
YesCount: "2",
|
YesCount: "2",
|
||||||
NoCount: "0",
|
NoCount: "0",
|
||||||
AbstainCount: "0",
|
AbstainCount: "0",
|
||||||
|
@ -1887,6 +1907,7 @@ func (s *TestSuite) TestVote() {
|
||||||
ProposalId: myProposalID,
|
ProposalId: myProposalID,
|
||||||
Voter: addr3.String(),
|
Voter: addr3.String(),
|
||||||
Option: group.VOTE_OPTION_NO_WITH_VETO,
|
Option: group.VOTE_OPTION_NO_WITH_VETO,
|
||||||
|
Exec: 1, // Execute the proposal so that its status is final
|
||||||
})
|
})
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
},
|
},
|
||||||
|
@ -1947,7 +1968,7 @@ func (s *TestSuite) TestVote() {
|
||||||
expErr: true,
|
expErr: true,
|
||||||
postRun: func(sdkCtx sdk.Context) {},
|
postRun: func(sdkCtx sdk.Context) {},
|
||||||
},
|
},
|
||||||
"on timeout": {
|
"on voting period end": {
|
||||||
req: &group.MsgVote{
|
req: &group.MsgVote{
|
||||||
ProposalId: myProposalID,
|
ProposalId: myProposalID,
|
||||||
Voter: addr4.String(),
|
Voter: addr4.String(),
|
||||||
|
@ -1968,6 +1989,7 @@ func (s *TestSuite) TestVote() {
|
||||||
ProposalId: myProposalID,
|
ProposalId: myProposalID,
|
||||||
Voter: addr3.String(),
|
Voter: addr3.String(),
|
||||||
Option: group.VOTE_OPTION_YES,
|
Option: group.VOTE_OPTION_YES,
|
||||||
|
Exec: 1, // Execute to close the proposal.
|
||||||
})
|
})
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
},
|
},
|
||||||
|
@ -2019,7 +2041,9 @@ func (s *TestSuite) TestVote() {
|
||||||
groupPolicy,
|
groupPolicy,
|
||||||
&group.ThresholdDecisionPolicy{
|
&group.ThresholdDecisionPolicy{
|
||||||
Threshold: "1",
|
Threshold: "1",
|
||||||
Timeout: time.Second,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
@ -2093,16 +2117,26 @@ func (s *TestSuite) TestVote() {
|
||||||
s.Assert().Equal(spec.req.Metadata, votesByVoter[0].Metadata)
|
s.Assert().Equal(spec.req.Metadata, votesByVoter[0].Metadata)
|
||||||
s.Assert().Equal(s.blockTime, votesByVoter[0].SubmitTime)
|
s.Assert().Equal(s.blockTime, votesByVoter[0].SubmitTime)
|
||||||
|
|
||||||
// and proposal is updated
|
|
||||||
proposalRes, err := s.keeper.Proposal(ctx, &group.QueryProposalRequest{
|
proposalRes, err := s.keeper.Proposal(ctx, &group.QueryProposalRequest{
|
||||||
ProposalId: spec.req.ProposalId,
|
ProposalId: spec.req.ProposalId,
|
||||||
})
|
})
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
proposal := proposalRes.Proposal
|
proposal := proposalRes.Proposal
|
||||||
s.Assert().Equal(spec.expFinalTallyResult, proposal.FinalTallyResult)
|
if spec.isFinal {
|
||||||
|
s.Assert().Equal(spec.expTallyResult, proposal.FinalTallyResult)
|
||||||
s.Assert().Equal(spec.expResult, proposal.Result)
|
s.Assert().Equal(spec.expResult, proposal.Result)
|
||||||
s.Assert().Equal(spec.expProposalStatus, proposal.Status)
|
s.Assert().Equal(spec.expProposalStatus, proposal.Status)
|
||||||
s.Assert().Equal(spec.expExecutorResult, proposal.ExecutorResult)
|
s.Assert().Equal(spec.expExecutorResult, proposal.ExecutorResult)
|
||||||
|
} else {
|
||||||
|
s.Assert().Equal(group.DefaultTallyResult(), proposal.FinalTallyResult) // Make sure proposal isn't mutated.
|
||||||
|
|
||||||
|
// do a round of tallying
|
||||||
|
tallyResult, err := s.keeper.Tally(sdkCtx, *proposal, myGroupID)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
s.Assert().Equal(spec.expTallyResult, tallyResult)
|
||||||
|
}
|
||||||
|
|
||||||
spec.postRun(sdkCtx)
|
spec.postRun(sdkCtx)
|
||||||
})
|
})
|
||||||
|
@ -2370,6 +2404,7 @@ func createGroupAndGroupPolicy(
|
||||||
policy := group.NewThresholdDecisionPolicy(
|
policy := group.NewThresholdDecisionPolicy(
|
||||||
"1",
|
"1",
|
||||||
time.Second,
|
time.Second,
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
err = groupPolicy.SetDecisionPolicy(policy)
|
err = groupPolicy.SetDecisionPolicy(policy)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
|
@ -467,16 +467,11 @@ func (k Keeper) SubmitProposal(goCtx context.Context, req *group.MsgSubmitPropos
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent proposal that can not succeed.
|
// Prevent proposal that can not succeed.
|
||||||
err = policy.Validate(g)
|
err = policy.Validate(g, k.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define proposal timout.
|
|
||||||
// The voting window begins as soon as the proposal is submitted.
|
|
||||||
timeout := policy.GetTimeout()
|
|
||||||
window := timeout
|
|
||||||
|
|
||||||
m := &group.Proposal{
|
m := &group.Proposal{
|
||||||
Id: k.proposalTable.Sequence().PeekNextVal(ctx.KVStore(k.key)),
|
Id: k.proposalTable.Sequence().PeekNextVal(ctx.KVStore(k.key)),
|
||||||
Address: req.Address,
|
Address: req.Address,
|
||||||
|
@ -488,14 +483,10 @@ func (k Keeper) SubmitProposal(goCtx context.Context, req *group.MsgSubmitPropos
|
||||||
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
Result: group.PROPOSAL_RESULT_UNFINALIZED,
|
||||||
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
Status: group.PROPOSAL_STATUS_SUBMITTED,
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
Timeout: ctx.BlockTime().Add(window),
|
VotingPeriodEnd: ctx.BlockTime().Add(policy.GetVotingPeriod()), // The voting window begins as soon as the proposal is submitted.
|
||||||
FinalTallyResult: group.TallyResult{
|
FinalTallyResult: group.DefaultTallyResult(),
|
||||||
YesCount: "0",
|
|
||||||
NoCount: "0",
|
|
||||||
AbstainCount: "0",
|
|
||||||
NoWithVetoCount: "0",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.SetMsgs(msgs); err != nil {
|
if err := m.SetMsgs(msgs); err != nil {
|
||||||
return nil, sdkerrors.Wrap(err, "create proposal")
|
return nil, sdkerrors.Wrap(err, "create proposal")
|
||||||
}
|
}
|
||||||
|
@ -524,6 +515,7 @@ func (k Keeper) SubmitProposal(goCtx context.Context, req *group.MsgSubmitPropos
|
||||||
return &group.MsgSubmitProposalResponse{ProposalId: id}, sdkerrors.Wrap(err, "The proposal was created but failed on vote")
|
return &group.MsgSubmitProposalResponse{ProposalId: id}, sdkerrors.Wrap(err, "The proposal was created but failed on vote")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then try to execute the proposal
|
// Then try to execute the proposal
|
||||||
_, err = k.Exec(sdk.WrapSDKContext(ctx), &group.MsgExec{
|
_, err = k.Exec(sdk.WrapSDKContext(ctx), &group.MsgExec{
|
||||||
ProposalId: id,
|
ProposalId: id,
|
||||||
|
@ -619,15 +611,7 @@ func (k Keeper) Vote(goCtx context.Context, req *group.MsgVote) (*group.MsgVoteR
|
||||||
if proposal.Status != group.PROPOSAL_STATUS_SUBMITTED {
|
if proposal.Status != group.PROPOSAL_STATUS_SUBMITTED {
|
||||||
return nil, sdkerrors.Wrap(errors.ErrInvalid, "proposal not open for voting")
|
return nil, sdkerrors.Wrap(errors.ErrInvalid, "proposal not open for voting")
|
||||||
}
|
}
|
||||||
proposalTimeout, err := gogotypes.TimestampProto(proposal.Timeout)
|
if ctx.BlockTime().After(proposal.VotingPeriodEnd) {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
votingPeriodEnd, err := gogotypes.TimestampFromProto(proposalTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if votingPeriodEnd.Before(ctx.BlockTime()) || votingPeriodEnd.Equal(ctx.BlockTime()) {
|
|
||||||
return nil, sdkerrors.Wrap(errors.ErrExpired, "voting period has ended already")
|
return nil, sdkerrors.Wrap(errors.ErrExpired, "voting period has ended already")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,9 +647,6 @@ func (k Keeper) Vote(goCtx context.Context, req *group.MsgVote) (*group.MsgVoteR
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
SubmitTime: ctx.BlockTime(),
|
SubmitTime: ctx.BlockTime(),
|
||||||
}
|
}
|
||||||
if err := proposal.FinalTallyResult.Add(newVote, voter.Member.Weight); err != nil {
|
|
||||||
return nil, sdkerrors.Wrap(err, "add new vote")
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ORM will return an error if the vote already exists,
|
// The ORM will return an error if the vote already exists,
|
||||||
// making sure than a voter hasn't already voted.
|
// making sure than a voter hasn't already voted.
|
||||||
|
@ -673,15 +654,6 @@ func (k Keeper) Vote(goCtx context.Context, req *group.MsgVote) (*group.MsgVoteR
|
||||||
return nil, sdkerrors.Wrap(err, "store vote")
|
return nil, sdkerrors.Wrap(err, "store vote")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run tally with new votes to close early.
|
|
||||||
if err := doTally(ctx, &proposal, electorate, policyInfo); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = k.proposalTable.Update(ctx.KVStore(k.key), id, &proposal); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ctx.EventManager().EmitTypedEvent(&group.EventVote{ProposalId: id})
|
err = ctx.EventManager().EmitTypedEvent(&group.EventVote{ProposalId: id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -701,8 +673,9 @@ func (k Keeper) Vote(goCtx context.Context, req *group.MsgVote) (*group.MsgVoteR
|
||||||
return &group.MsgVoteResponse{}, nil
|
return &group.MsgVoteResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// doTally updates the proposal status and tally if necessary based on the group policy's decision policy.
|
// doTallyAndUpdate performs a tally, and updates the proposal's
|
||||||
func doTally(ctx sdk.Context, p *group.Proposal, electorate group.GroupInfo, policyInfo group.GroupPolicyInfo) error {
|
// `FinalTallyResult` field only if the tally is final.
|
||||||
|
func (k Keeper) doTallyAndUpdate(ctx sdk.Context, p *group.Proposal, electorate group.GroupInfo, policyInfo group.GroupPolicyInfo) error {
|
||||||
policy := policyInfo.GetDecisionPolicy()
|
policy := policyInfo.GetDecisionPolicy()
|
||||||
pSubmittedAt, err := gogotypes.TimestampProto(p.SubmitTime)
|
pSubmittedAt, err := gogotypes.TimestampProto(p.SubmitTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -712,16 +685,25 @@ func doTally(ctx sdk.Context, p *group.Proposal, electorate group.GroupInfo, pol
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
switch result, err := policy.Allow(p.FinalTallyResult, electorate.TotalWeight, ctx.BlockTime().Sub(submittedAt)); {
|
|
||||||
|
tallyResult, err := k.Tally(ctx, *p, policyInfo.GroupId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result, err := policy.Allow(tallyResult, electorate.TotalWeight, ctx.BlockTime().Sub(submittedAt)); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return sdkerrors.Wrap(err, "policy execution")
|
return sdkerrors.Wrap(err, "policy execution")
|
||||||
case result.Allow && result.Final:
|
case result.Allow && result.Final:
|
||||||
|
p.FinalTallyResult = tallyResult
|
||||||
p.Result = group.PROPOSAL_RESULT_ACCEPTED
|
p.Result = group.PROPOSAL_RESULT_ACCEPTED
|
||||||
p.Status = group.PROPOSAL_STATUS_CLOSED
|
p.Status = group.PROPOSAL_STATUS_CLOSED
|
||||||
case !result.Allow && result.Final:
|
case !result.Allow && result.Final:
|
||||||
|
p.FinalTallyResult = tallyResult
|
||||||
p.Result = group.PROPOSAL_RESULT_REJECTED
|
p.Result = group.PROPOSAL_RESULT_REJECTED
|
||||||
p.Status = group.PROPOSAL_STATUS_CLOSED
|
p.Status = group.PROPOSAL_STATUS_CLOSED
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,7 +752,8 @@ func (k Keeper) Exec(goCtx context.Context, req *group.MsgExec) (*group.MsgExecR
|
||||||
proposal.Status = group.PROPOSAL_STATUS_ABORTED
|
proposal.Status = group.PROPOSAL_STATUS_ABORTED
|
||||||
return storeUpdates()
|
return storeUpdates()
|
||||||
}
|
}
|
||||||
if err := doTally(ctx, &proposal, electorate, policyInfo); err != nil {
|
|
||||||
|
if err := k.doTallyAndUpdate(ctx, &proposal, electorate, policyInfo); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,16 @@ import (
|
||||||
// doExecuteMsgs routes the messages to the registered handlers. Messages are limited to those that require no authZ or
|
// doExecuteMsgs routes the messages to the registered handlers. Messages are limited to those that require no authZ or
|
||||||
// by the account of group policy only. Otherwise this gives access to other peoples accounts as the sdk ant handler is bypassed
|
// by the account of group policy only. Otherwise this gives access to other peoples accounts as the sdk ant handler is bypassed
|
||||||
func (s Keeper) doExecuteMsgs(ctx sdk.Context, router *authmiddleware.MsgServiceRouter, proposal group.Proposal, groupPolicyAcc sdk.AccAddress) ([]sdk.Result, error) {
|
func (s Keeper) doExecuteMsgs(ctx sdk.Context, router *authmiddleware.MsgServiceRouter, proposal group.Proposal, groupPolicyAcc sdk.AccAddress) ([]sdk.Result, error) {
|
||||||
|
// Ensure it's not too late to execute the messages.
|
||||||
|
// After https://github.com/cosmos/cosmos-sdk/issues/11245, proposals should
|
||||||
|
// be pruned automatically, so this function should not even be called, as
|
||||||
|
// the proposal doesn't exist in state. For sanity check, we can still keep
|
||||||
|
// this simple and cheap check.
|
||||||
|
expiryDate := proposal.VotingPeriodEnd.Add(s.config.MaxExecutionPeriod)
|
||||||
|
if expiryDate.Before(ctx.BlockTime()) {
|
||||||
|
return nil, grouperrors.ErrExpired.Wrapf("proposal expired on %s", expiryDate)
|
||||||
|
}
|
||||||
|
|
||||||
msgs := proposal.GetMsgs()
|
msgs := proposal.GetMsgs()
|
||||||
|
|
||||||
results := make([]sdk.Result, len(msgs))
|
results := make([]sdk.Result, len(msgs))
|
||||||
|
|
|
@ -367,7 +367,7 @@ func TestMsgCreateGroupWithPolicy(t *testing.T) {
|
||||||
"invalid admin address",
|
"invalid admin address",
|
||||||
func() *group.MsgCreateGroupWithPolicy {
|
func() *group.MsgCreateGroupWithPolicy {
|
||||||
admin := "admin"
|
admin := "admin"
|
||||||
policy := group.NewThresholdDecisionPolicy("1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
members := []group.Member{
|
members := []group.Member{
|
||||||
{
|
{
|
||||||
Address: member1.String(),
|
Address: member1.String(),
|
||||||
|
@ -385,7 +385,7 @@ func TestMsgCreateGroupWithPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"invalid member address",
|
"invalid member address",
|
||||||
func() *group.MsgCreateGroupWithPolicy {
|
func() *group.MsgCreateGroupWithPolicy {
|
||||||
policy := group.NewThresholdDecisionPolicy("1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
members := []group.Member{
|
members := []group.Member{
|
||||||
{
|
{
|
||||||
Address: "invalid_address",
|
Address: "invalid_address",
|
||||||
|
@ -403,7 +403,7 @@ func TestMsgCreateGroupWithPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"negative member's weight not allowed",
|
"negative member's weight not allowed",
|
||||||
func() *group.MsgCreateGroupWithPolicy {
|
func() *group.MsgCreateGroupWithPolicy {
|
||||||
policy := group.NewThresholdDecisionPolicy("1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
members := []group.Member{
|
members := []group.Member{
|
||||||
{
|
{
|
||||||
Address: member1.String(),
|
Address: member1.String(),
|
||||||
|
@ -421,7 +421,7 @@ func TestMsgCreateGroupWithPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"zero member's weight not allowed",
|
"zero member's weight not allowed",
|
||||||
func() *group.MsgCreateGroupWithPolicy {
|
func() *group.MsgCreateGroupWithPolicy {
|
||||||
policy := group.NewThresholdDecisionPolicy("1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
members := []group.Member{
|
members := []group.Member{
|
||||||
{
|
{
|
||||||
Address: member1.String(),
|
Address: member1.String(),
|
||||||
|
@ -439,7 +439,7 @@ func TestMsgCreateGroupWithPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"duplicate member not allowed",
|
"duplicate member not allowed",
|
||||||
func() *group.MsgCreateGroupWithPolicy {
|
func() *group.MsgCreateGroupWithPolicy {
|
||||||
policy := group.NewThresholdDecisionPolicy("1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
members := []group.Member{
|
members := []group.Member{
|
||||||
{
|
{
|
||||||
Address: member1.String(),
|
Address: member1.String(),
|
||||||
|
@ -462,7 +462,7 @@ func TestMsgCreateGroupWithPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"invalid threshold policy",
|
"invalid threshold policy",
|
||||||
func() *group.MsgCreateGroupWithPolicy {
|
func() *group.MsgCreateGroupWithPolicy {
|
||||||
policy := group.NewThresholdDecisionPolicy("-1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("-1", time.Second, 0)
|
||||||
members := []group.Member{
|
members := []group.Member{
|
||||||
{
|
{
|
||||||
Address: member1.String(),
|
Address: member1.String(),
|
||||||
|
@ -480,7 +480,7 @@ func TestMsgCreateGroupWithPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"valid test case with single member",
|
"valid test case with single member",
|
||||||
func() *group.MsgCreateGroupWithPolicy {
|
func() *group.MsgCreateGroupWithPolicy {
|
||||||
policy := group.NewThresholdDecisionPolicy("1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
members := []group.Member{
|
members := []group.Member{
|
||||||
{
|
{
|
||||||
Address: member1.String(),
|
Address: member1.String(),
|
||||||
|
@ -498,7 +498,7 @@ func TestMsgCreateGroupWithPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"valid test case with multiple members",
|
"valid test case with multiple members",
|
||||||
func() *group.MsgCreateGroupWithPolicy {
|
func() *group.MsgCreateGroupWithPolicy {
|
||||||
policy := group.NewThresholdDecisionPolicy("1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
members := []group.Member{
|
members := []group.Member{
|
||||||
{
|
{
|
||||||
Address: member1.String(),
|
Address: member1.String(),
|
||||||
|
@ -566,7 +566,7 @@ func TestMsgCreateGroupPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"invalid threshold policy",
|
"invalid threshold policy",
|
||||||
func() *group.MsgCreateGroupPolicy {
|
func() *group.MsgCreateGroupPolicy {
|
||||||
policy := group.NewThresholdDecisionPolicy("-1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("-1", time.Second, 0)
|
||||||
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return req
|
return req
|
||||||
|
@ -575,9 +575,53 @@ func TestMsgCreateGroupPolicy(t *testing.T) {
|
||||||
"expected a positive decimal",
|
"expected a positive decimal",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"valid test case",
|
"invalid voting period",
|
||||||
func() *group.MsgCreateGroupPolicy {
|
func() *group.MsgCreateGroupPolicy {
|
||||||
policy := group.NewThresholdDecisionPolicy("1", time.Second)
|
policy := group.NewThresholdDecisionPolicy("-1", time.Duration(0), 0)
|
||||||
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return req
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"expected a positive decimal",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid execution period",
|
||||||
|
func() *group.MsgCreateGroupPolicy {
|
||||||
|
policy := group.NewThresholdDecisionPolicy("-1", time.Minute, 0)
|
||||||
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return req
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"expected a positive decimal",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid test case, only voting period",
|
||||||
|
func() *group.MsgCreateGroupPolicy {
|
||||||
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return req
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid test case, voting and execution, empty min exec period",
|
||||||
|
func() *group.MsgCreateGroupPolicy {
|
||||||
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return req
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid test case, voting and execution, non-empty min exec period",
|
||||||
|
func() *group.MsgCreateGroupPolicy {
|
||||||
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, time.Minute)
|
||||||
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return req
|
return req
|
||||||
|
@ -588,7 +632,7 @@ func TestMsgCreateGroupPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"invalid percentage decision policy with zero value",
|
"invalid percentage decision policy with zero value",
|
||||||
func() *group.MsgCreateGroupPolicy {
|
func() *group.MsgCreateGroupPolicy {
|
||||||
percentagePolicy := group.NewPercentageDecisionPolicy("0", time.Second)
|
percentagePolicy := group.NewPercentageDecisionPolicy("0", time.Second, 0)
|
||||||
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return req
|
return req
|
||||||
|
@ -599,7 +643,7 @@ func TestMsgCreateGroupPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"invalid percentage decision policy with negative value",
|
"invalid percentage decision policy with negative value",
|
||||||
func() *group.MsgCreateGroupPolicy {
|
func() *group.MsgCreateGroupPolicy {
|
||||||
percentagePolicy := group.NewPercentageDecisionPolicy("-0.2", time.Second)
|
percentagePolicy := group.NewPercentageDecisionPolicy("-0.2", time.Second, 0)
|
||||||
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return req
|
return req
|
||||||
|
@ -610,7 +654,7 @@ func TestMsgCreateGroupPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"invalid percentage decision policy with value greater than 1",
|
"invalid percentage decision policy with value greater than 1",
|
||||||
func() *group.MsgCreateGroupPolicy {
|
func() *group.MsgCreateGroupPolicy {
|
||||||
percentagePolicy := group.NewPercentageDecisionPolicy("2", time.Second)
|
percentagePolicy := group.NewPercentageDecisionPolicy("2", time.Second, 0)
|
||||||
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return req
|
return req
|
||||||
|
@ -621,7 +665,7 @@ func TestMsgCreateGroupPolicy(t *testing.T) {
|
||||||
{
|
{
|
||||||
"valid test case with percentage decision policy",
|
"valid test case with percentage decision policy",
|
||||||
func() *group.MsgCreateGroupPolicy {
|
func() *group.MsgCreateGroupPolicy {
|
||||||
percentagePolicy := group.NewPercentageDecisionPolicy("0.5", time.Second)
|
percentagePolicy := group.NewPercentageDecisionPolicy("0.5", time.Second, 0)
|
||||||
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return req
|
return req
|
||||||
|
@ -647,23 +691,23 @@ func TestMsgCreateGroupPolicy(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMsgUpdateGroupPolicyDecisionPolicy(t *testing.T) {
|
func TestMsgUpdateGroupPolicyDecisionPolicy(t *testing.T) {
|
||||||
validPolicy := group.NewThresholdDecisionPolicy("1", time.Second)
|
validPolicy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
||||||
msg1, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member1, validPolicy)
|
msg1, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member1, validPolicy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
invalidPolicy := group.NewThresholdDecisionPolicy("-1", time.Second)
|
invalidPolicy := group.NewThresholdDecisionPolicy("-1", time.Second, 0)
|
||||||
msg2, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member2, invalidPolicy)
|
msg2, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member2, invalidPolicy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
validPercentagePolicy := group.NewPercentageDecisionPolicy("0.7", time.Second)
|
validPercentagePolicy := group.NewPercentageDecisionPolicy("0.7", time.Second, 0)
|
||||||
msg3, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member3, validPercentagePolicy)
|
msg3, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member3, validPercentagePolicy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
invalidPercentagePolicy := group.NewPercentageDecisionPolicy("-0.1", time.Second)
|
invalidPercentagePolicy := group.NewPercentageDecisionPolicy("-0.1", time.Second, 0)
|
||||||
msg4, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member4, invalidPercentagePolicy)
|
msg4, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member4, invalidPercentagePolicy)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
invalidPercentagePolicy2 := group.NewPercentageDecisionPolicy("2", time.Second)
|
invalidPercentagePolicy2 := group.NewPercentageDecisionPolicy("2", time.Second, 0)
|
||||||
msg5, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member5, invalidPercentagePolicy2)
|
msg5, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member5, invalidPercentagePolicy2)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ func getGroupPolicies(r *rand.Rand, simState *module.SimulationState) []*group.G
|
||||||
groupPolicies := make([]*group.GroupPolicyInfo, 3)
|
groupPolicies := make([]*group.GroupPolicyInfo, 3)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
acc, _ := simtypes.RandomAcc(r, simState.Accounts)
|
acc, _ := simtypes.RandomAcc(r, simState.Accounts)
|
||||||
any, err := codectypes.NewAnyWithValue(group.NewThresholdDecisionPolicy("10", time.Second*time.Duration(1)))
|
any, err := codectypes.NewAnyWithValue(group.NewThresholdDecisionPolicy("10", time.Second, 0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ func getProposals(r *rand.Rand, simState *module.SimulationState) []*group.Propo
|
||||||
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
ExecutorResult: group.PROPOSAL_EXECUTOR_RESULT_NOT_RUN,
|
||||||
Metadata: simtypes.RandStringOfLength(r, 50),
|
Metadata: simtypes.RandStringOfLength(r, 50),
|
||||||
SubmitTime: submittedAt,
|
SubmitTime: submittedAt,
|
||||||
Timeout: timeout,
|
VotingPeriodEnd: timeout,
|
||||||
}
|
}
|
||||||
err := proposal.SetMsgs([]sdk.Msg{&banktypes.MsgSend{
|
err := proposal.SetMsgs([]sdk.Msg{&banktypes.MsgSend{
|
||||||
FromAddress: fromAddr,
|
FromAddress: fromAddr,
|
||||||
|
|
|
@ -285,7 +285,9 @@ func SimulateMsgCreateGroupWithPolicy(ak group.AccountKeeper, bk group.BankKeepe
|
||||||
members := genGroupMembers(r, accounts)
|
members := genGroupMembers(r, accounts)
|
||||||
decisionPolicy := &group.ThresholdDecisionPolicy{
|
decisionPolicy := &group.ThresholdDecisionPolicy{
|
||||||
Threshold: fmt.Sprintf("%d", simtypes.RandIntBetween(r, 1, 10)),
|
Threshold: fmt.Sprintf("%d", simtypes.RandIntBetween(r, 1, 10)),
|
||||||
Timeout: time.Second * time.Duration(30*24*60*60),
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * time.Duration(30*24*60*60),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := &group.MsgCreateGroupWithPolicy{
|
msg := &group.MsgCreateGroupWithPolicy{
|
||||||
|
@ -349,7 +351,9 @@ func SimulateMsgCreateGroupPolicy(ak group.AccountKeeper, bk group.BankKeeper, k
|
||||||
simtypes.RandStringOfLength(r, 10),
|
simtypes.RandStringOfLength(r, 10),
|
||||||
&group.ThresholdDecisionPolicy{
|
&group.ThresholdDecisionPolicy{
|
||||||
Threshold: fmt.Sprintf("%d", simtypes.RandIntBetween(r, 1, 10)),
|
Threshold: fmt.Sprintf("%d", simtypes.RandIntBetween(r, 1, 10)),
|
||||||
Timeout: time.Second * time.Duration(30*24*60*60),
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * time.Duration(30*24*60*60),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -400,7 +404,7 @@ func SimulateMsgSubmitProposal(ak group.AccountKeeper, bk group.BankKeeper, k ke
|
||||||
|
|
||||||
// Return a no-op if we know the proposal cannot be created
|
// Return a no-op if we know the proposal cannot be created
|
||||||
policy := groupPolicy.GetDecisionPolicy()
|
policy := groupPolicy.GetDecisionPolicy()
|
||||||
err = policy.Validate(*g)
|
err = policy.Validate(*g, group.DefaultConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return simtypes.NoOpMsg(group.ModuleName, TypeMsgSubmitProposal, ""), nil, nil
|
return simtypes.NoOpMsg(group.ModuleName, TypeMsgSubmitProposal, ""), nil, nil
|
||||||
}
|
}
|
||||||
|
@ -721,7 +725,9 @@ func SimulateMsgUpdateGroupPolicyDecisionPolicy(ak group.AccountKeeper,
|
||||||
|
|
||||||
msg, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(acc.Address, groupPolicyBech32, &group.ThresholdDecisionPolicy{
|
msg, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(acc.Address, groupPolicyBech32, &group.ThresholdDecisionPolicy{
|
||||||
Threshold: fmt.Sprintf("%d", simtypes.RandIntBetween(r, 1, 10)),
|
Threshold: fmt.Sprintf("%d", simtypes.RandIntBetween(r, 1, 10)),
|
||||||
Timeout: time.Second * time.Duration(simtypes.RandIntBetween(r, 100, 1000)),
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * time.Duration(simtypes.RandIntBetween(r, 100, 1000)),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyDecisionPolicy, err.Error()), nil, err
|
return simtypes.NoOpMsg(group.ModuleName, TypeMsgUpdateGroupPolicyDecisionPolicy, err.Error()), nil, err
|
||||||
|
@ -820,7 +826,7 @@ func SimulateMsgWithdrawProposal(ak group.AccountKeeper,
|
||||||
ctx := sdk.WrapSDKContext(sdkCtx)
|
ctx := sdk.WrapSDKContext(sdkCtx)
|
||||||
|
|
||||||
policy := groupPolicy.GetDecisionPolicy()
|
policy := groupPolicy.GetDecisionPolicy()
|
||||||
err = policy.Validate(*g)
|
err = policy.Validate(*g, group.DefaultConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return simtypes.NoOpMsg(group.ModuleName, TypeMsgWithdrawProposal, err.Error()), nil, nil
|
return simtypes.NoOpMsg(group.ModuleName, TypeMsgWithdrawProposal, err.Error()), nil, nil
|
||||||
}
|
}
|
||||||
|
@ -840,7 +846,7 @@ func SimulateMsgWithdrawProposal(ak group.AccountKeeper,
|
||||||
|
|
||||||
for _, p := range proposals {
|
for _, p := range proposals {
|
||||||
if p.Status == group.PROPOSAL_STATUS_SUBMITTED {
|
if p.Status == group.PROPOSAL_STATUS_SUBMITTED {
|
||||||
timeout := p.Timeout
|
timeout := p.VotingPeriodEnd
|
||||||
proposal = p
|
proposal = p
|
||||||
proposalID = int(p.Id)
|
proposalID = int(p.Id)
|
||||||
if timeout.Before(sdkCtx.BlockTime()) || timeout.Equal(sdkCtx.BlockTime()) {
|
if timeout.Before(sdkCtx.BlockTime()) || timeout.Equal(sdkCtx.BlockTime()) {
|
||||||
|
@ -959,7 +965,7 @@ func SimulateMsgVote(ak group.AccountKeeper,
|
||||||
|
|
||||||
for _, p := range proposals {
|
for _, p := range proposals {
|
||||||
if p.Status == group.PROPOSAL_STATUS_SUBMITTED {
|
if p.Status == group.PROPOSAL_STATUS_SUBMITTED {
|
||||||
timeout := p.Timeout
|
timeout := p.VotingPeriodEnd
|
||||||
proposal = p
|
proposal = p
|
||||||
proposalID = int(p.Id)
|
proposalID = int(p.Id)
|
||||||
if timeout.Before(sdkCtx.BlockTime()) || timeout.Equal(sdkCtx.BlockTime()) {
|
if timeout.Before(sdkCtx.BlockTime()) || timeout.Equal(sdkCtx.BlockTime()) {
|
||||||
|
@ -1032,27 +1038,27 @@ func SimulateMsgExec(ak group.AccountKeeper,
|
||||||
r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
r *rand.Rand, app *baseapp.BaseApp, sdkCtx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||||
_, groupPolicy, acc, account, err := randomGroupPolicy(r, k, ak, sdkCtx, accounts)
|
_, groupPolicy, acc, account, err := randomGroupPolicy(r, k, ak, sdkCtx, accounts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, ""), nil, err
|
return simtypes.NoOpMsg(TypeMsgExec, TypeMsgExec, ""), nil, err
|
||||||
}
|
}
|
||||||
if groupPolicy == nil {
|
if groupPolicy == nil {
|
||||||
return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "no group policy found"), nil, nil
|
return simtypes.NoOpMsg(TypeMsgExec, TypeMsgExec, "no group policy found"), nil, nil
|
||||||
}
|
}
|
||||||
groupPolicyAddr := groupPolicy.Address
|
groupPolicyAddr := groupPolicy.Address
|
||||||
|
|
||||||
spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress())
|
spendableCoins := bk.SpendableCoins(sdkCtx, account.GetAddress())
|
||||||
fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins)
|
fees, err := simtypes.RandomFees(r, sdkCtx, spendableCoins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "fee error"), nil, err
|
return simtypes.NoOpMsg(TypeMsgExec, TypeMsgExec, "fee error"), nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := sdk.WrapSDKContext(sdkCtx)
|
ctx := sdk.WrapSDKContext(sdkCtx)
|
||||||
proposalsResult, err := k.ProposalsByGroupPolicy(ctx, &group.QueryProposalsByGroupPolicyRequest{Address: groupPolicyAddr})
|
proposalsResult, err := k.ProposalsByGroupPolicy(ctx, &group.QueryProposalsByGroupPolicyRequest{Address: groupPolicyAddr})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "fail to query group info"), nil, err
|
return simtypes.NoOpMsg(TypeMsgExec, TypeMsgExec, "fail to query group info"), nil, err
|
||||||
}
|
}
|
||||||
proposals := proposalsResult.GetProposals()
|
proposals := proposalsResult.GetProposals()
|
||||||
if len(proposals) == 0 {
|
if len(proposals) == 0 {
|
||||||
return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "no proposals found"), nil, nil
|
return simtypes.NoOpMsg(TypeMsgExec, TypeMsgExec, "no proposals found"), nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
proposalID := -1
|
proposalID := -1
|
||||||
|
@ -1066,7 +1072,7 @@ func SimulateMsgExec(ak group.AccountKeeper,
|
||||||
|
|
||||||
// return no-op if no proposal found
|
// return no-op if no proposal found
|
||||||
if proposalID == -1 {
|
if proposalID == -1 {
|
||||||
return simtypes.NoOpMsg(group.ModuleName, TypeMsgExec, "no proposals found"), nil, nil
|
return simtypes.NoOpMsg(TypeMsgExec, TypeMsgExec, "no proposals found"), nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := group.MsgExec{
|
msg := group.MsgExec{
|
||||||
|
|
|
@ -221,7 +221,7 @@ func (suite *SimTestSuite) TestSimulateSubmitProposal() {
|
||||||
Admin: acc.Address.String(),
|
Admin: acc.Address.String(),
|
||||||
GroupId: groupRes.GroupId,
|
GroupId: groupRes.GroupId,
|
||||||
}
|
}
|
||||||
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour))
|
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour, 0))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
@ -275,7 +275,7 @@ func (suite *SimTestSuite) TestWithdrawProposal() {
|
||||||
Admin: addr,
|
Admin: addr,
|
||||||
GroupId: groupRes.GroupId,
|
GroupId: groupRes.GroupId,
|
||||||
}
|
}
|
||||||
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour))
|
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour, 0))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
@ -342,7 +342,7 @@ func (suite *SimTestSuite) TestSimulateVote() {
|
||||||
GroupId: groupRes.GroupId,
|
GroupId: groupRes.GroupId,
|
||||||
Metadata: "",
|
Metadata: "",
|
||||||
}
|
}
|
||||||
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour))
|
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour, 0))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
@ -408,7 +408,7 @@ func (suite *SimTestSuite) TestSimulateExec() {
|
||||||
Admin: addr,
|
Admin: addr,
|
||||||
GroupId: groupRes.GroupId,
|
GroupId: groupRes.GroupId,
|
||||||
}
|
}
|
||||||
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour))
|
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour, 0))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
@ -430,6 +430,7 @@ func (suite *SimTestSuite) TestSimulateExec() {
|
||||||
ProposalId: proposalRes.ProposalId,
|
ProposalId: proposalRes.ProposalId,
|
||||||
Voter: addr,
|
Voter: addr,
|
||||||
Option: group.VOTE_OPTION_YES,
|
Option: group.VOTE_OPTION_YES,
|
||||||
|
Exec: 1,
|
||||||
})
|
})
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
@ -607,7 +608,7 @@ func (suite *SimTestSuite) TestSimulateUpdateGroupPolicyAdmin() {
|
||||||
Admin: acc.Address.String(),
|
Admin: acc.Address.String(),
|
||||||
GroupId: groupRes.GroupId,
|
GroupId: groupRes.GroupId,
|
||||||
}
|
}
|
||||||
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour))
|
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour, 0))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
@ -660,7 +661,7 @@ func (suite *SimTestSuite) TestSimulateUpdateGroupPolicyDecisionPolicy() {
|
||||||
Admin: acc.Address.String(),
|
Admin: acc.Address.String(),
|
||||||
GroupId: groupRes.GroupId,
|
GroupId: groupRes.GroupId,
|
||||||
}
|
}
|
||||||
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour))
|
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour, 0))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
@ -713,7 +714,7 @@ func (suite *SimTestSuite) TestSimulateUpdateGroupPolicyMetadata() {
|
||||||
Admin: acc.Address.String(),
|
Admin: acc.Address.String(),
|
||||||
GroupId: groupRes.GroupId,
|
GroupId: groupRes.GroupId,
|
||||||
}
|
}
|
||||||
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour))
|
err = accountReq.SetDecisionPolicy(group.NewThresholdDecisionPolicy("1", time.Hour, 0))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
groupPolicyRes, err := suite.app.GroupKeeper.CreateGroupPolicy(ctx, accountReq)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
|
@ -24,18 +24,28 @@ type DecisionPolicyResult struct {
|
||||||
type DecisionPolicy interface {
|
type DecisionPolicy interface {
|
||||||
codec.ProtoMarshaler
|
codec.ProtoMarshaler
|
||||||
|
|
||||||
|
// GetVotingPeriod returns the duration after proposal submission where
|
||||||
|
// votes are accepted.
|
||||||
|
GetVotingPeriod() time.Duration
|
||||||
|
// Allow defines policy-specific logic to allow a proposal to pass or not,
|
||||||
|
// based on its tally result, the group's total power and the time since
|
||||||
|
// the proposal was submitted.
|
||||||
|
Allow(tallyResult TallyResult, totalPower string, sinceSubmission time.Duration) (DecisionPolicyResult, error)
|
||||||
|
|
||||||
ValidateBasic() error
|
ValidateBasic() error
|
||||||
GetTimeout() time.Duration
|
Validate(g GroupInfo, config Config) error
|
||||||
Allow(tallyResult TallyResult, totalPower string, votingDuration time.Duration) (DecisionPolicyResult, error)
|
|
||||||
Validate(g GroupInfo) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements DecisionPolicy Interface
|
// Implements DecisionPolicy Interface
|
||||||
var _ DecisionPolicy = &ThresholdDecisionPolicy{}
|
var _ DecisionPolicy = &ThresholdDecisionPolicy{}
|
||||||
|
|
||||||
// NewThresholdDecisionPolicy creates a threshold DecisionPolicy
|
// NewThresholdDecisionPolicy creates a threshold DecisionPolicy
|
||||||
func NewThresholdDecisionPolicy(threshold string, timeout time.Duration) DecisionPolicy {
|
func NewThresholdDecisionPolicy(threshold string, votingPeriod time.Duration, minExecutionPeriod time.Duration) DecisionPolicy {
|
||||||
return &ThresholdDecisionPolicy{threshold, timeout}
|
return &ThresholdDecisionPolicy{threshold, &DecisionPolicyWindows{votingPeriod, minExecutionPeriod}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p ThresholdDecisionPolicy) GetVotingPeriod() time.Duration {
|
||||||
|
return p.Windows.VotingPeriod
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p ThresholdDecisionPolicy) ValidateBasic() error {
|
func (p ThresholdDecisionPolicy) ValidateBasic() error {
|
||||||
|
@ -43,19 +53,17 @@ func (p ThresholdDecisionPolicy) ValidateBasic() error {
|
||||||
return sdkerrors.Wrap(err, "threshold")
|
return sdkerrors.Wrap(err, "threshold")
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout := p.Timeout
|
if p.Windows == nil || p.Windows.VotingPeriod == 0 {
|
||||||
|
return sdkerrors.Wrap(errors.ErrInvalid, "voting period cannot be zero")
|
||||||
if timeout <= time.Nanosecond {
|
|
||||||
return sdkerrors.Wrap(errors.ErrInvalid, "timeout")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow allows a proposal to pass when the tally of yes votes equals or exceeds the threshold before the timeout.
|
// Allow allows a proposal to pass when the tally of yes votes equals or exceeds the threshold before the timeout.
|
||||||
func (p ThresholdDecisionPolicy) Allow(tallyResult TallyResult, totalPower string, votingDuration time.Duration) (DecisionPolicyResult, error) {
|
func (p ThresholdDecisionPolicy) Allow(tallyResult TallyResult, totalPower string, sinceSubmission time.Duration) (DecisionPolicyResult, error) {
|
||||||
timeout := p.Timeout
|
if sinceSubmission < p.Windows.MinExecutionPeriod {
|
||||||
if timeout <= votingDuration {
|
return DecisionPolicyResult{}, errors.ErrUnauthorized.Wrapf("must wait %s after submission before execution, currently at %s", p.Windows.MinExecutionPeriod, sinceSubmission)
|
||||||
return DecisionPolicyResult{Allow: false, Final: true}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
threshold, err := math.NewPositiveDecFromString(p.Threshold)
|
threshold, err := math.NewPositiveDecFromString(p.Threshold)
|
||||||
|
@ -93,7 +101,7 @@ func (p ThresholdDecisionPolicy) Allow(tallyResult TallyResult, totalPower strin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate returns an error if policy threshold is greater than the total group weight
|
// Validate returns an error if policy threshold is greater than the total group weight
|
||||||
func (p *ThresholdDecisionPolicy) Validate(g GroupInfo) error {
|
func (p *ThresholdDecisionPolicy) Validate(g GroupInfo, config Config) error {
|
||||||
threshold, err := math.NewPositiveDecFromString(p.Threshold)
|
threshold, err := math.NewPositiveDecFromString(p.Threshold)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sdkerrors.Wrap(err, "threshold")
|
return sdkerrors.Wrap(err, "threshold")
|
||||||
|
@ -105,6 +113,9 @@ func (p *ThresholdDecisionPolicy) Validate(g GroupInfo) error {
|
||||||
if threshold.Cmp(totalWeight) > 0 {
|
if threshold.Cmp(totalWeight) > 0 {
|
||||||
return sdkerrors.Wrapf(errors.ErrInvalid, "policy threshold %s should not be greater than the total group weight %s", p.Threshold, g.TotalWeight)
|
return sdkerrors.Wrapf(errors.ErrInvalid, "policy threshold %s should not be greater than the total group weight %s", p.Threshold, g.TotalWeight)
|
||||||
}
|
}
|
||||||
|
if p.Windows.MinExecutionPeriod > p.Windows.VotingPeriod+config.MaxExecutionPeriod {
|
||||||
|
return sdkerrors.Wrap(errors.ErrInvalid, "min_execution_period should be smaller than voting_period + max_execution_period")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +123,12 @@ func (p *ThresholdDecisionPolicy) Validate(g GroupInfo) error {
|
||||||
var _ DecisionPolicy = &PercentageDecisionPolicy{}
|
var _ DecisionPolicy = &PercentageDecisionPolicy{}
|
||||||
|
|
||||||
// NewPercentageDecisionPolicy creates a new percentage DecisionPolicy
|
// NewPercentageDecisionPolicy creates a new percentage DecisionPolicy
|
||||||
func NewPercentageDecisionPolicy(percentage string, timeout time.Duration) DecisionPolicy {
|
func NewPercentageDecisionPolicy(percentage string, votingPeriod time.Duration, executionPeriod time.Duration) DecisionPolicy {
|
||||||
return &PercentageDecisionPolicy{percentage, timeout}
|
return &PercentageDecisionPolicy{percentage, &DecisionPolicyWindows{votingPeriod, executionPeriod}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p PercentageDecisionPolicy) GetVotingPeriod() time.Duration {
|
||||||
|
return p.Windows.VotingPeriod
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p PercentageDecisionPolicy) ValidateBasic() error {
|
func (p PercentageDecisionPolicy) ValidateBasic() error {
|
||||||
|
@ -125,22 +140,24 @@ func (p PercentageDecisionPolicy) ValidateBasic() error {
|
||||||
return sdkerrors.Wrap(errors.ErrInvalid, "percentage must be > 0 and <= 1")
|
return sdkerrors.Wrap(errors.ErrInvalid, "percentage must be > 0 and <= 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout := p.Timeout
|
if p.Windows == nil || p.Windows.VotingPeriod == 0 {
|
||||||
if timeout <= time.Nanosecond {
|
return sdkerrors.Wrap(errors.ErrInvalid, "voting period cannot be 0")
|
||||||
return sdkerrors.Wrap(errors.ErrInvalid, "timeout")
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PercentageDecisionPolicy) Validate(g GroupInfo, config Config) error {
|
||||||
|
if p.Windows.MinExecutionPeriod > p.Windows.VotingPeriod+config.MaxExecutionPeriod {
|
||||||
|
return sdkerrors.Wrap(errors.ErrInvalid, "min_execution_period should be smaller than voting_period + max_execution_period")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PercentageDecisionPolicy) Validate(g GroupInfo) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow allows a proposal to pass when the tally of yes votes equals or exceeds the percentage threshold before the timeout.
|
// Allow allows a proposal to pass when the tally of yes votes equals or exceeds the percentage threshold before the timeout.
|
||||||
func (p PercentageDecisionPolicy) Allow(tally TallyResult, totalPower string, votingDuration time.Duration) (DecisionPolicyResult, error) {
|
func (p PercentageDecisionPolicy) Allow(tally TallyResult, totalPower string, sinceSubmission time.Duration) (DecisionPolicyResult, error) {
|
||||||
timeout := p.Timeout
|
if sinceSubmission < p.Windows.MinExecutionPeriod {
|
||||||
if timeout <= votingDuration {
|
return DecisionPolicyResult{}, errors.ErrUnauthorized.Wrapf("must wait %s after submission before execution, currently at %s", p.Windows.MinExecutionPeriod, sinceSubmission)
|
||||||
return DecisionPolicyResult{Allow: false, Final: true}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
percentage, err := math.NewPositiveDecFromString(p.Percentage)
|
percentage, err := math.NewPositiveDecFromString(p.Percentage)
|
||||||
|
@ -535,6 +552,16 @@ func (t TallyResult) TotalCounts() (math.Dec, error) {
|
||||||
return totalCounts, nil
|
return totalCounts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultTallyResult returns a TallyResult with all counts set to 0.
|
||||||
|
func DefaultTallyResult() TallyResult {
|
||||||
|
return TallyResult{
|
||||||
|
YesCount: "0",
|
||||||
|
NoCount: "0",
|
||||||
|
NoWithVetoCount: "0",
|
||||||
|
AbstainCount: "0",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// VoteOptionFromString returns a VoteOption from a string. It returns an error
|
// VoteOptionFromString returns a VoteOption from a string. It returns an error
|
||||||
// if the string is invalid.
|
// if the string is invalid.
|
||||||
func VoteOptionFromString(str string) (VoteOption, error) {
|
func VoteOptionFromString(str string) (VoteOption, error) {
|
||||||
|
|
|
@ -307,9 +307,8 @@ func (m *Members) GetMembers() []Member {
|
||||||
type ThresholdDecisionPolicy struct {
|
type ThresholdDecisionPolicy struct {
|
||||||
// threshold is the minimum weighted sum of yes votes that must be met or exceeded for a proposal to succeed.
|
// threshold is the minimum weighted sum of yes votes that must be met or exceeded for a proposal to succeed.
|
||||||
Threshold string `protobuf:"bytes,1,opt,name=threshold,proto3" json:"threshold,omitempty"`
|
Threshold string `protobuf:"bytes,1,opt,name=threshold,proto3" json:"threshold,omitempty"`
|
||||||
// timeout is the duration from submission of a proposal to the end of voting period
|
// windows defines the different windows for voting and execution.
|
||||||
// Within this times votes and exec messages can be submitted.
|
Windows *DecisionPolicyWindows `protobuf:"bytes,2,opt,name=windows,proto3" json:"windows,omitempty"`
|
||||||
Timeout time.Duration `protobuf:"bytes,2,opt,name=timeout,proto3,stdduration" json:"timeout"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ThresholdDecisionPolicy) Reset() { *m = ThresholdDecisionPolicy{} }
|
func (m *ThresholdDecisionPolicy) Reset() { *m = ThresholdDecisionPolicy{} }
|
||||||
|
@ -352,20 +351,19 @@ func (m *ThresholdDecisionPolicy) GetThreshold() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ThresholdDecisionPolicy) GetTimeout() time.Duration {
|
func (m *ThresholdDecisionPolicy) GetWindows() *DecisionPolicyWindows {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Timeout
|
return m.Windows
|
||||||
}
|
}
|
||||||
return 0
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PercentageDecisionPolicy implements the DecisionPolicy interface
|
// PercentageDecisionPolicy implements the DecisionPolicy interface
|
||||||
type PercentageDecisionPolicy struct {
|
type PercentageDecisionPolicy struct {
|
||||||
// percentage is the minimum percentage the weighted sum of yes votes must meet for a proposal to succeed.
|
// percentage is the minimum percentage the weighted sum of yes votes must meet for a proposal to succeed.
|
||||||
Percentage string `protobuf:"bytes,1,opt,name=percentage,proto3" json:"percentage,omitempty"`
|
Percentage string `protobuf:"bytes,1,opt,name=percentage,proto3" json:"percentage,omitempty"`
|
||||||
// timeout is the duration from submission of a proposal to the end of voting period
|
// windows defines the different windows for voting and execution.
|
||||||
// Within these times votes and exec messages can be submitted.
|
Windows *DecisionPolicyWindows `protobuf:"bytes,2,opt,name=windows,proto3" json:"windows,omitempty"`
|
||||||
Timeout time.Duration `protobuf:"bytes,2,opt,name=timeout,proto3,stdduration" json:"timeout"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PercentageDecisionPolicy) Reset() { *m = PercentageDecisionPolicy{} }
|
func (m *PercentageDecisionPolicy) Reset() { *m = PercentageDecisionPolicy{} }
|
||||||
|
@ -408,9 +406,75 @@ func (m *PercentageDecisionPolicy) GetPercentage() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PercentageDecisionPolicy) GetTimeout() time.Duration {
|
func (m *PercentageDecisionPolicy) GetWindows() *DecisionPolicyWindows {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Timeout
|
return m.Windows
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecisionPolicyWindows defines the different windows for voting and execution.
|
||||||
|
type DecisionPolicyWindows struct {
|
||||||
|
// voting_period is the duration from submission of a proposal to the end of voting period
|
||||||
|
// Within this times votes can be submitted with MsgVote.
|
||||||
|
VotingPeriod time.Duration `protobuf:"bytes,1,opt,name=voting_period,json=votingPeriod,proto3,stdduration" json:"voting_period"`
|
||||||
|
// min_execution_period is the minimum duration after the proposal submission
|
||||||
|
// where members can start sending MsgExec. This means that the window for
|
||||||
|
// sending a MsgExec transaction is:
|
||||||
|
// `[ submission + min_execution_period ; submission + voting_period + max_execution_period]`
|
||||||
|
// where max_execution_period is a app-specific config, defined in the keeper.
|
||||||
|
// If not set, min_execution_period will default to 0.
|
||||||
|
//
|
||||||
|
// Please make sure to set a `min_execution_period` that is smaller than
|
||||||
|
// `voting_period + max_execution_period`, or else the above execution window
|
||||||
|
// is empty, meaning that all proposals created with this decision policy
|
||||||
|
// won't be able to be executed.
|
||||||
|
MinExecutionPeriod time.Duration `protobuf:"bytes,2,opt,name=min_execution_period,json=minExecutionPeriod,proto3,stdduration" json:"min_execution_period"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DecisionPolicyWindows) Reset() { *m = DecisionPolicyWindows{} }
|
||||||
|
func (m *DecisionPolicyWindows) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*DecisionPolicyWindows) ProtoMessage() {}
|
||||||
|
func (*DecisionPolicyWindows) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_e091dfce5c49c8b6, []int{4}
|
||||||
|
}
|
||||||
|
func (m *DecisionPolicyWindows) XXX_Unmarshal(b []byte) error {
|
||||||
|
return m.Unmarshal(b)
|
||||||
|
}
|
||||||
|
func (m *DecisionPolicyWindows) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
if deterministic {
|
||||||
|
return xxx_messageInfo_DecisionPolicyWindows.Marshal(b, m, deterministic)
|
||||||
|
} else {
|
||||||
|
b = b[:cap(b)]
|
||||||
|
n, err := m.MarshalToSizedBuffer(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return b[:n], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (m *DecisionPolicyWindows) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_DecisionPolicyWindows.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *DecisionPolicyWindows) XXX_Size() int {
|
||||||
|
return m.Size()
|
||||||
|
}
|
||||||
|
func (m *DecisionPolicyWindows) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_DecisionPolicyWindows.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_DecisionPolicyWindows proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *DecisionPolicyWindows) GetVotingPeriod() time.Duration {
|
||||||
|
if m != nil {
|
||||||
|
return m.VotingPeriod
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DecisionPolicyWindows) GetMinExecutionPeriod() time.Duration {
|
||||||
|
if m != nil {
|
||||||
|
return m.MinExecutionPeriod
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -438,7 +502,7 @@ func (m *GroupInfo) Reset() { *m = GroupInfo{} }
|
||||||
func (m *GroupInfo) String() string { return proto.CompactTextString(m) }
|
func (m *GroupInfo) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GroupInfo) ProtoMessage() {}
|
func (*GroupInfo) ProtoMessage() {}
|
||||||
func (*GroupInfo) Descriptor() ([]byte, []int) {
|
func (*GroupInfo) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_e091dfce5c49c8b6, []int{4}
|
return fileDescriptor_e091dfce5c49c8b6, []int{5}
|
||||||
}
|
}
|
||||||
func (m *GroupInfo) XXX_Unmarshal(b []byte) error {
|
func (m *GroupInfo) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
|
@ -521,7 +585,7 @@ func (m *GroupMember) Reset() { *m = GroupMember{} }
|
||||||
func (m *GroupMember) String() string { return proto.CompactTextString(m) }
|
func (m *GroupMember) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GroupMember) ProtoMessage() {}
|
func (*GroupMember) ProtoMessage() {}
|
||||||
func (*GroupMember) Descriptor() ([]byte, []int) {
|
func (*GroupMember) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_e091dfce5c49c8b6, []int{5}
|
return fileDescriptor_e091dfce5c49c8b6, []int{6}
|
||||||
}
|
}
|
||||||
func (m *GroupMember) XXX_Unmarshal(b []byte) error {
|
func (m *GroupMember) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
|
@ -587,7 +651,7 @@ func (m *GroupPolicyInfo) Reset() { *m = GroupPolicyInfo{} }
|
||||||
func (m *GroupPolicyInfo) String() string { return proto.CompactTextString(m) }
|
func (m *GroupPolicyInfo) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GroupPolicyInfo) ProtoMessage() {}
|
func (*GroupPolicyInfo) ProtoMessage() {}
|
||||||
func (*GroupPolicyInfo) Descriptor() ([]byte, []int) {
|
func (*GroupPolicyInfo) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_e091dfce5c49c8b6, []int{6}
|
return fileDescriptor_e091dfce5c49c8b6, []int{7}
|
||||||
}
|
}
|
||||||
func (m *GroupPolicyInfo) XXX_Unmarshal(b []byte) error {
|
func (m *GroupPolicyInfo) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
|
@ -647,11 +711,12 @@ type Proposal struct {
|
||||||
// via gRPC, this field is not populated until the proposal's voting period
|
// via gRPC, this field is not populated until the proposal's voting period
|
||||||
// has ended.
|
// has ended.
|
||||||
FinalTallyResult TallyResult `protobuf:"bytes,10,opt,name=final_tally_result,json=finalTallyResult,proto3" json:"final_tally_result"`
|
FinalTallyResult TallyResult `protobuf:"bytes,10,opt,name=final_tally_result,json=finalTallyResult,proto3" json:"final_tally_result"`
|
||||||
// timeout is the timestamp before which both voting and execution must be
|
// voting_period_end is the timestamp before which voting must be done.
|
||||||
// done. If this timestamp is passed, then the proposal cannot be executed
|
// Unless a successfull MsgExec is called before (to execute a proposal whose
|
||||||
// anymore and should be considered pending delete. This timestamp is checked
|
// tally is successful before the voting period ends), tallying will be done
|
||||||
// against the block header's timestamp.
|
// at this point, and the `final_tally_result`, as well
|
||||||
Timeout time.Time `protobuf:"bytes,11,opt,name=timeout,proto3,stdtime" json:"timeout"`
|
// as `status` and `result` fields will be accordingly updated.
|
||||||
|
VotingPeriodEnd time.Time `protobuf:"bytes,11,opt,name=voting_period_end,json=votingPeriodEnd,proto3,stdtime" json:"voting_period_end"`
|
||||||
// executor_result is the final result based on the votes and election rule. Initial value is NotRun.
|
// executor_result is the final result based on the votes and election rule. Initial value is NotRun.
|
||||||
ExecutorResult ProposalExecutorResult `protobuf:"varint,12,opt,name=executor_result,json=executorResult,proto3,enum=cosmos.group.v1beta1.ProposalExecutorResult" json:"executor_result,omitempty"`
|
ExecutorResult ProposalExecutorResult `protobuf:"varint,12,opt,name=executor_result,json=executorResult,proto3,enum=cosmos.group.v1beta1.ProposalExecutorResult" json:"executor_result,omitempty"`
|
||||||
// messages is a list of Msgs that will be executed if the proposal passes.
|
// messages is a list of Msgs that will be executed if the proposal passes.
|
||||||
|
@ -662,7 +727,7 @@ func (m *Proposal) Reset() { *m = Proposal{} }
|
||||||
func (m *Proposal) String() string { return proto.CompactTextString(m) }
|
func (m *Proposal) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Proposal) ProtoMessage() {}
|
func (*Proposal) ProtoMessage() {}
|
||||||
func (*Proposal) Descriptor() ([]byte, []int) {
|
func (*Proposal) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_e091dfce5c49c8b6, []int{7}
|
return fileDescriptor_e091dfce5c49c8b6, []int{8}
|
||||||
}
|
}
|
||||||
func (m *Proposal) XXX_Unmarshal(b []byte) error {
|
func (m *Proposal) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
|
@ -707,7 +772,7 @@ func (m *TallyResult) Reset() { *m = TallyResult{} }
|
||||||
func (m *TallyResult) String() string { return proto.CompactTextString(m) }
|
func (m *TallyResult) String() string { return proto.CompactTextString(m) }
|
||||||
func (*TallyResult) ProtoMessage() {}
|
func (*TallyResult) ProtoMessage() {}
|
||||||
func (*TallyResult) Descriptor() ([]byte, []int) {
|
func (*TallyResult) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_e091dfce5c49c8b6, []int{8}
|
return fileDescriptor_e091dfce5c49c8b6, []int{9}
|
||||||
}
|
}
|
||||||
func (m *TallyResult) XXX_Unmarshal(b []byte) error {
|
func (m *TallyResult) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
|
@ -754,7 +819,7 @@ func (m *Vote) Reset() { *m = Vote{} }
|
||||||
func (m *Vote) String() string { return proto.CompactTextString(m) }
|
func (m *Vote) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Vote) ProtoMessage() {}
|
func (*Vote) ProtoMessage() {}
|
||||||
func (*Vote) Descriptor() ([]byte, []int) {
|
func (*Vote) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_e091dfce5c49c8b6, []int{9}
|
return fileDescriptor_e091dfce5c49c8b6, []int{10}
|
||||||
}
|
}
|
||||||
func (m *Vote) XXX_Unmarshal(b []byte) error {
|
func (m *Vote) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
|
@ -827,6 +892,7 @@ func init() {
|
||||||
proto.RegisterType((*Members)(nil), "cosmos.group.v1beta1.Members")
|
proto.RegisterType((*Members)(nil), "cosmos.group.v1beta1.Members")
|
||||||
proto.RegisterType((*ThresholdDecisionPolicy)(nil), "cosmos.group.v1beta1.ThresholdDecisionPolicy")
|
proto.RegisterType((*ThresholdDecisionPolicy)(nil), "cosmos.group.v1beta1.ThresholdDecisionPolicy")
|
||||||
proto.RegisterType((*PercentageDecisionPolicy)(nil), "cosmos.group.v1beta1.PercentageDecisionPolicy")
|
proto.RegisterType((*PercentageDecisionPolicy)(nil), "cosmos.group.v1beta1.PercentageDecisionPolicy")
|
||||||
|
proto.RegisterType((*DecisionPolicyWindows)(nil), "cosmos.group.v1beta1.DecisionPolicyWindows")
|
||||||
proto.RegisterType((*GroupInfo)(nil), "cosmos.group.v1beta1.GroupInfo")
|
proto.RegisterType((*GroupInfo)(nil), "cosmos.group.v1beta1.GroupInfo")
|
||||||
proto.RegisterType((*GroupMember)(nil), "cosmos.group.v1beta1.GroupMember")
|
proto.RegisterType((*GroupMember)(nil), "cosmos.group.v1beta1.GroupMember")
|
||||||
proto.RegisterType((*GroupPolicyInfo)(nil), "cosmos.group.v1beta1.GroupPolicyInfo")
|
proto.RegisterType((*GroupPolicyInfo)(nil), "cosmos.group.v1beta1.GroupPolicyInfo")
|
||||||
|
@ -838,87 +904,91 @@ func init() {
|
||||||
func init() { proto.RegisterFile("cosmos/group/v1beta1/types.proto", fileDescriptor_e091dfce5c49c8b6) }
|
func init() { proto.RegisterFile("cosmos/group/v1beta1/types.proto", fileDescriptor_e091dfce5c49c8b6) }
|
||||||
|
|
||||||
var fileDescriptor_e091dfce5c49c8b6 = []byte{
|
var fileDescriptor_e091dfce5c49c8b6 = []byte{
|
||||||
// 1274 bytes of a gzipped FileDescriptorProto
|
// 1344 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x4f, 0x6f, 0x1b, 0x45,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x4d, 0x6f, 0x1b, 0x45,
|
||||||
0x14, 0xf7, 0x3a, 0x8e, 0xff, 0x3c, 0xa7, 0x8e, 0x35, 0x8d, 0xda, 0x4d, 0x1a, 0x6c, 0xd7, 0xe4,
|
0x18, 0xf6, 0x3a, 0x8e, 0x3f, 0x5e, 0xa7, 0x8e, 0x99, 0x86, 0x76, 0x93, 0x06, 0xdb, 0x35, 0x39,
|
||||||
0x10, 0x15, 0x6a, 0xb7, 0x01, 0x21, 0x54, 0x95, 0xa2, 0xb5, 0xb3, 0x2d, 0x46, 0xa9, 0x6d, 0x76,
|
0x44, 0x2d, 0xb5, 0x5b, 0x83, 0x10, 0xaa, 0x2a, 0x90, 0xed, 0x6c, 0x5b, 0xa3, 0xd4, 0x36, 0xbb,
|
||||||
0xd7, 0x09, 0xf4, 0xc0, 0x6a, 0xed, 0x9d, 0x3a, 0x2b, 0xec, 0x1d, 0x6b, 0x77, 0x9c, 0xd6, 0xdf,
|
0xeb, 0x04, 0x7a, 0x60, 0xb5, 0xf6, 0x4e, 0x9d, 0x15, 0xf6, 0x8e, 0xb5, 0x3b, 0x4e, 0xea, 0x7f,
|
||||||
0xa0, 0x42, 0x42, 0xf4, 0xc0, 0x81, 0x0b, 0x52, 0x25, 0xee, 0x48, 0x48, 0x3d, 0xf1, 0x09, 0x2a,
|
0xd0, 0x1b, 0x15, 0x02, 0x89, 0x0b, 0x52, 0x25, 0xee, 0x48, 0x48, 0x3d, 0x20, 0x7e, 0x41, 0xc5,
|
||||||
0x4e, 0x15, 0x27, 0x4e, 0x80, 0xd2, 0x4b, 0xb9, 0xf3, 0x01, 0xd0, 0xce, 0xcc, 0xfa, 0x5f, 0x5d,
|
0xa9, 0xe2, 0xc4, 0x09, 0x50, 0x7b, 0x29, 0xf7, 0xfe, 0x00, 0xb4, 0x33, 0xb3, 0x8e, 0xed, 0xba,
|
||||||
0xab, 0xad, 0xe0, 0x64, 0xcf, 0xbc, 0xdf, 0x9b, 0xf7, 0x7b, 0xef, 0xfd, 0xe6, 0x8d, 0x16, 0x0a,
|
0x56, 0x52, 0xc1, 0xa9, 0x99, 0x79, 0x9f, 0xe7, 0x9d, 0xe7, 0xfd, 0xdc, 0x1a, 0x72, 0x1d, 0xe2,
|
||||||
0x1d, 0xe2, 0xf7, 0x89, 0x5f, 0xee, 0x7a, 0x64, 0x38, 0x28, 0x9f, 0x5c, 0x6d, 0x63, 0x6a, 0x5d,
|
0xf5, 0x89, 0x57, 0xec, 0xba, 0x64, 0x38, 0x28, 0x1e, 0x5e, 0x6b, 0x63, 0x6a, 0x5e, 0x2b, 0xd2,
|
||||||
0x2d, 0xd3, 0xd1, 0x00, 0xfb, 0xa5, 0x81, 0x47, 0x28, 0x41, 0x1b, 0x1c, 0x51, 0x62, 0x88, 0x92,
|
0xd1, 0x00, 0x7b, 0x85, 0x81, 0x4b, 0x28, 0x41, 0x6b, 0x1c, 0x51, 0x60, 0x88, 0x82, 0x40, 0x6c,
|
||||||
0x40, 0x6c, 0x6d, 0x74, 0x49, 0x97, 0x30, 0x40, 0x39, 0xf8, 0xc7, 0xb1, 0x5b, 0xb9, 0x2e, 0x21,
|
0xac, 0x75, 0x49, 0x97, 0x30, 0x40, 0xd1, 0xff, 0x8b, 0x63, 0x37, 0x32, 0x5d, 0x42, 0xba, 0x3d,
|
||||||
0xdd, 0x1e, 0x2e, 0xb3, 0x55, 0x7b, 0x78, 0xb7, 0x6c, 0x0f, 0x3d, 0x8b, 0x3a, 0xc4, 0x15, 0xf6,
|
0x5c, 0x64, 0xa7, 0xf6, 0xf0, 0x5e, 0xd1, 0x1a, 0xba, 0x26, 0xb5, 0x89, 0x23, 0xec, 0xd9, 0x59,
|
||||||
0xfc, 0xbc, 0x9d, 0x3a, 0x7d, 0xec, 0x53, 0xab, 0x3f, 0x10, 0x80, 0x4d, 0x1e, 0xcc, 0xe4, 0x27,
|
0x3b, 0xb5, 0xfb, 0xd8, 0xa3, 0x66, 0x7f, 0x20, 0x00, 0xeb, 0xfc, 0x31, 0x83, 0x7b, 0x16, 0x2f,
|
||||||
0x8b, 0xc8, 0xc2, 0x34, 0xef, 0x6b, 0xb9, 0x23, 0x6e, 0x2a, 0xfe, 0x2c, 0x41, 0xfc, 0x36, 0xee,
|
0x0b, 0xd3, 0x2c, 0xd7, 0x74, 0x46, 0xdc, 0x94, 0xff, 0x59, 0x82, 0xe8, 0x1d, 0xdc, 0x6f, 0x63,
|
||||||
0xb7, 0xb1, 0x87, 0xf6, 0x20, 0x61, 0xd9, 0xb6, 0x87, 0x7d, 0x5f, 0x96, 0x0a, 0xd2, 0x6e, 0xaa,
|
0x17, 0x95, 0x20, 0x66, 0x5a, 0x96, 0x8b, 0x3d, 0x4f, 0x96, 0x72, 0xd2, 0x76, 0xa2, 0x22, 0xff,
|
||||||
0x22, 0xff, 0xf6, 0xf8, 0x72, 0x98, 0x82, 0xc2, 0x2d, 0x3a, 0xf5, 0x1c, 0xb7, 0xab, 0x85, 0x40,
|
0xfe, 0xf8, 0x4a, 0x10, 0x42, 0x99, 0x5b, 0x34, 0xea, 0xda, 0x4e, 0x57, 0x0d, 0x80, 0xe8, 0x1c,
|
||||||
0x74, 0x0e, 0xe2, 0xf7, 0xb0, 0xd3, 0x3d, 0xa6, 0x72, 0x34, 0x70, 0xd1, 0xc4, 0x0a, 0x6d, 0x41,
|
0x44, 0x8f, 0xb0, 0xdd, 0x3d, 0xa0, 0x72, 0xd8, 0xa7, 0xa8, 0xe2, 0x84, 0x36, 0x20, 0xde, 0xc7,
|
||||||
0xb2, 0x8f, 0xa9, 0x65, 0x5b, 0xd4, 0x92, 0x57, 0x98, 0x65, 0xbc, 0x46, 0x1f, 0x43, 0xd2, 0xb2,
|
0xd4, 0xb4, 0x4c, 0x6a, 0xca, 0x4b, 0xcc, 0x32, 0x3e, 0xa3, 0x4f, 0x20, 0x6e, 0x5a, 0x16, 0xb6,
|
||||||
0x6d, 0x6c, 0x9b, 0x16, 0x95, 0x63, 0x05, 0x69, 0x37, 0xbd, 0xb7, 0x55, 0xe2, 0x04, 0x4b, 0x21,
|
0x0c, 0x93, 0xca, 0x91, 0x9c, 0xb4, 0x9d, 0x2c, 0x6d, 0x14, 0xb8, 0xc0, 0x42, 0x20, 0xb0, 0xa0,
|
||||||
0xc1, 0x92, 0x11, 0x26, 0x57, 0x49, 0x3e, 0xf9, 0x23, 0x1f, 0x79, 0xf8, 0x67, 0x5e, 0x62, 0x41,
|
0x07, 0xc1, 0x55, 0xe2, 0x4f, 0xfe, 0xcc, 0x86, 0x1e, 0xfe, 0x95, 0x95, 0xd8, 0xa3, 0xd8, 0x2a,
|
||||||
0xb1, 0xad, 0xd0, 0xe2, 0x2d, 0x48, 0x70, 0xca, 0x3e, 0xba, 0x0e, 0x89, 0x3e, 0xff, 0x2b, 0x4b,
|
0xd3, 0xfc, 0x2d, 0x88, 0x71, 0xc9, 0x1e, 0xba, 0x01, 0xb1, 0x3e, 0xff, 0x53, 0x96, 0x72, 0x4b,
|
||||||
0x85, 0x95, 0xdd, 0xf4, 0xde, 0x76, 0x69, 0x51, 0xcd, 0x4b, 0x1c, 0x5f, 0x89, 0x05, 0x87, 0x69,
|
0xdb, 0xc9, 0xd2, 0x66, 0x61, 0x5e, 0xce, 0x0b, 0x1c, 0x5f, 0x89, 0xf8, 0xce, 0xd4, 0x80, 0x92,
|
||||||
0xa1, 0x4b, 0xf1, 0x6b, 0x09, 0xce, 0x1b, 0xc7, 0x1e, 0xf6, 0x8f, 0x49, 0xcf, 0xde, 0xc7, 0x1d,
|
0xff, 0x46, 0x82, 0xf3, 0xfa, 0x81, 0x8b, 0xbd, 0x03, 0xd2, 0xb3, 0x76, 0x70, 0xc7, 0xf6, 0x6c,
|
||||||
0xc7, 0x77, 0x88, 0xdb, 0x24, 0x3d, 0xa7, 0x33, 0x42, 0xdb, 0x90, 0xa2, 0xa1, 0x89, 0xd7, 0x43,
|
0xe2, 0x34, 0x49, 0xcf, 0xee, 0x8c, 0xd0, 0x26, 0x24, 0x68, 0x60, 0xe2, 0xf9, 0x50, 0x8f, 0x2f,
|
||||||
0x9b, 0x6c, 0xa0, 0x8f, 0x20, 0x11, 0xd4, 0x9f, 0x0c, 0x79, 0xe2, 0xe9, 0xbd, 0xcd, 0x17, 0x52,
|
0x90, 0x02, 0xb1, 0x23, 0xdb, 0xb1, 0xc8, 0x91, 0xc7, 0x02, 0x4f, 0x96, 0x2e, 0xcf, 0x7f, 0x77,
|
||||||
0xd8, 0x17, 0xfd, 0xe3, 0x19, 0x7c, 0xcf, 0x32, 0x10, 0x3e, 0xd7, 0xd0, 0xaf, 0x8f, 0x2f, 0x67,
|
0xda, 0xe9, 0x3e, 0xa7, 0xa8, 0x01, 0xf7, 0x3a, 0xfa, 0xed, 0xf1, 0x95, 0xd4, 0x34, 0x26, 0xff,
|
||||||
0x66, 0x03, 0x16, 0xbf, 0x91, 0x40, 0x6e, 0x62, 0xaf, 0x83, 0x5d, 0x6a, 0x75, 0xf1, 0x1c, 0x9b,
|
0x9d, 0x04, 0x72, 0x13, 0xbb, 0x1d, 0xec, 0x50, 0xb3, 0x8b, 0x67, 0x54, 0x65, 0x00, 0x06, 0x63,
|
||||||
0x1c, 0xc0, 0x60, 0x6c, 0x13, 0x74, 0xa6, 0x76, 0xfe, 0x0f, 0x3e, 0x7f, 0x4b, 0x90, 0xba, 0x15,
|
0x9b, 0x90, 0x35, 0x71, 0xf3, 0x7f, 0xea, 0xfa, 0x45, 0x82, 0xb7, 0xe7, 0xd2, 0xd0, 0x6d, 0x38,
|
||||||
0x14, 0xb1, 0xe6, 0xde, 0x25, 0x28, 0x03, 0x51, 0x87, 0xd7, 0x21, 0xa6, 0x45, 0x1d, 0x1b, 0x95,
|
0x73, 0x48, 0xa8, 0xed, 0x74, 0x8d, 0x01, 0x76, 0x6d, 0xc2, 0xd3, 0x95, 0x2c, 0xad, 0xbf, 0x52,
|
||||||
0x60, 0xd5, 0xb2, 0xfb, 0x8e, 0xcb, 0xfb, 0xbe, 0x44, 0x2a, 0x1c, 0xb6, 0x54, 0x10, 0x32, 0x24,
|
0xd5, 0x1d, 0xd1, 0xd2, 0xbc, 0xa8, 0xdf, 0xfb, 0x45, 0x5d, 0xe1, 0xcc, 0x26, 0x23, 0xa2, 0x16,
|
||||||
0x4e, 0xb0, 0x17, 0x84, 0x66, 0x7a, 0x88, 0x69, 0xe1, 0x12, 0x5d, 0x84, 0x35, 0x4a, 0xa8, 0xd5,
|
0xac, 0xf5, 0x6d, 0xc7, 0xc0, 0xf7, 0x71, 0x67, 0xe8, 0x03, 0x03, 0x87, 0xe1, 0x93, 0x3b, 0x44,
|
||||||
0x33, 0x85, 0xc8, 0x56, 0x99, 0x67, 0x9a, 0xed, 0x1d, 0x71, 0xa5, 0x55, 0x01, 0x3a, 0x1e, 0xb6,
|
0x7d, 0xdb, 0x51, 0x02, 0x3e, 0x77, 0x9b, 0xff, 0x47, 0x82, 0xc4, 0x2d, 0x3f, 0xfe, 0x9a, 0x73,
|
||||||
0x28, 0xd7, 0x53, 0xfc, 0x35, 0xf4, 0x94, 0x12, 0x7e, 0x0a, 0x2d, 0x7e, 0x09, 0x69, 0x96, 0xaa,
|
0x8f, 0xa0, 0x14, 0x84, 0x6d, 0xae, 0x31, 0xa2, 0x86, 0x6d, 0x0b, 0x15, 0x60, 0xd9, 0xb4, 0xfa,
|
||||||
0xb8, 0x09, 0x9b, 0x90, 0x64, 0xf2, 0x31, 0xc7, 0x29, 0x27, 0xd8, 0xba, 0x66, 0xa3, 0xf7, 0x21,
|
0xb6, 0xc3, 0x5b, 0x78, 0x41, 0xd7, 0x73, 0xd8, 0xc2, 0xde, 0x96, 0x21, 0x76, 0x88, 0x5d, 0x3f,
|
||||||
0xce, 0xd5, 0x23, 0xea, 0xbc, 0x54, 0x6f, 0x9a, 0xc0, 0x16, 0x9f, 0x47, 0x61, 0x9d, 0x05, 0xe0,
|
0x45, 0xac, 0xb5, 0x23, 0x6a, 0x70, 0x44, 0x17, 0x61, 0x85, 0x12, 0x6a, 0xf6, 0x0c, 0x31, 0x2f,
|
||||||
0xb5, 0x65, 0x15, 0x7d, 0x93, 0xeb, 0x36, 0x4d, 0x2c, 0x3a, 0x4b, 0x6c, 0xdc, 0x90, 0x95, 0xd7,
|
0xcb, 0x8c, 0x99, 0x64, 0x77, 0xfb, 0x7c, 0x68, 0xaa, 0x00, 0x1d, 0x17, 0x9b, 0x94, 0x8f, 0x46,
|
||||||
0x6f, 0x48, 0xec, 0xe5, 0x0d, 0x59, 0x9d, 0x6d, 0xc8, 0x67, 0xb0, 0x6e, 0x0b, 0x99, 0x98, 0x03,
|
0xf4, 0x14, 0xa3, 0x91, 0x10, 0xbc, 0x32, 0xcd, 0x7f, 0x09, 0x49, 0x16, 0xaa, 0x18, 0xea, 0x75,
|
||||||
0x96, 0x8b, 0x28, 0xf9, 0xc6, 0x0b, 0x25, 0x57, 0xdc, 0x51, 0x65, 0x81, 0xae, 0xb4, 0x8c, 0x3d,
|
0x88, 0xb3, 0xca, 0x1b, 0xe3, 0x90, 0x63, 0xec, 0x5c, 0xb3, 0xd0, 0x07, 0x10, 0xe5, 0x83, 0x20,
|
||||||
0x2b, 0xed, 0xd9, 0x06, 0x26, 0xde, 0xa8, 0x81, 0xd7, 0x92, 0x0f, 0x1e, 0xe5, 0x23, 0xcf, 0x1f,
|
0xd2, 0xbb, 0x70, 0x74, 0x54, 0x81, 0xcd, 0xbf, 0x08, 0xc3, 0x2a, 0x7b, 0x80, 0xf7, 0x00, 0xcb,
|
||||||
0xe5, 0xa5, 0xe2, 0xe9, 0x2a, 0x24, 0x9b, 0x1e, 0x19, 0x10, 0xdf, 0xea, 0xbd, 0xa0, 0xda, 0xa9,
|
0xe8, 0x9b, 0x6c, 0x8e, 0x49, 0x61, 0xe1, 0x69, 0x61, 0xe3, 0x82, 0x2c, 0x9d, 0xbe, 0x20, 0x91,
|
||||||
0x9a, 0x47, 0x5f, 0xb5, 0xe6, 0xcb, 0x94, 0xfb, 0x01, 0xa4, 0x06, 0x2c, 0x56, 0x30, 0x80, 0x62,
|
0xd7, 0x17, 0x64, 0x79, 0xba, 0x20, 0x9f, 0xc1, 0xaa, 0x25, 0xda, 0xd9, 0x18, 0xb0, 0x58, 0x44,
|
||||||
0x85, 0x95, 0xa5, 0x27, 0x4e, 0xa0, 0x48, 0x85, 0xb4, 0x3f, 0x6c, 0xf7, 0x1d, 0x6a, 0x06, 0x37,
|
0xca, 0xd7, 0x5e, 0x49, 0x79, 0xd9, 0x19, 0x55, 0xe6, 0x8c, 0x84, 0x9a, 0xb2, 0xa6, 0xa7, 0x73,
|
||||||
0x90, 0x15, 0xf9, 0x55, 0x93, 0x06, 0xee, 0x18, 0x98, 0xd0, 0xdb, 0x70, 0x86, 0xcb, 0x21, 0xec,
|
0xba, 0x80, 0xb1, 0x37, 0x2a, 0xe0, 0xf5, 0xf8, 0x83, 0x47, 0xd9, 0xd0, 0x8b, 0x47, 0x59, 0x29,
|
||||||
0x56, 0x9c, 0x65, 0xba, 0xc6, 0x36, 0x0f, 0x45, 0xcb, 0xae, 0xc0, 0x06, 0x07, 0xf1, 0x7e, 0x8d,
|
0xff, 0x72, 0x19, 0xe2, 0x4d, 0x97, 0x0c, 0x88, 0x67, 0xf6, 0x5e, 0xe9, 0xda, 0x89, 0x9c, 0x87,
|
||||||
0xb1, 0x09, 0x86, 0x45, 0xdd, 0x89, 0x2c, 0x43, 0x8f, 0xeb, 0x10, 0xf7, 0xa9, 0x45, 0x87, 0xbe,
|
0x4f, 0x9a, 0xf3, 0x45, 0x9d, 0xfb, 0x21, 0x24, 0x06, 0xec, 0x2d, 0x7f, 0x97, 0x46, 0x72, 0x4b,
|
||||||
0x9c, 0x2c, 0x48, 0xbb, 0x99, 0xbd, 0x9d, 0xc5, 0x1a, 0x0f, 0xab, 0xac, 0x33, 0xac, 0x26, 0x7c,
|
0x0b, 0x3d, 0x1e, 0x43, 0x91, 0x02, 0x49, 0x6f, 0xd8, 0xee, 0xdb, 0xd4, 0xf0, 0x3f, 0x48, 0x2c,
|
||||||
0x02, 0x6f, 0x0f, 0xfb, 0xc3, 0x1e, 0x95, 0x53, 0xaf, 0xe2, 0xad, 0x31, 0xac, 0x26, 0x7c, 0x50,
|
0xc9, 0x27, 0x0d, 0x1a, 0x38, 0xd1, 0x37, 0xa1, 0x77, 0xe1, 0x0c, 0x6f, 0x87, 0xa0, 0x5a, 0x51,
|
||||||
0x0b, 0xd0, 0x5d, 0xc7, 0xb5, 0x7a, 0x26, 0xb5, 0x7a, 0xbd, 0x91, 0x29, 0x4e, 0x02, 0x56, 0xa0,
|
0x16, 0xe9, 0x0a, 0xbb, 0xdc, 0x13, 0x25, 0xbb, 0x0a, 0x6b, 0x1c, 0xc4, 0xeb, 0x35, 0xc6, 0xc6,
|
||||||
0x8b, 0x8b, 0x4f, 0x32, 0x02, 0x24, 0x3f, 0x46, 0x0c, 0xf8, 0x2c, 0x3b, 0x62, 0x6a, 0x1f, 0xdd,
|
0x18, 0x16, 0x75, 0x8f, 0xdb, 0x32, 0x60, 0xdc, 0x80, 0xa8, 0x47, 0x4d, 0x3a, 0xf4, 0xe4, 0x78,
|
||||||
0x98, 0xcc, 0xc7, 0xf4, 0xeb, 0x3c, 0x39, 0xc2, 0x09, 0xb5, 0x60, 0x1d, 0xdf, 0xc7, 0x9d, 0x21,
|
0x4e, 0xda, 0x4e, 0x95, 0xb6, 0xe6, 0xf7, 0x78, 0x90, 0x65, 0x8d, 0x61, 0x55, 0xc1, 0xf1, 0xd9,
|
||||||
0x25, 0x5e, 0xc8, 0x69, 0x8d, 0x65, 0xf7, 0xee, 0xf2, 0xec, 0x54, 0xe1, 0x24, 0xb2, 0xcc, 0xe0,
|
0x2e, 0xf6, 0x86, 0x3d, 0x2a, 0x27, 0x4e, 0xc2, 0x56, 0x19, 0x56, 0x15, 0x1c, 0xd4, 0x02, 0x74,
|
||||||
0x99, 0x35, 0xba, 0x12, 0x68, 0xcb, 0xf7, 0xad, 0x2e, 0xf6, 0xe5, 0x33, 0xec, 0xfd, 0x5a, 0x78,
|
0xcf, 0x76, 0xcc, 0x9e, 0x41, 0xcd, 0x5e, 0x6f, 0x64, 0x08, 0x4f, 0xc0, 0x12, 0x74, 0x71, 0xbe,
|
||||||
0x8f, 0xb4, 0x31, 0xea, 0x5a, 0x2c, 0x10, 0x7a, 0xf1, 0x07, 0x09, 0xd2, 0xd3, 0xe9, 0x5d, 0x80,
|
0x27, 0xdd, 0x47, 0x72, 0x37, 0xe2, 0x5b, 0x95, 0x66, 0x2e, 0x26, 0xee, 0x51, 0x13, 0xde, 0x9a,
|
||||||
0xd4, 0x08, 0xfb, 0x66, 0x87, 0x0c, 0x5d, 0x2a, 0x5e, 0x87, 0xe4, 0x08, 0xfb, 0xd5, 0x60, 0x1d,
|
0xda, 0xb6, 0x06, 0x76, 0x2c, 0x39, 0x79, 0x8a, 0xb4, 0xaf, 0x4e, 0xae, 0x5c, 0xc5, 0xf1, 0xb7,
|
||||||
0xa8, 0xc4, 0x6a, 0xfb, 0xd4, 0x72, 0x5c, 0x01, 0xe0, 0x4f, 0xf5, 0x9a, 0xd8, 0xe4, 0xa0, 0x4d,
|
0xee, 0x2a, 0xdf, 0xb8, 0xc4, 0x0d, 0x54, 0xae, 0xb0, 0x78, 0xdf, 0x5b, 0x1c, 0xaf, 0x22, 0x48,
|
||||||
0x48, 0xba, 0x44, 0xd8, 0xb9, 0xca, 0x13, 0x2e, 0xe1, 0xa6, 0x77, 0x00, 0xb9, 0xc4, 0xbc, 0xe7,
|
0x22, 0xee, 0x14, 0x9e, 0x3a, 0xa3, 0xab, 0x7e, 0xb7, 0x79, 0x9e, 0xd9, 0xc5, 0x9e, 0x7c, 0x86,
|
||||||
0xd0, 0x63, 0xf3, 0x04, 0xd3, 0x10, 0xc4, 0x67, 0xc6, 0xba, 0x4b, 0x8e, 0x1c, 0x7a, 0x7c, 0x88,
|
0x7d, 0x9c, 0xe7, 0x4e, 0x96, 0x3a, 0x46, 0x5d, 0x8f, 0xf8, 0xad, 0x9f, 0xff, 0x41, 0x82, 0xe4,
|
||||||
0x29, 0x07, 0x0b, 0x7e, 0xff, 0x48, 0x10, 0x3b, 0x24, 0x14, 0xa3, 0x3c, 0xa4, 0x07, 0xa2, 0x14,
|
0x64, 0xc0, 0x17, 0x20, 0x31, 0xc2, 0x9e, 0xd1, 0x21, 0x43, 0x87, 0x8a, 0x4f, 0x5e, 0x7c, 0x84,
|
||||||
0x93, 0x61, 0x0a, 0xe1, 0x16, 0x1f, 0x5b, 0x27, 0x84, 0x8a, 0x71, 0xba, 0x74, 0x6c, 0x31, 0x18,
|
0xbd, 0xaa, 0x7f, 0xf6, 0xfb, 0xc6, 0x6c, 0x7b, 0xd4, 0xb4, 0x1d, 0x01, 0xe0, 0xff, 0x0f, 0x59,
|
||||||
0xfa, 0x10, 0xe2, 0x64, 0x10, 0x3c, 0x63, 0x8c, 0x65, 0x66, 0xaf, 0xb0, 0xb8, 0xfe, 0x41, 0xf0,
|
0x11, 0x97, 0x1c, 0xb4, 0x0e, 0x71, 0x87, 0x08, 0x3b, 0xef, 0xfb, 0x98, 0x43, 0xb8, 0xe9, 0x32,
|
||||||
0x06, 0xc3, 0x69, 0x02, 0xbf, 0x74, 0xe0, 0xfd, 0x37, 0xf7, 0xf1, 0xd2, 0xb7, 0x12, 0xc0, 0x24,
|
0x20, 0x87, 0x18, 0x47, 0x36, 0x3d, 0x30, 0x0e, 0x31, 0x0d, 0x40, 0x7c, 0x8b, 0xac, 0x3a, 0x64,
|
||||||
0x32, 0xba, 0x00, 0xe7, 0x0f, 0x1b, 0x86, 0x6a, 0x36, 0x9a, 0x46, 0xad, 0x51, 0x37, 0x5b, 0x75,
|
0xdf, 0xa6, 0x07, 0x7b, 0x98, 0x72, 0xb0, 0xd0, 0xf7, 0x52, 0x82, 0xc8, 0x1e, 0xa1, 0x18, 0x65,
|
||||||
0xbd, 0xa9, 0x56, 0x6b, 0x37, 0x6b, 0xea, 0x7e, 0x36, 0x82, 0xce, 0xc2, 0xfa, 0xb4, 0xf1, 0x0b,
|
0x21, 0x39, 0x10, 0xa9, 0x38, 0x5e, 0xaf, 0x10, 0x5c, 0xf1, 0x45, 0x76, 0x48, 0xa8, 0x58, 0xb0,
|
||||||
0x55, 0xcf, 0x4a, 0xe8, 0x3c, 0x9c, 0x9d, 0xde, 0x54, 0x2a, 0xba, 0xa1, 0xd4, 0xea, 0xd9, 0x28,
|
0x0b, 0x17, 0x19, 0x83, 0xa1, 0x8f, 0x20, 0x4a, 0x06, 0xfe, 0x77, 0x8b, 0xa9, 0x4c, 0x95, 0x72,
|
||||||
0x42, 0x90, 0x99, 0x36, 0xd4, 0x1b, 0xd9, 0x15, 0xb4, 0x0d, 0xf2, 0xec, 0x9e, 0x79, 0x54, 0x33,
|
0xf3, 0xf3, 0xef, 0x3f, 0xde, 0x60, 0x38, 0x55, 0xe0, 0x17, 0xae, 0xc0, 0xff, 0x66, 0x42, 0x2f,
|
||||||
0x3e, 0x31, 0x0f, 0x55, 0xa3, 0x91, 0x8d, 0x6d, 0xc5, 0x1e, 0xfc, 0x98, 0x8b, 0x5c, 0xfa, 0x49,
|
0x7d, 0x2d, 0x01, 0x1c, 0xbf, 0x8c, 0x2e, 0xc0, 0xf9, 0xbd, 0x86, 0xae, 0x18, 0x8d, 0xa6, 0x5e,
|
||||||
0x82, 0xcc, 0xec, 0x3d, 0x45, 0x79, 0xb8, 0xd0, 0xd4, 0x1a, 0xcd, 0x86, 0xae, 0x1c, 0x98, 0xba,
|
0x6b, 0xd4, 0x8d, 0x56, 0x5d, 0x6b, 0x2a, 0xd5, 0xda, 0xcd, 0x9a, 0xb2, 0x93, 0x0e, 0xa1, 0xb3,
|
||||||
0xa1, 0x18, 0x2d, 0x7d, 0x8e, 0xd9, 0x5b, 0xb0, 0x39, 0x0f, 0xd0, 0x5b, 0x95, 0xdb, 0x35, 0xc3,
|
0xb0, 0x3a, 0x69, 0xfc, 0x42, 0xd1, 0xd2, 0x12, 0x3a, 0x0f, 0x67, 0x27, 0x2f, 0xcb, 0x15, 0x4d,
|
||||||
0x50, 0xf7, 0xb3, 0x12, 0xda, 0x82, 0x73, 0xf3, 0xe6, 0xea, 0x41, 0x43, 0x57, 0xf7, 0xb3, 0xd1,
|
0x2f, 0xd7, 0xea, 0xe9, 0x30, 0x42, 0x90, 0x9a, 0x34, 0xd4, 0x1b, 0xe9, 0x25, 0xb4, 0x09, 0xf2,
|
||||||
0x20, 0xe3, 0x79, 0x9b, 0x52, 0x69, 0x68, 0x81, 0xe3, 0xca, 0xa2, 0x73, 0x03, 0xc2, 0xfb, 0x9a,
|
0xf4, 0x9d, 0xb1, 0x5f, 0xd3, 0x6f, 0x1b, 0x7b, 0x8a, 0xde, 0x48, 0x47, 0x36, 0x22, 0x0f, 0x7e,
|
||||||
0x72, 0x54, 0x1f, 0x13, 0xfe, 0x6e, 0x8a, 0xb0, 0x10, 0xf7, 0x34, 0x61, 0x4d, 0xd5, 0x5b, 0x07,
|
0xcc, 0x84, 0x2e, 0xfd, 0x24, 0x41, 0x6a, 0x7a, 0x72, 0x51, 0x16, 0x2e, 0x34, 0xd5, 0x46, 0xb3,
|
||||||
0xc6, 0x1c, 0xe1, 0x85, 0x80, 0x9b, 0xb5, 0xba, 0x72, 0x50, 0xbb, 0xc3, 0x28, 0x6f, 0x83, 0x3c,
|
0xa1, 0x95, 0x77, 0x0d, 0x4d, 0x2f, 0xeb, 0x2d, 0x6d, 0x46, 0xd9, 0x3b, 0xb0, 0x3e, 0x0b, 0xd0,
|
||||||
0x0f, 0x50, 0xaa, 0x55, 0xb5, 0x69, 0x30, 0xd2, 0x0b, 0xac, 0x9a, 0xfa, 0xa9, 0x5a, 0x65, 0xac,
|
0x5a, 0x95, 0x3b, 0x35, 0x5d, 0x57, 0x76, 0xd2, 0x12, 0xda, 0x80, 0x73, 0xb3, 0xe6, 0xea, 0x6e,
|
||||||
0x05, 0xad, 0x5f, 0x24, 0x38, 0xb7, 0xf8, 0x4e, 0xa3, 0x5d, 0xd8, 0x19, 0xbb, 0xab, 0x9f, 0xab,
|
0x43, 0x53, 0x76, 0xd2, 0x61, 0x3f, 0xe2, 0x59, 0x5b, 0xb9, 0xd2, 0x50, 0x7d, 0xe2, 0xd2, 0x3c,
|
||||||
0xd5, 0x96, 0xd1, 0xd0, 0x16, 0xf3, 0xdc, 0x81, 0xc2, 0x4b, 0x91, 0xf5, 0x86, 0x61, 0x6a, 0xad,
|
0xbf, 0xbe, 0xe0, 0x1d, 0xb5, 0xbc, 0x5f, 0x1f, 0x0b, 0xfe, 0x76, 0x42, 0xb0, 0x68, 0xee, 0x49,
|
||||||
0x7a, 0x56, 0x5a, 0x8a, 0xd2, 0x5b, 0xd5, 0xaa, 0xaa, 0xeb, 0xd9, 0xe8, 0x52, 0xd4, 0x4d, 0xa5,
|
0xc1, 0xaa, 0xa2, 0xb5, 0x76, 0xf5, 0x19, 0xc1, 0x73, 0x01, 0x37, 0x6b, 0xf5, 0xf2, 0x6e, 0xed,
|
||||||
0x76, 0xd0, 0xd2, 0xd4, 0x90, 0x7c, 0xe5, 0xc6, 0x93, 0xd3, 0x9c, 0xf4, 0xf4, 0x34, 0x27, 0xfd,
|
0x2e, 0x93, 0xbc, 0x09, 0xf2, 0x2c, 0xa0, 0x5c, 0xad, 0x2a, 0x4d, 0x9d, 0x89, 0x9e, 0x63, 0x55,
|
||||||
0x75, 0x9a, 0x93, 0x1e, 0x3e, 0xcb, 0x45, 0x9e, 0x3e, 0xcb, 0x45, 0x7e, 0x7f, 0x96, 0x8b, 0xdc,
|
0x95, 0x4f, 0x95, 0x2a, 0x53, 0x2d, 0x64, 0xfd, 0x2a, 0xc1, 0xb9, 0xf9, 0x33, 0x8d, 0xb6, 0x61,
|
||||||
0xd9, 0xe9, 0x3a, 0xf4, 0x78, 0xd8, 0x2e, 0x75, 0x48, 0x5f, 0x7c, 0x31, 0x88, 0x9f, 0xcb, 0xbe,
|
0x6b, 0x4c, 0x57, 0x3e, 0x57, 0xaa, 0x2d, 0xbd, 0xa1, 0xce, 0xd7, 0xb9, 0x05, 0xb9, 0xd7, 0x22,
|
||||||
0xfd, 0x55, 0xf9, 0x3e, 0xff, 0xb4, 0x69, 0xc7, 0xd9, 0x05, 0x78, 0xef, 0xdf, 0x00, 0x00, 0x00,
|
0xeb, 0x0d, 0xdd, 0x50, 0x5b, 0xf5, 0xb4, 0xb4, 0x10, 0xa5, 0xb5, 0xaa, 0x55, 0x45, 0xd3, 0xd2,
|
||||||
0xff, 0xff, 0x7b, 0x95, 0x5a, 0x6f, 0xf1, 0x0c, 0x00, 0x00,
|
0xe1, 0x85, 0xa8, 0x9b, 0xe5, 0xda, 0x6e, 0x4b, 0x55, 0x02, 0xf1, 0x95, 0x8f, 0x9f, 0x3c, 0xcb,
|
||||||
|
0x48, 0x4f, 0x9f, 0x65, 0xa4, 0xbf, 0x9f, 0x65, 0xa4, 0x87, 0xcf, 0x33, 0xa1, 0xa7, 0xcf, 0x33,
|
||||||
|
0xa1, 0x3f, 0x9e, 0x67, 0x42, 0x77, 0xb7, 0xba, 0x36, 0x3d, 0x18, 0xb6, 0x0b, 0x1d, 0xd2, 0x17,
|
||||||
|
0x3f, 0x87, 0xc4, 0x3f, 0x57, 0x3c, 0xeb, 0xab, 0xe2, 0x7d, 0xfe, 0xbb, 0xad, 0x1d, 0x65, 0x03,
|
||||||
|
0xf0, 0xfe, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x5a, 0xf3, 0xf9, 0xce, 0x0d, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *GroupPolicyInfo) Equal(that interface{}) bool {
|
func (this *GroupPolicyInfo) Equal(that interface{}) bool {
|
||||||
|
@ -1072,14 +1142,18 @@ func (m *ThresholdDecisionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error)
|
||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Timeout, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.Timeout):])
|
if m.Windows != nil {
|
||||||
if err2 != nil {
|
{
|
||||||
return 0, err2
|
size, err := m.Windows.MarshalToSizedBuffer(dAtA[:i])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
i -= size
|
||||||
|
i = encodeVarintTypes(dAtA, i, uint64(size))
|
||||||
}
|
}
|
||||||
i -= n2
|
|
||||||
i = encodeVarintTypes(dAtA, i, uint64(n2))
|
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x12
|
dAtA[i] = 0x12
|
||||||
|
}
|
||||||
if len(m.Threshold) > 0 {
|
if len(m.Threshold) > 0 {
|
||||||
i -= len(m.Threshold)
|
i -= len(m.Threshold)
|
||||||
copy(dAtA[i:], m.Threshold)
|
copy(dAtA[i:], m.Threshold)
|
||||||
|
@ -1110,14 +1184,18 @@ func (m *PercentageDecisionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error
|
||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
n3, err3 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Timeout, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.Timeout):])
|
if m.Windows != nil {
|
||||||
if err3 != nil {
|
{
|
||||||
return 0, err3
|
size, err := m.Windows.MarshalToSizedBuffer(dAtA[:i])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
i -= size
|
||||||
|
i = encodeVarintTypes(dAtA, i, uint64(size))
|
||||||
}
|
}
|
||||||
i -= n3
|
|
||||||
i = encodeVarintTypes(dAtA, i, uint64(n3))
|
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x12
|
dAtA[i] = 0x12
|
||||||
|
}
|
||||||
if len(m.Percentage) > 0 {
|
if len(m.Percentage) > 0 {
|
||||||
i -= len(m.Percentage)
|
i -= len(m.Percentage)
|
||||||
copy(dAtA[i:], m.Percentage)
|
copy(dAtA[i:], m.Percentage)
|
||||||
|
@ -1128,6 +1206,45 @@ func (m *PercentageDecisionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error
|
||||||
return len(dAtA) - i, nil
|
return len(dAtA) - i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *DecisionPolicyWindows) Marshal() (dAtA []byte, err error) {
|
||||||
|
size := m.Size()
|
||||||
|
dAtA = make([]byte, size)
|
||||||
|
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dAtA[:n], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DecisionPolicyWindows) MarshalTo(dAtA []byte) (int, error) {
|
||||||
|
size := m.Size()
|
||||||
|
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DecisionPolicyWindows) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
|
i := len(dAtA)
|
||||||
|
_ = i
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
n4, err4 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MinExecutionPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MinExecutionPeriod):])
|
||||||
|
if err4 != nil {
|
||||||
|
return 0, err4
|
||||||
|
}
|
||||||
|
i -= n4
|
||||||
|
i = encodeVarintTypes(dAtA, i, uint64(n4))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x12
|
||||||
|
n5, err5 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.VotingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.VotingPeriod):])
|
||||||
|
if err5 != nil {
|
||||||
|
return 0, err5
|
||||||
|
}
|
||||||
|
i -= n5
|
||||||
|
i = encodeVarintTypes(dAtA, i, uint64(n5))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0xa
|
||||||
|
return len(dAtA) - i, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *GroupInfo) Marshal() (dAtA []byte, err error) {
|
func (m *GroupInfo) Marshal() (dAtA []byte, err error) {
|
||||||
size := m.Size()
|
size := m.Size()
|
||||||
dAtA = make([]byte, size)
|
dAtA = make([]byte, size)
|
||||||
|
@ -1148,12 +1265,12 @@ func (m *GroupInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
n4, err4 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):])
|
n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):])
|
||||||
if err4 != nil {
|
if err6 != nil {
|
||||||
return 0, err4
|
return 0, err6
|
||||||
}
|
}
|
||||||
i -= n4
|
i -= n6
|
||||||
i = encodeVarintTypes(dAtA, i, uint64(n4))
|
i = encodeVarintTypes(dAtA, i, uint64(n6))
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x32
|
dAtA[i] = 0x32
|
||||||
if len(m.TotalWeight) > 0 {
|
if len(m.TotalWeight) > 0 {
|
||||||
|
@ -1250,12 +1367,12 @@ func (m *GroupPolicyInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):])
|
n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):])
|
||||||
if err6 != nil {
|
if err8 != nil {
|
||||||
return 0, err6
|
return 0, err8
|
||||||
}
|
}
|
||||||
i -= n6
|
i -= n8
|
||||||
i = encodeVarintTypes(dAtA, i, uint64(n6))
|
i = encodeVarintTypes(dAtA, i, uint64(n8))
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x3a
|
dAtA[i] = 0x3a
|
||||||
if m.DecisionPolicy != nil {
|
if m.DecisionPolicy != nil {
|
||||||
|
@ -1343,12 +1460,12 @@ func (m *Proposal) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x60
|
dAtA[i] = 0x60
|
||||||
}
|
}
|
||||||
n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timeout, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timeout):])
|
n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.VotingPeriodEnd, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.VotingPeriodEnd):])
|
||||||
if err8 != nil {
|
if err10 != nil {
|
||||||
return 0, err8
|
return 0, err10
|
||||||
}
|
}
|
||||||
i -= n8
|
i -= n10
|
||||||
i = encodeVarintTypes(dAtA, i, uint64(n8))
|
i = encodeVarintTypes(dAtA, i, uint64(n10))
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x5a
|
dAtA[i] = 0x5a
|
||||||
{
|
{
|
||||||
|
@ -1381,12 +1498,12 @@ func (m *Proposal) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x30
|
dAtA[i] = 0x30
|
||||||
}
|
}
|
||||||
n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SubmitTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SubmitTime):])
|
n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SubmitTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SubmitTime):])
|
||||||
if err10 != nil {
|
if err12 != nil {
|
||||||
return 0, err10
|
return 0, err12
|
||||||
}
|
}
|
||||||
i -= n10
|
i -= n12
|
||||||
i = encodeVarintTypes(dAtA, i, uint64(n10))
|
i = encodeVarintTypes(dAtA, i, uint64(n12))
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x2a
|
dAtA[i] = 0x2a
|
||||||
if len(m.Proposers) > 0 {
|
if len(m.Proposers) > 0 {
|
||||||
|
@ -1491,12 +1608,12 @@ func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SubmitTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SubmitTime):])
|
n13, err13 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SubmitTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SubmitTime):])
|
||||||
if err11 != nil {
|
if err13 != nil {
|
||||||
return 0, err11
|
return 0, err13
|
||||||
}
|
}
|
||||||
i -= n11
|
i -= n13
|
||||||
i = encodeVarintTypes(dAtA, i, uint64(n11))
|
i = encodeVarintTypes(dAtA, i, uint64(n13))
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0x2a
|
dAtA[i] = 0x2a
|
||||||
if len(m.Metadata) > 0 {
|
if len(m.Metadata) > 0 {
|
||||||
|
@ -1585,8 +1702,10 @@ func (m *ThresholdDecisionPolicy) Size() (n int) {
|
||||||
if l > 0 {
|
if l > 0 {
|
||||||
n += 1 + l + sovTypes(uint64(l))
|
n += 1 + l + sovTypes(uint64(l))
|
||||||
}
|
}
|
||||||
l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.Timeout)
|
if m.Windows != nil {
|
||||||
|
l = m.Windows.Size()
|
||||||
n += 1 + l + sovTypes(uint64(l))
|
n += 1 + l + sovTypes(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1600,7 +1719,22 @@ func (m *PercentageDecisionPolicy) Size() (n int) {
|
||||||
if l > 0 {
|
if l > 0 {
|
||||||
n += 1 + l + sovTypes(uint64(l))
|
n += 1 + l + sovTypes(uint64(l))
|
||||||
}
|
}
|
||||||
l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.Timeout)
|
if m.Windows != nil {
|
||||||
|
l = m.Windows.Size()
|
||||||
|
n += 1 + l + sovTypes(uint64(l))
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DecisionPolicyWindows) Size() (n int) {
|
||||||
|
if m == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.VotingPeriod)
|
||||||
|
n += 1 + l + sovTypes(uint64(l))
|
||||||
|
l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.MinExecutionPeriod)
|
||||||
n += 1 + l + sovTypes(uint64(l))
|
n += 1 + l + sovTypes(uint64(l))
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
@ -1722,7 +1856,7 @@ func (m *Proposal) Size() (n int) {
|
||||||
}
|
}
|
||||||
l = m.FinalTallyResult.Size()
|
l = m.FinalTallyResult.Size()
|
||||||
n += 1 + l + sovTypes(uint64(l))
|
n += 1 + l + sovTypes(uint64(l))
|
||||||
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timeout)
|
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.VotingPeriodEnd)
|
||||||
n += 1 + l + sovTypes(uint64(l))
|
n += 1 + l + sovTypes(uint64(l))
|
||||||
if m.ExecutorResult != 0 {
|
if m.ExecutorResult != 0 {
|
||||||
n += 1 + sovTypes(uint64(m.ExecutorResult))
|
n += 1 + sovTypes(uint64(m.ExecutorResult))
|
||||||
|
@ -2118,7 +2252,7 @@ func (m *ThresholdDecisionPolicy) Unmarshal(dAtA []byte) error {
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
case 2:
|
case 2:
|
||||||
if wireType != 2 {
|
if wireType != 2 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Timeout", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field Windows", wireType)
|
||||||
}
|
}
|
||||||
var msglen int
|
var msglen int
|
||||||
for shift := uint(0); ; shift += 7 {
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
@ -2145,7 +2279,10 @@ func (m *ThresholdDecisionPolicy) Unmarshal(dAtA []byte) error {
|
||||||
if postIndex > l {
|
if postIndex > l {
|
||||||
return io.ErrUnexpectedEOF
|
return io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.Timeout, dAtA[iNdEx:postIndex]); err != nil {
|
if m.Windows == nil {
|
||||||
|
m.Windows = &DecisionPolicyWindows{}
|
||||||
|
}
|
||||||
|
if err := m.Windows.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
@ -2233,7 +2370,7 @@ func (m *PercentageDecisionPolicy) Unmarshal(dAtA []byte) error {
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
case 2:
|
case 2:
|
||||||
if wireType != 2 {
|
if wireType != 2 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Timeout", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field Windows", wireType)
|
||||||
}
|
}
|
||||||
var msglen int
|
var msglen int
|
||||||
for shift := uint(0); ; shift += 7 {
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
@ -2260,7 +2397,126 @@ func (m *PercentageDecisionPolicy) Unmarshal(dAtA []byte) error {
|
||||||
if postIndex > l {
|
if postIndex > l {
|
||||||
return io.ErrUnexpectedEOF
|
return io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.Timeout, dAtA[iNdEx:postIndex]); err != nil {
|
if m.Windows == nil {
|
||||||
|
m.Windows = &DecisionPolicyWindows{}
|
||||||
|
}
|
||||||
|
if err := m.Windows.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
iNdEx = postIndex
|
||||||
|
default:
|
||||||
|
iNdEx = preIndex
|
||||||
|
skippy, err := skipTypes(dAtA[iNdEx:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||||
|
return ErrInvalidLengthTypes
|
||||||
|
}
|
||||||
|
if (iNdEx + skippy) > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
iNdEx += skippy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if iNdEx > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (m *DecisionPolicyWindows) Unmarshal(dAtA []byte) error {
|
||||||
|
l := len(dAtA)
|
||||||
|
iNdEx := 0
|
||||||
|
for iNdEx < l {
|
||||||
|
preIndex := iNdEx
|
||||||
|
var wire uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowTypes
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
wire |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldNum := int32(wire >> 3)
|
||||||
|
wireType := int(wire & 0x7)
|
||||||
|
if wireType == 4 {
|
||||||
|
return fmt.Errorf("proto: DecisionPolicyWindows: wiretype end group for non-group")
|
||||||
|
}
|
||||||
|
if fieldNum <= 0 {
|
||||||
|
return fmt.Errorf("proto: DecisionPolicyWindows: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||||
|
}
|
||||||
|
switch fieldNum {
|
||||||
|
case 1:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field VotingPeriod", wireType)
|
||||||
|
}
|
||||||
|
var msglen int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowTypes
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
msglen |= int(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if msglen < 0 {
|
||||||
|
return ErrInvalidLengthTypes
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + msglen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthTypes
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.VotingPeriod, dAtA[iNdEx:postIndex]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 2:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field MinExecutionPeriod", wireType)
|
||||||
|
}
|
||||||
|
var msglen int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowTypes
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
msglen |= int(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if msglen < 0 {
|
||||||
|
return ErrInvalidLengthTypes
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + msglen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return ErrInvalidLengthTypes
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.MinExecutionPeriod, dAtA[iNdEx:postIndex]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
@ -3148,7 +3404,7 @@ func (m *Proposal) Unmarshal(dAtA []byte) error {
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
case 11:
|
case 11:
|
||||||
if wireType != 2 {
|
if wireType != 2 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Timeout", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field VotingPeriodEnd", wireType)
|
||||||
}
|
}
|
||||||
var msglen int
|
var msglen int
|
||||||
for shift := uint(0); ; shift += 7 {
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
@ -3175,7 +3431,7 @@ func (m *Proposal) Unmarshal(dAtA []byte) error {
|
||||||
if postIndex > l {
|
if postIndex > l {
|
||||||
return io.ErrUnexpectedEOF
|
return io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timeout, dAtA[iNdEx:postIndex]); err != nil {
|
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.VotingPeriodEnd, dAtA[iNdEx:postIndex]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
|
|
@ -9,6 +9,105 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestThresholdDecisionPolicyValidate(t *testing.T) {
|
||||||
|
g := group.GroupInfo{
|
||||||
|
TotalWeight: "10",
|
||||||
|
}
|
||||||
|
config := group.DefaultConfig()
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
policy group.ThresholdDecisionPolicy
|
||||||
|
expErr bool
|
||||||
|
}{
|
||||||
|
|
||||||
|
{
|
||||||
|
"threshold bigger than total weight",
|
||||||
|
group.ThresholdDecisionPolicy{
|
||||||
|
Threshold: "12",
|
||||||
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"min exec period too big",
|
||||||
|
group.ThresholdDecisionPolicy{
|
||||||
|
Threshold: "5",
|
||||||
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second,
|
||||||
|
MinExecutionPeriod: time.Hour * 24 * 30,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all good",
|
||||||
|
group.ThresholdDecisionPolicy{
|
||||||
|
Threshold: "5",
|
||||||
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Hour,
|
||||||
|
MinExecutionPeriod: time.Hour * 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
err := tc.policy.Validate(g, config)
|
||||||
|
if tc.expErr {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPercentageDecisionPolicyValidate(t *testing.T) {
|
||||||
|
g := group.GroupInfo{}
|
||||||
|
config := group.DefaultConfig()
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
policy group.PercentageDecisionPolicy
|
||||||
|
expErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"min exec period too big",
|
||||||
|
group.PercentageDecisionPolicy{
|
||||||
|
Percentage: "0.5",
|
||||||
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second,
|
||||||
|
MinExecutionPeriod: time.Hour * 24 * 30,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all good",
|
||||||
|
group.PercentageDecisionPolicy{
|
||||||
|
Percentage: "0.5",
|
||||||
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Hour,
|
||||||
|
MinExecutionPeriod: time.Hour * 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
err := tc.policy.Validate(g, config)
|
||||||
|
if tc.expErr {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -17,12 +116,15 @@ func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
||||||
totalPower string
|
totalPower string
|
||||||
votingDuration time.Duration
|
votingDuration time.Duration
|
||||||
result group.DecisionPolicyResult
|
result group.DecisionPolicyResult
|
||||||
|
expErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"YesCount percentage > decision policy percentage",
|
"YesCount percentage > decision policy percentage",
|
||||||
&group.PercentageDecisionPolicy{
|
&group.PercentageDecisionPolicy{
|
||||||
Percentage: "0.5",
|
Percentage: "0.5",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "2",
|
YesCount: "2",
|
||||||
|
@ -36,12 +138,15 @@ func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: true,
|
Allow: true,
|
||||||
Final: true,
|
Final: true,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"YesCount percentage == decision policy percentage",
|
"YesCount percentage == decision policy percentage",
|
||||||
&group.PercentageDecisionPolicy{
|
&group.PercentageDecisionPolicy{
|
||||||
Percentage: "0.5",
|
Percentage: "0.5",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "2",
|
YesCount: "2",
|
||||||
|
@ -55,12 +160,15 @@ func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: true,
|
Allow: true,
|
||||||
Final: true,
|
Final: true,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"YesCount percentage < decision policy percentage",
|
"YesCount percentage < decision policy percentage",
|
||||||
&group.PercentageDecisionPolicy{
|
&group.PercentageDecisionPolicy{
|
||||||
Percentage: "0.5",
|
Percentage: "0.5",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "1",
|
||||||
|
@ -74,12 +182,15 @@ func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: false,
|
Allow: false,
|
||||||
Final: false,
|
Final: false,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sum percentage (YesCount + undecided votes percentage) < decision policy percentage",
|
"sum percentage (YesCount + undecided votes percentage) < decision policy percentage",
|
||||||
&group.PercentageDecisionPolicy{
|
&group.PercentageDecisionPolicy{
|
||||||
Percentage: "0.5",
|
Percentage: "0.5",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "1",
|
||||||
|
@ -93,12 +204,15 @@ func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: false,
|
Allow: false,
|
||||||
Final: true,
|
Final: true,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sum percentage = decision policy percentage",
|
"sum percentage = decision policy percentage",
|
||||||
&group.PercentageDecisionPolicy{
|
&group.PercentageDecisionPolicy{
|
||||||
Percentage: "0.5",
|
Percentage: "0.5",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "1",
|
||||||
|
@ -112,12 +226,15 @@ func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: false,
|
Allow: false,
|
||||||
Final: false,
|
Final: false,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sum percentage > decision policy percentage",
|
"sum percentage > decision policy percentage",
|
||||||
&group.PercentageDecisionPolicy{
|
&group.PercentageDecisionPolicy{
|
||||||
Percentage: "0.5",
|
Percentage: "0.5",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "1",
|
||||||
|
@ -131,12 +248,16 @@ func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: false,
|
Allow: false,
|
||||||
Final: false,
|
Final: false,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"decision policy timeout <= voting duration",
|
"time since submission < min execution period",
|
||||||
&group.PercentageDecisionPolicy{
|
&group.PercentageDecisionPolicy{
|
||||||
Percentage: "0.5",
|
Percentage: "0.5",
|
||||||
Timeout: time.Second * 10,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 10,
|
||||||
|
MinExecutionPeriod: time.Minute,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "2",
|
YesCount: "2",
|
||||||
|
@ -146,17 +267,19 @@ func TestPercentageDecisionPolicyAllow(t *testing.T) {
|
||||||
},
|
},
|
||||||
"3",
|
"3",
|
||||||
time.Duration(time.Second * 50),
|
time.Duration(time.Second * 50),
|
||||||
group.DecisionPolicyResult{
|
group.DecisionPolicyResult{},
|
||||||
Allow: false,
|
true,
|
||||||
Final: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
policyResult, err := tc.policy.Allow(*tc.tally, tc.totalPower, tc.votingDuration)
|
policyResult, err := tc.policy.Allow(*tc.tally, tc.totalPower, tc.votingDuration)
|
||||||
|
if tc.expErr {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tc.result, policyResult)
|
require.Equal(t, tc.result, policyResult)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,12 +292,15 @@ func TestThresholdDecisionPolicyAllow(t *testing.T) {
|
||||||
totalPower string
|
totalPower string
|
||||||
votingDuration time.Duration
|
votingDuration time.Duration
|
||||||
result group.DecisionPolicyResult
|
result group.DecisionPolicyResult
|
||||||
|
expErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"YesCount >= threshold decision policy",
|
"YesCount >= threshold decision policy",
|
||||||
&group.ThresholdDecisionPolicy{
|
&group.ThresholdDecisionPolicy{
|
||||||
Threshold: "3",
|
Threshold: "3",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "3",
|
YesCount: "3",
|
||||||
|
@ -188,12 +314,15 @@ func TestThresholdDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: true,
|
Allow: true,
|
||||||
Final: true,
|
Final: true,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"YesCount < threshold decision policy",
|
"YesCount < threshold decision policy",
|
||||||
&group.ThresholdDecisionPolicy{
|
&group.ThresholdDecisionPolicy{
|
||||||
Threshold: "3",
|
Threshold: "3",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "1",
|
||||||
|
@ -207,12 +336,15 @@ func TestThresholdDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: false,
|
Allow: false,
|
||||||
Final: false,
|
Final: false,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sum votes < threshold decision policy",
|
"sum votes < threshold decision policy",
|
||||||
&group.ThresholdDecisionPolicy{
|
&group.ThresholdDecisionPolicy{
|
||||||
Threshold: "3",
|
Threshold: "3",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "1",
|
||||||
|
@ -226,12 +358,15 @@ func TestThresholdDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: false,
|
Allow: false,
|
||||||
Final: true,
|
Final: true,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sum votes >= threshold decision policy",
|
"sum votes >= threshold decision policy",
|
||||||
&group.ThresholdDecisionPolicy{
|
&group.ThresholdDecisionPolicy{
|
||||||
Threshold: "3",
|
Threshold: "3",
|
||||||
Timeout: time.Second * 100,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "1",
|
YesCount: "1",
|
||||||
|
@ -245,12 +380,16 @@ func TestThresholdDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: false,
|
Allow: false,
|
||||||
Final: false,
|
Final: false,
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"decision policy timeout <= voting duration",
|
"time since submission < min execution period",
|
||||||
&group.ThresholdDecisionPolicy{
|
&group.ThresholdDecisionPolicy{
|
||||||
Threshold: "3",
|
Threshold: "3",
|
||||||
Timeout: time.Second * 10,
|
Windows: &group.DecisionPolicyWindows{
|
||||||
|
VotingPeriod: time.Second * 10,
|
||||||
|
MinExecutionPeriod: time.Minute,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&group.TallyResult{
|
&group.TallyResult{
|
||||||
YesCount: "3",
|
YesCount: "3",
|
||||||
|
@ -264,13 +403,18 @@ func TestThresholdDecisionPolicyAllow(t *testing.T) {
|
||||||
Allow: false,
|
Allow: false,
|
||||||
Final: true,
|
Final: true,
|
||||||
},
|
},
|
||||||
|
true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
policyResult, err := tc.policy.Allow(*tc.tally, tc.totalPower, tc.votingDuration)
|
policyResult, err := tc.policy.Allow(*tc.tally, tc.totalPower, tc.votingDuration)
|
||||||
|
if tc.expErr {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tc.result, policyResult)
|
require.Equal(t, tc.result, policyResult)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue