code.vegaprotocol.io/vega@v0.79.0/core/datasource/common/data_signer.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  //lint:file-ignore ST1003 Ignore underscores in names, this is straigh copied from the proto package to ease introducing the domain types
    17  
    18  package common
    19  
    20  import (
    21  	"encoding/hex"
    22  	"fmt"
    23  	"strings"
    24  
    25  	"code.vegaprotocol.io/vega/core/datasource/errors"
    26  	"code.vegaprotocol.io/vega/libs/stringer"
    27  	datapb "code.vegaprotocol.io/vega/protos/vega/data/v1"
    28  )
    29  
    30  // PubKey.
    31  type PubKey struct {
    32  	Key string
    33  }
    34  
    35  func (p PubKey) IntoProto() *datapb.PubKey {
    36  	return &datapb.PubKey{
    37  		Key: p.Key,
    38  	}
    39  }
    40  
    41  func (p PubKey) String() string {
    42  	return fmt.Sprintf(
    43  		"pubKey(%s)",
    44  		p.Key,
    45  	)
    46  }
    47  
    48  func (p PubKey) DeepClone() *PubKey {
    49  	return &PubKey{
    50  		Key: p.Key,
    51  	}
    52  }
    53  
    54  type SignerPubKey struct {
    55  	PubKey *PubKey
    56  }
    57  
    58  func (s SignerPubKey) String() string {
    59  	return fmt.Sprintf(
    60  		"signerPubKey(%s)",
    61  		stringer.PtrToString(s.PubKey),
    62  	)
    63  }
    64  
    65  func (s SignerPubKey) IntoProto() *datapb.Signer_PubKey {
    66  	pubKey := &datapb.PubKey{}
    67  	if s.PubKey != nil {
    68  		pubKey = s.PubKey.IntoProto()
    69  	}
    70  
    71  	return &datapb.Signer_PubKey{
    72  		PubKey: pubKey,
    73  	}
    74  }
    75  
    76  func (s SignerPubKey) oneOfProto() interface{} {
    77  	return s.IntoProto()
    78  }
    79  
    80  func (s SignerPubKey) GetSignerType() SignerType {
    81  	return SignerTypePubKey
    82  }
    83  
    84  func (s SignerPubKey) DeepClone() signer {
    85  	if s.PubKey == nil {
    86  		return &SignerPubKey{}
    87  	}
    88  	return &SignerPubKey{
    89  		PubKey: s.PubKey,
    90  	}
    91  }
    92  
    93  func (s SignerPubKey) IsEmpty() bool {
    94  	if s.PubKey == nil {
    95  		return true
    96  	}
    97  	return s.PubKey.Key == ""
    98  }
    99  
   100  func (s SignerPubKey) AsHex(prepend bool) (signer, error) {
   101  	if s.PubKey == nil {
   102  		return &s, errors.ErrSignerIsEmpty
   103  	}
   104  
   105  	if s.PubKey.Key == "" {
   106  		return nil, errors.ErrSignerIsEmpty
   107  	}
   108  
   109  	// Check if the content is already hex encoded
   110  	if strings.HasPrefix(s.PubKey.Key, "0x") {
   111  		return &s, nil
   112  	}
   113  
   114  	validHex, _ := isHex(s.PubKey.Key)
   115  	if validHex {
   116  		if prepend {
   117  			s.PubKey.Key = fmt.Sprintf("0x%s", s.PubKey.Key)
   118  		}
   119  		return &s, nil
   120  	}
   121  
   122  	// If the content is not a valid Hex - encode it
   123  	s.PubKey.Key = fmt.Sprintf("0x%s", hex.EncodeToString([]byte(s.PubKey.Key)))
   124  	return &s, nil
   125  }
   126  
   127  func (s SignerPubKey) AsString() (signer, error) {
   128  	if s.PubKey == nil {
   129  		return nil, errors.ErrSignerIsEmpty
   130  	}
   131  
   132  	// Check if the content is hex encoded
   133  	st := strings.TrimPrefix(s.PubKey.Key, "0x")
   134  	validHex, _ := isHex(st)
   135  	if validHex {
   136  		decoded, err := hex.DecodeString(st)
   137  		if err != nil {
   138  			return &s, fmt.Errorf("error decoding signer: %v", err)
   139  		}
   140  
   141  		s.PubKey.Key = string(decoded)
   142  	}
   143  	return &s, nil
   144  }
   145  
   146  func (s SignerPubKey) Serialize() []byte {
   147  	c := strings.TrimPrefix(s.PubKey.Key, "0x")
   148  	return append([]byte{byte(SignerPubKeyPrepend)}, []byte(c)...)
   149  }
   150  
   151  func DeserializePubKey(data []byte) *SignerPubKey {
   152  	return &SignerPubKey{
   153  		PubKey: &PubKey{
   154  			Key: string(data),
   155  		},
   156  	}
   157  }
   158  
   159  func PubKeyFromProto(s *datapb.Signer_PubKey) *SignerPubKey {
   160  	var pubKey *PubKey
   161  	if s != nil {
   162  		if s.PubKey != nil {
   163  			pubKey = &PubKey{
   164  				Key: s.PubKey.Key,
   165  			}
   166  		}
   167  	}
   168  
   169  	return &SignerPubKey{
   170  		PubKey: pubKey,
   171  	}
   172  }
   173  
   174  // ETHAddress.
   175  type ETHAddress struct {
   176  	Address string
   177  }
   178  
   179  func (e ETHAddress) IntoProto() *datapb.ETHAddress {
   180  	return &datapb.ETHAddress{
   181  		Address: e.Address,
   182  	}
   183  }
   184  
   185  func (e ETHAddress) String() string {
   186  	return fmt.Sprintf(
   187  		"ethAddress(%s)",
   188  		e.Address,
   189  	)
   190  }
   191  
   192  func (e ETHAddress) DeepClone() *ETHAddress {
   193  	return &ETHAddress{
   194  		Address: e.Address,
   195  	}
   196  }
   197  
   198  type SignerETHAddress struct {
   199  	ETHAddress *ETHAddress
   200  }
   201  
   202  func (s SignerETHAddress) String() string {
   203  	return fmt.Sprintf(
   204  		"signerETHAddress(%s)",
   205  		stringer.PtrToString(s.ETHAddress),
   206  	)
   207  }
   208  
   209  func (s SignerETHAddress) IntoProto() *datapb.Signer_EthAddress {
   210  	ethAddress := &datapb.ETHAddress{}
   211  	if s.ETHAddress != nil {
   212  		ethAddress = s.ETHAddress.IntoProto()
   213  	}
   214  
   215  	return &datapb.Signer_EthAddress{
   216  		EthAddress: ethAddress,
   217  	}
   218  }
   219  
   220  func (s SignerETHAddress) oneOfProto() interface{} {
   221  	return s.IntoProto()
   222  }
   223  
   224  func (s SignerETHAddress) GetSignerType() SignerType {
   225  	return SignerTypeEthAddress
   226  }
   227  
   228  func (s SignerETHAddress) DeepClone() signer {
   229  	if s.ETHAddress == nil {
   230  		return &SignerETHAddress{}
   231  	}
   232  	return &SignerETHAddress{
   233  		ETHAddress: s.ETHAddress,
   234  	}
   235  }
   236  
   237  func (s SignerETHAddress) IsEmpty() bool {
   238  	if s.ETHAddress == nil {
   239  		return true
   240  	}
   241  	return s.ETHAddress.Address == ""
   242  }
   243  
   244  func (s SignerETHAddress) AsHex(prepend bool) (signer, error) {
   245  	if s.ETHAddress == nil {
   246  		return nil, errors.ErrSignerIsEmpty
   247  	}
   248  
   249  	if s.ETHAddress.Address == "" {
   250  		return nil, errors.ErrSignerIsEmpty
   251  	}
   252  
   253  	// Check if the content is already hex encoded
   254  	if strings.HasPrefix(s.ETHAddress.Address, "0x") {
   255  		return &s, nil
   256  	}
   257  
   258  	validHex, _ := isHex(s.ETHAddress.Address)
   259  	if validHex {
   260  		if prepend {
   261  			s.ETHAddress.Address = fmt.Sprintf("0x%s", s.ETHAddress.Address)
   262  		}
   263  		return &s, nil
   264  	}
   265  
   266  	s.ETHAddress.Address = fmt.Sprintf("0x%s", hex.EncodeToString([]byte(s.ETHAddress.Address)))
   267  	return &s, nil
   268  }
   269  
   270  func (s SignerETHAddress) AsString() (signer, error) {
   271  	if s.ETHAddress == nil {
   272  		return nil, errors.ErrSignerIsEmpty
   273  	}
   274  
   275  	// Check if the content is hex encoded
   276  	st := strings.TrimPrefix(s.ETHAddress.Address, "0x")
   277  	validHex, _ := isHex(st)
   278  	if validHex {
   279  		decoded, err := hex.DecodeString(st)
   280  		if err != nil {
   281  			return &s, fmt.Errorf("error decoding signer: %v", err)
   282  		}
   283  
   284  		s.ETHAddress.Address = string(decoded)
   285  	}
   286  	return &s, nil
   287  }
   288  
   289  func (s SignerETHAddress) Serialize() []byte {
   290  	c := strings.TrimPrefix(s.ETHAddress.Address, "0x")
   291  	return append([]byte{byte(ETHAddressPrepend)}, []byte(c)...)
   292  }
   293  
   294  func DeserializeETHAddress(data []byte) *SignerETHAddress {
   295  	return &SignerETHAddress{
   296  		ETHAddress: &ETHAddress{
   297  			Address: "0x" + string(data),
   298  		},
   299  	}
   300  }
   301  
   302  func ETHAddressFromProto(s *datapb.Signer_EthAddress) *SignerETHAddress {
   303  	var ethAddress *ETHAddress
   304  	if s != nil {
   305  		if s.EthAddress != nil {
   306  			ethAddress = &ETHAddress{
   307  				Address: s.EthAddress.Address,
   308  			}
   309  		}
   310  	}
   311  
   312  	return &SignerETHAddress{
   313  		ETHAddress: ethAddress,
   314  	}
   315  }
   316  
   317  type SignerType int
   318  
   319  const (
   320  	SignerTypeUnspecified SignerType = iota
   321  	SignerTypePubKey
   322  	SignerTypeEthAddress
   323  )
   324  
   325  type Signer struct {
   326  	Signer signer
   327  }
   328  
   329  func (s Signer) oneOfProto() interface{} {
   330  	return s.IntoProto()
   331  }
   332  
   333  // IntoProto will always return a `datapb.Signer` that needs to be checked
   334  // if it has any content afterwards.
   335  func (s Signer) IntoProto() *datapb.Signer {
   336  	signer := &datapb.Signer{}
   337  	if s.Signer != nil {
   338  		sig := s.Signer.oneOfProto()
   339  
   340  		switch tp := sig.(type) {
   341  		case *datapb.Signer_PubKey:
   342  			signer.Signer = tp
   343  		case *datapb.Signer_EthAddress:
   344  			signer.Signer = tp
   345  		}
   346  	}
   347  
   348  	return signer
   349  }
   350  
   351  func (s Signer) DeepClone() *Signer {
   352  	cpy := s
   353  	cpy.Signer = s.Signer.DeepClone()
   354  	return &cpy
   355  }
   356  
   357  func (s Signer) String() string {
   358  	return stringer.ObjToString(s.Signer)
   359  }
   360  
   361  func (s Signer) IsEmpty() bool {
   362  	if s.Signer != nil {
   363  		return s.Signer.IsEmpty()
   364  	}
   365  	return true
   366  }
   367  
   368  func (s Signer) GetSignerPubKey() *PubKey {
   369  	if s.Signer != nil {
   370  		switch t := s.Signer.(type) {
   371  		case *SignerPubKey:
   372  			return t.PubKey
   373  		}
   374  	}
   375  	return nil
   376  }
   377  
   378  func (s Signer) GetSignerETHAddress() *ETHAddress {
   379  	if s.Signer != nil {
   380  		switch t := s.Signer.(type) {
   381  		case *SignerETHAddress:
   382  			return t.ETHAddress
   383  		}
   384  	}
   385  	return nil
   386  }
   387  
   388  func (s Signer) GetSignerType() SignerType {
   389  	if s.Signer != nil {
   390  		switch s.Signer.(type) {
   391  		case *SignerPubKey:
   392  			return SignerTypePubKey
   393  		case *SignerETHAddress:
   394  			return SignerTypeEthAddress
   395  		}
   396  	}
   397  
   398  	return SignerTypeUnspecified
   399  }
   400  
   401  func SignerFromProto(s *datapb.Signer) *Signer {
   402  	signer := &Signer{}
   403  
   404  	if s.Signer != nil {
   405  		switch t := s.Signer.(type) {
   406  		case *datapb.Signer_PubKey:
   407  			signer.Signer = PubKeyFromProto(t)
   408  		case *datapb.Signer_EthAddress:
   409  			signer.Signer = ETHAddressFromProto(t)
   410  		}
   411  	}
   412  
   413  	return signer
   414  }
   415  
   416  func CreateSignerFromString(s string, t SignerType) *Signer {
   417  	signer := &Signer{}
   418  	switch t {
   419  	case SignerTypePubKey:
   420  		signer.Signer = &SignerPubKey{PubKey: &PubKey{s}}
   421  	case SignerTypeEthAddress:
   422  		signer.Signer = &SignerETHAddress{ETHAddress: &ETHAddress{s}}
   423  	}
   424  
   425  	return signer
   426  }
   427  
   428  // SignersIntoProto returns a list of signers after checking the list length.
   429  func SignersIntoProto(s []*Signer) []*datapb.Signer {
   430  	protoSigners := []*datapb.Signer{}
   431  	if len(s) > 0 {
   432  		protoSigners = make([]*datapb.Signer, len(s))
   433  		for i, signer := range s {
   434  			if signer != nil {
   435  				sign := signer.oneOfProto()
   436  				protoSigners[i] = sign.(*datapb.Signer)
   437  			}
   438  		}
   439  	}
   440  
   441  	return protoSigners
   442  }
   443  
   444  func SignersToStringList(s []*Signer) []string {
   445  	var signers []string
   446  
   447  	if len(s) > 0 {
   448  		for _, signer := range s {
   449  			if signer != nil {
   450  				signers = append(signers, signer.String())
   451  			}
   452  		}
   453  		return signers
   454  	}
   455  	return signers
   456  }
   457  
   458  // SignersFromProto returns a list of signers.
   459  // The list is allowed to be empty.
   460  func SignersFromProto(s []*datapb.Signer) []*Signer {
   461  	signers := []*Signer{}
   462  	if len(s) > 0 {
   463  		signers = make([]*Signer, len(s))
   464  		for i, signer := range s {
   465  			if s != nil {
   466  				signers[i] = SignerFromProto(signer)
   467  			}
   468  		}
   469  		return signers
   470  	}
   471  	return signers
   472  }
   473  
   474  // Encoding and decoding options
   475  
   476  const (
   477  	SignerPubKeyPrepend = 0x00
   478  	ETHAddressPrepend   = 0x01
   479  )
   480  
   481  // SignerAsHex represents the signer as a hex encoded string.
   482  // We export this function as a standalone option because there are cases when we are not sure
   483  // what is the signer type we deal with.
   484  func SignerAsHex(signer *Signer) (*Signer, error) {
   485  	switch signer.GetSignerType() {
   486  	case SignerTypePubKey:
   487  		if signer.Signer != nil {
   488  			s, err := signer.Signer.(*SignerPubKey).AsHex(false)
   489  			return &Signer{s}, err
   490  		}
   491  		return nil, errors.ErrSignerIsEmpty
   492  
   493  	case SignerTypeEthAddress:
   494  		if signer.Signer != nil {
   495  			s, err := signer.Signer.(*SignerETHAddress).AsHex(false)
   496  			return &Signer{s}, err
   497  		}
   498  		return nil, errors.ErrSignerIsEmpty
   499  	}
   500  
   501  	// If the signer type is not among the ones we know, we do not care to
   502  	// encode or decode it.
   503  	return nil, errors.ErrSignerUnknownType
   504  }
   505  
   506  // SignerAsString represents the Signer content as a string.
   507  func SignerAsString(signer *Signer) (*Signer, error) {
   508  	switch signer.GetSignerType() {
   509  	case SignerTypePubKey:
   510  		if signer.Signer != nil {
   511  			s, err := signer.Signer.(*SignerPubKey).AsString()
   512  
   513  			return &Signer{s}, err
   514  		}
   515  		return nil, errors.ErrSignerIsEmpty
   516  
   517  	case SignerTypeEthAddress:
   518  		if signer.Signer != nil {
   519  			s, err := signer.Signer.(*SignerETHAddress).AsString()
   520  			return &Signer{s}, err
   521  		}
   522  		return nil, errors.ErrSignerIsEmpty
   523  	}
   524  
   525  	// If the signer type is not among the ones we know, we do not care to
   526  	// encode or decode it.
   527  	return nil, errors.ErrSignerUnknownType
   528  }
   529  
   530  func isHex(src string) (bool, error) {
   531  	dst := make([]byte, hex.DecodedLen(len(src)))
   532  	if _, err := hex.Decode(dst, []byte(src)); err != nil {
   533  		return false, fmt.Errorf("string is not a valid hex: %v", err)
   534  	}
   535  
   536  	return true, nil
   537  }
   538  
   539  // Serialization and deserialization
   540  
   541  // SerializeSigner deserializes the signer to a byte slice - we use that
   542  // type top insert it into the database.
   543  // The deserialization prepends the slice with two bytes as signer type indicator -
   544  // that is used when the Signer is serialized back.
   545  func (s *Signer) Serialize() ([]byte, error) {
   546  	switch s.GetSignerType() {
   547  	case SignerTypePubKey:
   548  		if s.Signer != nil {
   549  			pk, _ := s.Signer.(*SignerPubKey)
   550  			if pk.PubKey != nil {
   551  				return pk.Serialize(), nil
   552  			}
   553  		}
   554  		return nil, errors.ErrSignerIsEmpty
   555  
   556  	case SignerTypeEthAddress:
   557  		if s.Signer != nil {
   558  			ea, _ := s.Signer.(*SignerETHAddress)
   559  			if ea.ETHAddress != nil {
   560  				return ea.Serialize(), nil
   561  			}
   562  		}
   563  		return nil, errors.ErrSignerIsEmpty
   564  	}
   565  
   566  	// If the signer type is not among the ones we know, we do not care to
   567  	// encode or decode it.
   568  	return nil, errors.ErrSignerUnknownType
   569  }
   570  
   571  func DeserializeSigner(content []byte) *Signer {
   572  	if len(content) > 0 {
   573  		switch content[0] {
   574  		case SignerPubKeyPrepend:
   575  			return &Signer{
   576  				Signer: DeserializePubKey(content[1:]),
   577  			}
   578  
   579  		case ETHAddressPrepend:
   580  			return &Signer{
   581  				Signer: DeserializeETHAddress(content[1:]),
   582  			}
   583  		}
   584  	}
   585  	// If the signer type is not among the ones we know, we do not care to
   586  	// encode or decode it.
   587  	return &Signer{Signer: nil}
   588  }
   589  
   590  func NewSigner(t SignerType) *Signer {
   591  	switch t {
   592  	case SignerTypePubKey:
   593  		return &Signer{
   594  			Signer: &SignerPubKey{},
   595  		}
   596  
   597  	case SignerTypeEthAddress:
   598  		return &Signer{
   599  			Signer: &SignerETHAddress{},
   600  		}
   601  	}
   602  	// No indication if the given type is unknown.
   603  	return nil
   604  }
   605  
   606  type SpecSigners []*Signer
   607  
   608  func (s SpecSigners) String() string {
   609  	allSigners := []string{}
   610  	for _, signer := range s {
   611  		allSigners = append(allSigners, signer.String())
   612  	}
   613  	return "[" + strings.Join(allSigners, ", ") + "]"
   614  }