github.com/InjectiveLabs/sdk-go@v1.53.0/chain/wasmx/types/proposal.go (about) 1 package types 2 3 import ( 4 "cosmossdk.io/errors" 5 sdk "github.com/cosmos/cosmos-sdk/types" 6 govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" 7 ) 8 9 // constants 10 const ( 11 ProposalContractRegistrationRequest string = "ProposalContractRegistrationRequest" 12 ProposalBatchContractRegistrationRequest string = "ProposalBatchContractRegistrationRequest" 13 ProposalBatchContractDeregistration string = "ProposalBatchContractDeregistration" 14 ProposalBatchStoreCode string = "ProposalBatchStoreCode" 15 ) 16 17 func init() { 18 govtypes.RegisterProposalType(ProposalContractRegistrationRequest) 19 govtypes.RegisterProposalType(ProposalBatchContractRegistrationRequest) 20 govtypes.RegisterProposalType(ProposalBatchContractDeregistration) 21 govtypes.RegisterProposalType(ProposalBatchStoreCode) 22 } 23 24 // Implements Proposal Interface 25 var _ govtypes.Content = &ContractRegistrationRequestProposal{} 26 var _ govtypes.Content = &BatchContractRegistrationRequestProposal{} 27 var _ govtypes.Content = &BatchContractDeregistrationProposal{} 28 var _ govtypes.Content = &BatchStoreCodeProposal{} 29 30 // NewContractRegistrationRequestProposal returns new instance of ContractRegistrationRequestProposal 31 func NewContractRegistrationRequestProposal(title, description string, contractRegistrationRequest ContractRegistrationRequest) *ContractRegistrationRequestProposal { 32 return &ContractRegistrationRequestProposal{ 33 Title: title, 34 Description: description, 35 ContractRegistrationRequest: contractRegistrationRequest, 36 } 37 } 38 39 // GetTitle returns the title of this proposal. 40 func (p *ContractRegistrationRequestProposal) GetTitle() string { 41 return p.Title 42 } 43 44 // GetDescription returns the description of this proposal. 45 func (p *ContractRegistrationRequestProposal) GetDescription() string { 46 return p.Description 47 } 48 49 // ProposalRoute returns router key of this proposal. 50 func (p *ContractRegistrationRequestProposal) ProposalRoute() string { return RouterKey } 51 52 // ProposalType returns proposal type of this proposal. 53 func (p *ContractRegistrationRequestProposal) ProposalType() string { 54 return ProposalContractRegistrationRequest 55 } 56 57 // ValidateBasic returns ValidateBasic result of this proposal. 58 func (p *ContractRegistrationRequestProposal) ValidateBasic() error { 59 if err := p.ContractRegistrationRequest.Validate(); err != nil { 60 return err 61 } 62 63 return govtypes.ValidateAbstract(p) 64 } 65 66 func (req *ContractRegistrationRequest) Validate() error { 67 // Check if contract address is valid 68 if _, err := sdk.AccAddressFromBech32(req.ContractAddress); err != nil { 69 return errors.Wrapf(ErrInvalidContractAddress, "ContractRegistrationRequestProposal: Error parsing registry contract address %s", err.Error()) 70 } 71 72 if req.GranterAddress != "" { 73 if _, err := sdk.AccAddressFromBech32(req.GranterAddress); err != nil { 74 return errors.Wrapf(ErrInvalidContractAddress, "ContractRegistrationRequestProposal: Error parsing granter address %s", err.Error()) 75 } 76 } 77 78 if req.FundingMode == FundingMode_Unspecified { 79 return errors.Wrapf(ErrInvalidFundingMode, "ContractRegistrationRequestProposal: FundingMode must be specified") 80 } 81 82 if (req.FundingMode == FundingMode_GrantOnly || req.FundingMode == FundingMode_Dual) && req.GranterAddress == "" { 83 return errors.Wrapf(ErrInvalidFundingMode, "GranterAddress must be specified") 84 } 85 86 if req.FundingMode == FundingMode_SelfFunded && req.GranterAddress != "" { 87 return errors.Wrapf(ErrInvalidFundingMode, "GranterAddress must be empty for self-funded contracts") 88 } 89 90 return nil 91 } 92 93 // GetTitle returns the title of this proposal. 94 func (p *BatchContractRegistrationRequestProposal) GetTitle() string { 95 return p.Title 96 } 97 98 // GetDescription returns the description of this proposal. 99 func (p *BatchContractRegistrationRequestProposal) GetDescription() string { 100 return p.Description 101 } 102 103 // ProposalRoute returns router key of this proposal. 104 func (p *BatchContractRegistrationRequestProposal) ProposalRoute() string { return RouterKey } 105 106 // ProposalType returns proposal type of this proposal. 107 func (p *BatchContractRegistrationRequestProposal) ProposalType() string { 108 return ProposalBatchContractRegistrationRequest 109 } 110 111 // ValidateBasic returns ValidateBasic result of this proposal. 112 func (p *BatchContractRegistrationRequestProposal) ValidateBasic() error { 113 for _, req := range p.ContractRegistrationRequests { 114 if err := req.Validate(); err != nil { 115 return err 116 } 117 } 118 119 if hasDuplicatesContractRegistrationRequest(p.ContractRegistrationRequests) { 120 return errors.Wrapf(ErrDuplicateContract, "BatchContractRegistrationRequestProposal: Duplicate contract registration requests") 121 } 122 123 return govtypes.ValidateAbstract(p) 124 } 125 126 // GetTitle returns the title of this proposal. 127 func (p *BatchContractDeregistrationProposal) GetTitle() string { 128 return p.Title 129 } 130 131 // GetDescription returns the description of this proposal. 132 func (p *BatchContractDeregistrationProposal) GetDescription() string { 133 return p.Description 134 } 135 136 // ProposalRoute returns router key of this proposal. 137 func (p *BatchContractDeregistrationProposal) ProposalRoute() string { return RouterKey } 138 139 // ProposalType returns proposal type of this proposal. 140 func (p *BatchContractDeregistrationProposal) ProposalType() string { 141 return ProposalBatchContractDeregistration 142 } 143 144 // ValidateBasic returns ValidateBasic result of this proposal. 145 func (p *BatchContractDeregistrationProposal) ValidateBasic() error { 146 if len(p.Contracts) == 0 { 147 return errors.Wrapf(ErrNoContractAddresses, "BatchContractDeregistrationProposal: Contract list was empty") 148 } 149 150 found := make(map[string]struct{}) 151 152 for _, contract := range p.Contracts { 153 // Check if contract address is valid 154 addr, err := sdk.AccAddressFromBech32(contract) 155 if err != nil { 156 return errors.Wrapf(ErrInvalidContractAddress, "BatchContractDeregistrationProposal: Error parsing contract address %s", err.Error()) 157 } 158 159 // Check that there are no duplicate contract addresses 160 if _, ok := found[addr.String()]; ok { 161 return errors.Wrapf(ErrDuplicateContract, "BatchContractDeregistrationProposal: Duplicate contract in contracts to deregister") 162 } else { 163 found[addr.String()] = struct{}{} 164 } 165 } 166 167 return govtypes.ValidateAbstract(p) 168 } 169 170 // GetTitle returns the title of this proposal. 171 func (p *BatchStoreCodeProposal) GetTitle() string { 172 return p.Title 173 } 174 175 // GetDescription returns the description of this proposal. 176 func (p *BatchStoreCodeProposal) GetDescription() string { 177 return p.Description 178 } 179 180 // ProposalRoute returns router key of this proposal. 181 func (p *BatchStoreCodeProposal) ProposalRoute() string { return RouterKey } 182 183 // ProposalType returns proposal type of this proposal. 184 func (p *BatchStoreCodeProposal) ProposalType() string { 185 return ProposalBatchStoreCode 186 } 187 188 // ValidateBasic returns ValidateBasic result of this proposal. 189 func (p *BatchStoreCodeProposal) ValidateBasic() error { 190 for idx := range p.Proposals { 191 if err := p.Proposals[idx].ValidateBasic(); err != nil { 192 return err 193 } 194 } 195 196 return govtypes.ValidateAbstract(p) 197 } 198 199 func HasDuplicates(slice []string) bool { 200 seen := make(map[string]struct{}) 201 for _, item := range slice { 202 if _, ok := seen[item]; ok { 203 return true 204 } 205 seen[item] = struct{}{} 206 } 207 return false 208 } 209 210 func hasDuplicatesContractRegistrationRequest(slice []ContractRegistrationRequest) bool { 211 seen := make(map[string]struct{}) 212 for _, item := range slice { 213 addr := sdk.MustAccAddressFromBech32(item.ContractAddress).String() 214 if _, ok := seen[addr]; ok { 215 return true 216 } 217 seen[addr] = struct{}{} 218 } 219 return false 220 }