github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/types/params.go (about)

     1  package types
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  
     8  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     9  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
    10  	paramtypes "github.com/fibonacci-chain/fbc/x/params"
    11  	"github.com/gogo/protobuf/jsonpb"
    12  	"github.com/pkg/errors"
    13  	"gopkg.in/yaml.v2"
    14  )
    15  
    16  var (
    17  	ParamStoreKeyUploadAccess        = []byte("uploadAccess")
    18  	ParamStoreKeyInstantiateAccess   = []byte("instantiateAccess")
    19  	ParamStoreKeyContractBlockedList = []byte("EnableContractBlockedList")
    20  	ParamStoreKeyVMBridgeEnable      = []byte("VMBridgeEnable")
    21  )
    22  
    23  var AllAccessTypes = []AccessType{
    24  	AccessTypeNobody,
    25  	AccessTypeOnlyAddress,
    26  	AccessTypeEverybody,
    27  }
    28  
    29  func (a AccessType) With(addr sdk.AccAddress) AccessConfig {
    30  	switch a {
    31  	case AccessTypeNobody:
    32  		return AllowNobody
    33  	case AccessTypeOnlyAddress:
    34  		if err := sdk.VerifyAddressFormat(addr); err != nil {
    35  			panic(err)
    36  		}
    37  		return AccessConfig{Permission: AccessTypeOnlyAddress, Address: addr.String()}
    38  	case AccessTypeEverybody:
    39  		return AllowEverybody
    40  	}
    41  	panic("unsupported access type")
    42  }
    43  
    44  func (a AccessType) String() string {
    45  	switch a {
    46  	case AccessTypeNobody:
    47  		return "Nobody"
    48  	case AccessTypeOnlyAddress:
    49  		return "OnlyAddress"
    50  	case AccessTypeEverybody:
    51  		return "Everybody"
    52  	}
    53  	return "Unspecified"
    54  }
    55  
    56  func (a *AccessType) UnmarshalText(text []byte) error {
    57  	for _, v := range AllAccessTypes {
    58  		if v.String() == string(text) {
    59  			*a = v
    60  			return nil
    61  		}
    62  	}
    63  	*a = AccessTypeUnspecified
    64  	return nil
    65  }
    66  
    67  func (a AccessType) MarshalText() ([]byte, error) {
    68  	return []byte(a.String()), nil
    69  }
    70  
    71  func (a *AccessType) MarshalJSONPB(_ *jsonpb.Marshaler) ([]byte, error) {
    72  	return json.Marshal(a)
    73  }
    74  
    75  func (a *AccessType) UnmarshalJSONPB(_ *jsonpb.Unmarshaler, data []byte) error {
    76  	return json.Unmarshal(data, a)
    77  }
    78  
    79  func (a AccessConfig) Equals(o AccessConfig) bool {
    80  	return a.Permission == o.Permission && a.Address == o.Address
    81  }
    82  
    83  var (
    84  	DefaultUploadAccess = AllowNobody
    85  	AllowEverybody      = AccessConfig{Permission: AccessTypeEverybody}
    86  	AllowNobody         = AccessConfig{Permission: AccessTypeNobody}
    87  )
    88  
    89  // ParamKeyTable returns the parameter key table.
    90  func ParamKeyTable() paramtypes.KeyTable {
    91  	return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
    92  }
    93  
    94  // DefaultParams returns default wasm parameters
    95  func DefaultParams() Params {
    96  	return Params{
    97  		CodeUploadAccess:             AllowNobody,
    98  		InstantiateDefaultPermission: AccessTypeEverybody,
    99  		UseContractBlockedList:       true,
   100  		VmbridgeEnable:               false,
   101  	}
   102  }
   103  
   104  // TestParams returns default wasm parameters for unit tests
   105  func TestParams() Params {
   106  	params := DefaultParams()
   107  	params.CodeUploadAccess = AllowEverybody
   108  	params.VmbridgeEnable = true
   109  	return params
   110  }
   111  
   112  func (p Params) String() string {
   113  	out, err := yaml.Marshal(p)
   114  	if err != nil {
   115  		panic(err)
   116  	}
   117  	return string(out)
   118  }
   119  
   120  // ParamSetPairs returns the parameter set pairs.
   121  func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
   122  	return paramtypes.ParamSetPairs{
   123  		paramtypes.NewParamSetPair(ParamStoreKeyUploadAccess, &p.CodeUploadAccess, validateAccessConfig),
   124  		paramtypes.NewParamSetPair(ParamStoreKeyInstantiateAccess, &p.InstantiateDefaultPermission, validateAccessType),
   125  		paramtypes.NewParamSetPair(ParamStoreKeyContractBlockedList, &p.UseContractBlockedList, validateBool),
   126  		paramtypes.NewParamSetPair(ParamStoreKeyVMBridgeEnable, &p.VmbridgeEnable, validateBool),
   127  	}
   128  }
   129  
   130  // ValidateBasic performs basic validation on wasm parameters
   131  func (p Params) ValidateBasic() error {
   132  	if err := validateAccessType(p.InstantiateDefaultPermission); err != nil {
   133  		return errors.Wrap(err, "instantiate default permission")
   134  	}
   135  	if err := validateAccessConfig(p.CodeUploadAccess); err != nil {
   136  		return errors.Wrap(err, "upload access")
   137  	}
   138  	return nil
   139  }
   140  
   141  func validateAccessConfig(i interface{}) error {
   142  	v, ok := i.(AccessConfig)
   143  	if !ok {
   144  		return fmt.Errorf("invalid parameter type: %T", i)
   145  	}
   146  	return v.ValidateBasic()
   147  }
   148  
   149  func validateBool(i interface{}) error {
   150  	_, ok := i.(bool)
   151  	if !ok {
   152  		return fmt.Errorf("invalid parameter type: %T", i)
   153  	}
   154  	return nil
   155  }
   156  
   157  func validateAccessType(i interface{}) error {
   158  	a, ok := i.(AccessType)
   159  	if !ok {
   160  		return fmt.Errorf("invalid parameter type: %T", i)
   161  	}
   162  	if a == AccessTypeUnspecified {
   163  		return sdkerrors.Wrap(ErrEmpty, "type")
   164  	}
   165  	for _, v := range AllAccessTypes {
   166  		if v == a {
   167  			return nil
   168  		}
   169  	}
   170  	return sdkerrors.Wrapf(ErrInvalid, "unknown type: %q", a)
   171  }
   172  
   173  func (a AccessConfig) ValidateBasic() error {
   174  	switch a.Permission {
   175  	case AccessTypeUnspecified:
   176  		return sdkerrors.Wrap(ErrEmpty, "type")
   177  	case AccessTypeNobody, AccessTypeEverybody:
   178  		if len(a.Address) != 0 {
   179  			return sdkerrors.Wrap(ErrInvalid, "address not allowed for this type")
   180  		}
   181  		return nil
   182  	case AccessTypeOnlyAddress:
   183  		for _, addr := range strings.Split(a.Address, ",") {
   184  			if _, err := sdk.AccAddressFromBech32(addr); err != nil {
   185  				return err
   186  			}
   187  		}
   188  		return nil
   189  	}
   190  	return sdkerrors.Wrapf(ErrInvalid, "unknown type: %q", a.Permission)
   191  }
   192  
   193  func (a AccessConfig) Allowed(actor sdk.AccAddress) bool {
   194  	switch a.Permission {
   195  	case AccessTypeNobody:
   196  		return false
   197  	case AccessTypeEverybody:
   198  		return true
   199  	case AccessTypeOnlyAddress:
   200  		addrs := strings.Split(a.Address, ",")
   201  		for _, addr := range addrs {
   202  			if addr == actor.String() {
   203  				return true
   204  			}
   205  		}
   206  		return false
   207  	default:
   208  		panic("unknown type")
   209  	}
   210  }