github.com/InjectiveLabs/sdk-go@v1.53.0/chain/ocr/types/types.go (about)

     1  package types
     2  
     3  import (
     4  	"strings"
     5  
     6  	"cosmossdk.io/errors"
     7  	sdk "github.com/cosmos/cosmos-sdk/types"
     8  	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
     9  	"github.com/cosmos/gogoproto/proto"
    10  	"golang.org/x/crypto/sha3"
    11  )
    12  
    13  const FeedIDMaxLength = 20
    14  
    15  var digestPrefixCosmos = []byte("\x00\x02")
    16  var digestSeparator = []byte("\x00\x00")
    17  
    18  func (cfg *ContractConfig) Digest(chainID, feedID string) []byte {
    19  	data, err := proto.Marshal(cfg)
    20  	if err != nil {
    21  		panic("unmarshable")
    22  	}
    23  
    24  	w := sha3.NewLegacyKeccak256()
    25  	if _, err := w.Write(data); err != nil {
    26  		panic(err)
    27  	}
    28  	if _, err := w.Write(digestSeparator); err != nil {
    29  		panic(err)
    30  	}
    31  	if _, err := w.Write([]byte(chainID)); err != nil {
    32  		panic(err)
    33  	}
    34  	if _, err := w.Write(digestSeparator); err != nil {
    35  		panic(err)
    36  	}
    37  	if _, err := w.Write([]byte(feedID)); err != nil {
    38  		panic(err)
    39  	}
    40  
    41  	configDigest := w.Sum(nil)
    42  	configDigest[0] = digestPrefixCosmos[0]
    43  	configDigest[1] = digestPrefixCosmos[1]
    44  
    45  	return configDigest
    46  }
    47  
    48  func (cfg *FeedConfig) ValidTransmitters() map[string]struct{} {
    49  	transmitters := make(map[string]struct{})
    50  	for _, transmitter := range cfg.Transmitters {
    51  		transmitters[transmitter] = struct{}{}
    52  	}
    53  	return transmitters
    54  }
    55  
    56  func (cfg *FeedConfig) TransmitterFromSigner() map[string]sdk.AccAddress {
    57  	transmitterFromSigner := make(map[string]sdk.AccAddress)
    58  	for idx, signer := range cfg.Signers {
    59  		addr, _ := sdk.AccAddressFromBech32(cfg.Transmitters[idx])
    60  		transmitterFromSigner[signer] = addr
    61  	}
    62  	return transmitterFromSigner
    63  }
    64  
    65  func (cfg *FeedConfig) ValidateBasic() error {
    66  	if err := checkConfigValid(
    67  		len(cfg.Signers),
    68  		len(cfg.Transmitters),
    69  		int(cfg.F),
    70  	); err != nil {
    71  		return err
    72  	}
    73  
    74  	if cfg.ModuleParams == nil {
    75  		return errors.Wrap(ErrIncorrectConfig, "onchain config is not specified")
    76  	}
    77  
    78  	// TODO: determine whether this is a sensible enough limitation
    79  	if cfg.ModuleParams.FeedId == "" || len(cfg.ModuleParams.FeedId) > FeedIDMaxLength {
    80  		return errors.Wrap(ErrIncorrectConfig, "feed_id is missing or incorrect length")
    81  	}
    82  
    83  	if strings.TrimSpace(cfg.ModuleParams.FeedId) != cfg.ModuleParams.FeedId {
    84  		return errors.Wrap(ErrIncorrectConfig, "feed_id cannot have leading or trailing space characters")
    85  	}
    86  
    87  	if cfg.ModuleParams.FeedAdmin != "" {
    88  		if _, err := sdk.AccAddressFromBech32(cfg.ModuleParams.FeedAdmin); err != nil {
    89  			return err
    90  		}
    91  	}
    92  
    93  	if cfg.ModuleParams.BillingAdmin != "" {
    94  		if _, err := sdk.AccAddressFromBech32(cfg.ModuleParams.BillingAdmin); err != nil {
    95  			return err
    96  		}
    97  	}
    98  
    99  	if cfg.ModuleParams.MinAnswer.IsNil() || cfg.ModuleParams.MaxAnswer.IsNil() {
   100  		return errors.Wrap(ErrIncorrectConfig, "MinAnswer and MaxAnswer cannot be nil")
   101  	}
   102  
   103  	if cfg.ModuleParams.LinkPerTransmission.IsNil() || !cfg.ModuleParams.LinkPerTransmission.IsPositive() {
   104  		return errors.Wrap(ErrIncorrectConfig, "LinkPerTransmission must be positive")
   105  	}
   106  
   107  	if cfg.ModuleParams.LinkPerObservation.IsNil() || !cfg.ModuleParams.LinkPerObservation.IsPositive() {
   108  		return errors.Wrap(ErrIncorrectConfig, "LinkPerObservation must be positive")
   109  	}
   110  
   111  	seenTransmitters := make(map[string]struct{}, len(cfg.Transmitters))
   112  	for _, transmitter := range cfg.Transmitters {
   113  		addr, err := sdk.AccAddressFromBech32(transmitter)
   114  		if err != nil {
   115  			return err
   116  		}
   117  
   118  		if _, ok := seenTransmitters[addr.String()]; ok {
   119  			return ErrRepeatedAddress
   120  		} else {
   121  			seenTransmitters[addr.String()] = struct{}{}
   122  		}
   123  	}
   124  
   125  	seenSigners := make(map[string]struct{}, len(cfg.Signers))
   126  	for _, signer := range cfg.Signers {
   127  		addr, err := sdk.AccAddressFromBech32(signer)
   128  		if err != nil {
   129  			return err
   130  		}
   131  
   132  		if _, ok := seenSigners[addr.String()]; ok {
   133  			return ErrRepeatedAddress
   134  		} else {
   135  			seenSigners[addr.String()] = struct{}{}
   136  		}
   137  	}
   138  
   139  	if cfg.ModuleParams.LinkDenom == "" {
   140  		return sdkerrors.ErrInvalidCoins
   141  	}
   142  
   143  	return nil
   144  }
   145  
   146  func checkConfigValid(
   147  	numSigners, numTransmitters, f int,
   148  ) error {
   149  	if numSigners > MaxNumOracles {
   150  		return ErrTooManySigners
   151  	}
   152  
   153  	if f <= 0 {
   154  		return errors.Wrap(ErrIncorrectConfig, "f must be positive")
   155  	}
   156  
   157  	if numSigners != numTransmitters {
   158  		return errors.Wrap(ErrIncorrectConfig, "oracle addresses out of registration")
   159  	}
   160  
   161  	if numSigners <= 3*f {
   162  		return errors.Wrapf(ErrIncorrectConfig, "faulty-oracle f too high: %d", f)
   163  	}
   164  
   165  	return nil
   166  }
   167  
   168  func ReportFromBytes(buf []byte) (*ReportToSign, error) {
   169  	var r ReportToSign
   170  	if err := proto.Unmarshal(buf, &r); err != nil {
   171  		err = errors.Wrap(err, "failed to proto-decode ReportToSign from bytes")
   172  		return nil, err
   173  	}
   174  
   175  	return &r, nil
   176  }
   177  
   178  func (r *ReportToSign) Bytes() []byte {
   179  	data, err := proto.Marshal(r)
   180  	if err != nil {
   181  		panic("unmarshable")
   182  	}
   183  
   184  	return data
   185  }
   186  
   187  func (r *ReportToSign) Digest() []byte {
   188  	w := sha3.NewLegacyKeccak256()
   189  	w.Write(r.Bytes())
   190  	return w.Sum(nil)
   191  }
   192  
   193  type Reward struct {
   194  	Addr   sdk.AccAddress
   195  	Amount sdk.Coin
   196  }