github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/types/metadataV4.go (about)

     1  // Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls
     2  //
     3  // Copyright 2020 Stafi Protocol
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package types
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"hash"
    23  	"strings"
    24  
    25  	"github.com/stafiprotocol/go-substrate-rpc-client/pkg/scale"
    26  	"github.com/stafiprotocol/go-substrate-rpc-client/xxhash"
    27  	"golang.org/x/crypto/blake2b"
    28  )
    29  
    30  // Modelled after https://github.com/paritytech/substrate/blob/v1.0.0rc2/srml/metadata/src/lib.rs
    31  type MetadataV4 struct {
    32  	Modules []ModuleMetadataV4
    33  }
    34  
    35  func (m *MetadataV4) Decode(decoder scale.Decoder) error {
    36  	err := decoder.Decode(&m.Modules)
    37  	if err != nil {
    38  		return err
    39  	}
    40  	return nil
    41  }
    42  
    43  func (m MetadataV4) Encode(encoder scale.Encoder) error {
    44  	err := encoder.Encode(m.Modules)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	return nil
    49  }
    50  
    51  func (m *MetadataV4) FindCallIndex(call string) (CallIndex, error) {
    52  	s := strings.Split(call, ".")
    53  	mi := uint8(0)
    54  	for _, mod := range m.Modules {
    55  		if !mod.HasCalls {
    56  			continue
    57  		}
    58  		if string(mod.Name) != s[0] {
    59  			mi++
    60  			continue
    61  		}
    62  		for ci, f := range mod.Calls {
    63  			if string(f.Name) == s[1] {
    64  				return CallIndex{mi, uint8(ci)}, nil
    65  			}
    66  		}
    67  		return CallIndex{}, fmt.Errorf("method %v not found within module %v for call %v", s[1], mod.Name, call)
    68  	}
    69  	return CallIndex{}, fmt.Errorf("module %v not found in metadata for call %v", s[0], call)
    70  }
    71  
    72  func (m *MetadataV4) FindEventNamesForEventID(eventID EventID) (Text, Text, error) {
    73  	mi := uint8(0)
    74  	for _, mod := range m.Modules {
    75  		if !mod.HasEvents {
    76  			continue
    77  		}
    78  		if mi != eventID[0] {
    79  			mi++
    80  			continue
    81  		}
    82  		if int(eventID[1]) >= len(mod.Events) {
    83  			return "", "", fmt.Errorf("event index %v for module %v out of range", eventID[1], mod.Name)
    84  		}
    85  		return mod.Prefix, mod.Events[eventID[1]].Name, nil
    86  	}
    87  	return "", "", fmt.Errorf("module index %v out of range", eventID[0])
    88  }
    89  
    90  func (m *MetadataV4) FindConstantValue(_module Text, _constant Text) ([]byte, error) {
    91  	return nil, fmt.Errorf("constants are only supported from metadata v6 and up")
    92  }
    93  
    94  func (m *MetadataV4) FindStorageEntryMetadata(module string, fn string) (StorageEntryMetadata, error) {
    95  	for _, mod := range m.Modules {
    96  		if !mod.HasStorage {
    97  			continue
    98  		}
    99  		if string(mod.Prefix) != module {
   100  			continue
   101  		}
   102  		for _, s := range mod.Storage {
   103  			if string(s.Name) != fn {
   104  				continue
   105  			}
   106  			return s, nil
   107  		}
   108  		return nil, fmt.Errorf("storage %v not found within module %v", fn, module)
   109  	}
   110  	return nil, fmt.Errorf("module %v not found in metadata", module)
   111  }
   112  
   113  func (m *MetadataV4) ExistsModuleMetadata(module string) bool {
   114  	for _, mod := range m.Modules {
   115  		if string(mod.Prefix) == module {
   116  			return true
   117  		}
   118  	}
   119  	return false
   120  }
   121  
   122  type StorageEntryMetadata interface {
   123  	IsPlain() bool
   124  	IsMap() bool
   125  	IsDoubleMap() bool
   126  	IsNMap() bool
   127  	Hasher() (hash.Hash, error)
   128  	Hasher2() (hash.Hash, error)
   129  	Hashers() ([]hash.Hash, error)
   130  }
   131  
   132  type ModuleMetadataV4 struct {
   133  	Name       Text
   134  	Prefix     Text
   135  	HasStorage bool
   136  	Storage    []StorageFunctionMetadataV4
   137  	HasCalls   bool
   138  	Calls      []FunctionMetadataV4
   139  	HasEvents  bool
   140  	Events     []EventMetadataV4
   141  }
   142  
   143  func (m *ModuleMetadataV4) Decode(decoder scale.Decoder) error {
   144  	err := decoder.Decode(&m.Name)
   145  	if err != nil {
   146  		return err
   147  	}
   148  
   149  	err = decoder.Decode(&m.Prefix)
   150  	if err != nil {
   151  		return err
   152  	}
   153  
   154  	err = decoder.Decode(&m.HasStorage)
   155  	if err != nil {
   156  		return err
   157  	}
   158  
   159  	if m.HasStorage {
   160  		err = decoder.Decode(&m.Storage)
   161  		if err != nil {
   162  			return err
   163  		}
   164  	}
   165  
   166  	err = decoder.Decode(&m.HasCalls)
   167  	if err != nil {
   168  		return err
   169  	}
   170  
   171  	if m.HasCalls {
   172  		err = decoder.Decode(&m.Calls)
   173  		if err != nil {
   174  			return err
   175  		}
   176  	}
   177  
   178  	err = decoder.Decode(&m.HasEvents)
   179  	if err != nil {
   180  		return err
   181  	}
   182  
   183  	if m.HasEvents {
   184  		err = decoder.Decode(&m.Events)
   185  		if err != nil {
   186  			return err
   187  		}
   188  	}
   189  	return nil
   190  }
   191  
   192  func (m ModuleMetadataV4) Encode(encoder scale.Encoder) error {
   193  	err := encoder.Encode(m.Name)
   194  	if err != nil {
   195  		return err
   196  	}
   197  
   198  	err = encoder.Encode(m.Prefix)
   199  	if err != nil {
   200  		return err
   201  	}
   202  
   203  	err = encoder.Encode(m.HasStorage)
   204  	if err != nil {
   205  		return err
   206  	}
   207  
   208  	if m.HasStorage {
   209  		err = encoder.Encode(m.Storage)
   210  		if err != nil {
   211  			return err
   212  		}
   213  	}
   214  
   215  	err = encoder.Encode(m.HasCalls)
   216  	if err != nil {
   217  		return err
   218  	}
   219  
   220  	if m.HasCalls {
   221  		err = encoder.Encode(m.Calls)
   222  		if err != nil {
   223  			return err
   224  		}
   225  	}
   226  
   227  	err = encoder.Encode(m.HasEvents)
   228  	if err != nil {
   229  		return err
   230  	}
   231  
   232  	if m.HasEvents {
   233  		err = encoder.Encode(m.Events)
   234  		if err != nil {
   235  			return err
   236  		}
   237  	}
   238  	return nil
   239  }
   240  
   241  type StorageFunctionMetadataV4 struct {
   242  	Name          Text
   243  	Modifier      StorageFunctionModifierV0
   244  	Type          StorageFunctionTypeV4
   245  	Fallback      Bytes
   246  	Documentation []Text
   247  }
   248  
   249  func (s StorageFunctionMetadataV4) IsPlain() bool {
   250  	return s.Type.IsType
   251  }
   252  
   253  func (s StorageFunctionMetadataV4) IsMap() bool {
   254  	return s.Type.IsMap
   255  }
   256  
   257  func (s StorageFunctionMetadataV4) IsDoubleMap() bool {
   258  	return s.Type.IsDoubleMap
   259  }
   260  
   261  func (s StorageFunctionMetadataV4) IsNMap() bool {
   262  	return false
   263  }
   264  
   265  func (s StorageFunctionMetadataV4) Hashers() ([]hash.Hash, error) {
   266  	return nil, fmt.Errorf("Hashers is not supported for metadata v4, please upgrade to use metadata v13 or newer")
   267  }
   268  
   269  func (s StorageFunctionMetadataV4) Hasher() (hash.Hash, error) {
   270  	if s.Type.IsMap {
   271  		return s.Type.AsMap.Hasher.HashFunc()
   272  	}
   273  	if s.Type.IsDoubleMap {
   274  		return s.Type.AsDoubleMap.Hasher.HashFunc()
   275  	}
   276  	return xxhash.New128(nil), nil
   277  }
   278  
   279  func (s StorageFunctionMetadataV4) Hasher2() (hash.Hash, error) {
   280  	return nil, fmt.Errorf("Hasher2 is not supported for metadata v4, please upgrade to use metadata v8 or newer")
   281  }
   282  
   283  type StorageFunctionTypeV4 struct {
   284  	IsType      bool
   285  	AsType      Type // 0
   286  	IsMap       bool
   287  	AsMap       MapTypeV4 // 1
   288  	IsDoubleMap bool
   289  	AsDoubleMap DoubleMapTypeV4 // 2
   290  }
   291  
   292  func (s *StorageFunctionTypeV4) Decode(decoder scale.Decoder) error {
   293  	var t uint8
   294  	err := decoder.Decode(&t)
   295  	if err != nil {
   296  		return err
   297  	}
   298  
   299  	switch t {
   300  	case 0:
   301  		s.IsType = true
   302  		err = decoder.Decode(&s.AsType)
   303  		if err != nil {
   304  			return err
   305  		}
   306  	case 1:
   307  		s.IsMap = true
   308  		err = decoder.Decode(&s.AsMap)
   309  		if err != nil {
   310  			return err
   311  		}
   312  	case 2:
   313  		s.IsDoubleMap = true
   314  		err = decoder.Decode(&s.AsDoubleMap)
   315  		if err != nil {
   316  			return err
   317  		}
   318  	default:
   319  		return fmt.Errorf("received unexpected type %v", t)
   320  	}
   321  	return nil
   322  }
   323  
   324  func (s StorageFunctionTypeV4) Encode(encoder scale.Encoder) error {
   325  	switch {
   326  	case s.IsType:
   327  		err := encoder.PushByte(0)
   328  		if err != nil {
   329  			return err
   330  		}
   331  		err = encoder.Encode(s.AsType)
   332  		if err != nil {
   333  			return err
   334  		}
   335  	case s.IsMap:
   336  		err := encoder.PushByte(1)
   337  		if err != nil {
   338  			return err
   339  		}
   340  		err = encoder.Encode(s.AsMap)
   341  		if err != nil {
   342  			return err
   343  		}
   344  	case s.IsDoubleMap:
   345  		err := encoder.PushByte(2)
   346  		if err != nil {
   347  			return err
   348  		}
   349  		err = encoder.Encode(s.AsDoubleMap)
   350  		if err != nil {
   351  			return err
   352  		}
   353  	default:
   354  		return fmt.Errorf("expected to be either type, map or double map, but none was set: %v", s)
   355  	}
   356  	return nil
   357  }
   358  
   359  type DoubleMapTypeV4 struct {
   360  	Hasher     StorageHasher
   361  	Key1       Type
   362  	Key2       Type
   363  	Value      Type
   364  	Key2Hasher Text
   365  }
   366  
   367  type MapTypeV4 struct {
   368  	Hasher StorageHasher
   369  	Key    Type
   370  	Value  Type
   371  	Linked bool
   372  }
   373  
   374  type StorageHasher struct {
   375  	IsBlake2_128   bool // 0
   376  	IsBlake2_256   bool // 1
   377  	IsTwox128      bool // 2
   378  	IsTwox256      bool // 3
   379  	IsTwox64Concat bool // 4
   380  }
   381  
   382  func (s *StorageHasher) Decode(decoder scale.Decoder) error {
   383  	var t uint8
   384  	err := decoder.Decode(&t)
   385  	if err != nil {
   386  		return err
   387  	}
   388  
   389  	switch t {
   390  	case 0:
   391  		s.IsBlake2_128 = true
   392  	case 1:
   393  		s.IsBlake2_256 = true
   394  	case 2:
   395  		s.IsTwox128 = true
   396  	case 3:
   397  		s.IsTwox256 = true
   398  	case 4:
   399  		s.IsTwox64Concat = true
   400  	default:
   401  		return fmt.Errorf("received unexpected storage hasher type %v", t)
   402  	}
   403  	return nil
   404  }
   405  
   406  func (s StorageHasher) Encode(encoder scale.Encoder) error {
   407  	var t uint8
   408  	switch {
   409  	case s.IsBlake2_128:
   410  		t = 0
   411  	case s.IsBlake2_256:
   412  		t = 1
   413  	case s.IsTwox128:
   414  		t = 2
   415  	case s.IsTwox256:
   416  		t = 3
   417  	case s.IsTwox64Concat:
   418  		t = 4
   419  	default:
   420  		return fmt.Errorf("expected storage hasher, but none was set: %v", s)
   421  	}
   422  	return encoder.PushByte(t)
   423  }
   424  
   425  type FunctionMetadataV4 struct {
   426  	Name          Text
   427  	Args          []FunctionArgumentMetadata
   428  	Documentation []Text
   429  }
   430  
   431  type EventMetadataV4 struct {
   432  	Name          Text
   433  	Args          []Type
   434  	Documentation []Text
   435  }
   436  
   437  func (s StorageHasher) HashFunc() (hash.Hash, error) {
   438  	// Blake2_128
   439  	if s.IsBlake2_128 {
   440  		return blake2b.New(128, nil)
   441  	}
   442  
   443  	// Blake2_256
   444  	if s.IsBlake2_256 {
   445  		return blake2b.New256(nil)
   446  	}
   447  
   448  	// Twox128
   449  	if s.IsTwox128 {
   450  		return xxhash.New128(nil), nil
   451  	}
   452  
   453  	// Twox256
   454  	if s.IsTwox256 {
   455  		return xxhash.New256(nil), nil
   456  	}
   457  
   458  	// Twox64Concat
   459  	if s.IsTwox64Concat {
   460  		return xxhash.New64Concat(nil), nil
   461  	}
   462  
   463  	return nil, errors.New("hash function type not yet supported")
   464  }
   465  
   466  type FunctionArgumentMetadata struct {
   467  	Name Text
   468  	Type Type
   469  }
   470  
   471  type StorageFunctionModifierV0 struct {
   472  	IsOptional bool // 0
   473  	IsDefault  bool // 1
   474  	IsRequired bool // 2
   475  }
   476  
   477  func (s *StorageFunctionModifierV0) Decode(decoder scale.Decoder) error {
   478  	var t uint8
   479  	err := decoder.Decode(&t)
   480  	if err != nil {
   481  		return err
   482  	}
   483  
   484  	switch t {
   485  	case 0:
   486  		s.IsOptional = true
   487  	case 1:
   488  		s.IsDefault = true
   489  	case 2:
   490  		s.IsRequired = true
   491  	default:
   492  		return fmt.Errorf("received unexpected storage function modifier type %v", t)
   493  	}
   494  	return nil
   495  }
   496  
   497  func (s StorageFunctionModifierV0) Encode(encoder scale.Encoder) error {
   498  	var t uint8
   499  	switch {
   500  	case s.IsOptional:
   501  		t = 0
   502  	case s.IsDefault:
   503  		t = 1
   504  	case s.IsRequired:
   505  		t = 2
   506  	default:
   507  		return fmt.Errorf("expected storage function modifier, but none was set: %v", s)
   508  	}
   509  	return encoder.PushByte(t)
   510  }