github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/types/metadataV10.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  	ghash "github.com/stafiprotocol/go-substrate-rpc-client/hash"
    26  	"github.com/stafiprotocol/go-substrate-rpc-client/pkg/scale"
    27  	"github.com/stafiprotocol/go-substrate-rpc-client/xxhash"
    28  )
    29  
    30  // Modelled after packages/types/src/Metadata/v10/Metadata.ts
    31  type MetadataV10 struct {
    32  	Modules []ModuleMetadataV10
    33  }
    34  
    35  func (m *MetadataV10) 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 MetadataV10) 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 *MetadataV10) 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 *MetadataV10) 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.Name, mod.Events[eventID[1]].Name, nil
    86  	}
    87  	return "", "", fmt.Errorf("module index %v out of range", eventID[0])
    88  }
    89  
    90  func (m *MetadataV10) FindConstantValue(module Text, constant Text) ([]byte, error) {
    91  	for _, mod := range m.Modules {
    92  		if mod.Name == module {
    93  			for _, cons := range mod.Constants {
    94  				if cons.Name == constant {
    95  					return cons.Value, nil
    96  				}
    97  			}
    98  		}
    99  	}
   100  	return nil, fmt.Errorf("could not find constant %s.%s", module, constant)
   101  }
   102  
   103  func (m *MetadataV10) FindStorageEntryMetadata(module string, fn string) (StorageEntryMetadata, error) {
   104  	for _, mod := range m.Modules {
   105  		if !mod.HasStorage {
   106  			continue
   107  		}
   108  		if string(mod.Storage.Prefix) != module {
   109  			continue
   110  		}
   111  		for _, s := range mod.Storage.Items {
   112  			if string(s.Name) != fn {
   113  				continue
   114  			}
   115  			return s, nil
   116  		}
   117  		return nil, fmt.Errorf("storage %v not found within module %v", fn, module)
   118  	}
   119  	return nil, fmt.Errorf("module %v not found in metadata", module)
   120  }
   121  
   122  func (m *MetadataV10) ExistsModuleMetadata(module string) bool {
   123  	for _, mod := range m.Modules {
   124  		if string(mod.Name) == module {
   125  			return true
   126  		}
   127  	}
   128  	return false
   129  }
   130  
   131  func (m MetadataV10) GetConst(prefix, name string, res interface{}) error {
   132  	for _, mod := range m.Modules {
   133  		if string(mod.Name) == prefix {
   134  			for _, cons := range mod.Constants {
   135  				if string(cons.Name) == name {
   136  					return DecodeFromBytes(cons.Value, res)
   137  				}
   138  			}
   139  		}
   140  	}
   141  	return fmt.Errorf("could not find constant %s.%s", prefix, name)
   142  }
   143  
   144  type ModuleMetadataV10 struct {
   145  	Name       Text
   146  	HasStorage bool
   147  	Storage    StorageMetadataV10
   148  	HasCalls   bool
   149  	Calls      []FunctionMetadataV4
   150  	HasEvents  bool
   151  	Events     []EventMetadataV4
   152  	Constants  []ModuleConstantMetadataV6
   153  	Errors     []ErrorMetadataV8
   154  }
   155  
   156  func (m *ModuleMetadataV10) Decode(decoder scale.Decoder) error {
   157  	err := decoder.Decode(&m.Name)
   158  	if err != nil {
   159  		return err
   160  	}
   161  
   162  	err = decoder.Decode(&m.HasStorage)
   163  	if err != nil {
   164  		return err
   165  	}
   166  
   167  	if m.HasStorage {
   168  		err = decoder.Decode(&m.Storage)
   169  		if err != nil {
   170  			return err
   171  		}
   172  	}
   173  
   174  	err = decoder.Decode(&m.HasCalls)
   175  	if err != nil {
   176  		return err
   177  	}
   178  
   179  	if m.HasCalls {
   180  		err = decoder.Decode(&m.Calls)
   181  		if err != nil {
   182  			return err
   183  		}
   184  	}
   185  
   186  	err = decoder.Decode(&m.HasEvents)
   187  	if err != nil {
   188  		return err
   189  	}
   190  
   191  	if m.HasEvents {
   192  		err = decoder.Decode(&m.Events)
   193  		if err != nil {
   194  			return err
   195  		}
   196  	}
   197  
   198  	err = decoder.Decode(&m.Constants)
   199  	if err != nil {
   200  		return err
   201  	}
   202  
   203  	return decoder.Decode(&m.Errors)
   204  }
   205  
   206  func (m ModuleMetadataV10) Encode(encoder scale.Encoder) error {
   207  	err := encoder.Encode(m.Name)
   208  	if err != nil {
   209  		return err
   210  	}
   211  
   212  	err = encoder.Encode(m.HasStorage)
   213  	if err != nil {
   214  		return err
   215  	}
   216  
   217  	if m.HasStorage {
   218  		err = encoder.Encode(m.Storage)
   219  		if err != nil {
   220  			return err
   221  		}
   222  	}
   223  
   224  	err = encoder.Encode(m.HasCalls)
   225  	if err != nil {
   226  		return err
   227  	}
   228  
   229  	if m.HasCalls {
   230  		err = encoder.Encode(m.Calls)
   231  		if err != nil {
   232  			return err
   233  		}
   234  	}
   235  
   236  	err = encoder.Encode(m.HasEvents)
   237  	if err != nil {
   238  		return err
   239  	}
   240  
   241  	if m.HasEvents {
   242  		err = encoder.Encode(m.Events)
   243  		if err != nil {
   244  			return err
   245  		}
   246  	}
   247  
   248  	err = encoder.Encode(m.Constants)
   249  	if err != nil {
   250  		return err
   251  	}
   252  
   253  	return encoder.Encode(m.Errors)
   254  }
   255  
   256  type StorageMetadataV10 struct {
   257  	Prefix Text
   258  	Items  []StorageFunctionMetadataV10
   259  }
   260  
   261  type StorageFunctionMetadataV10 struct {
   262  	Name          Text
   263  	Modifier      StorageFunctionModifierV0
   264  	Type          StorageFunctionTypeV10
   265  	Fallback      Bytes
   266  	Documentation []Text
   267  }
   268  
   269  func (s StorageFunctionMetadataV10) IsPlain() bool {
   270  	return s.Type.IsType
   271  }
   272  
   273  func (s StorageFunctionMetadataV10) IsMap() bool {
   274  	return s.Type.IsMap
   275  }
   276  
   277  func (s StorageFunctionMetadataV10) IsDoubleMap() bool {
   278  	return s.Type.IsDoubleMap
   279  }
   280  
   281  func (s StorageFunctionMetadataV10) IsNMap() bool {
   282  	return false
   283  }
   284  
   285  func (s StorageFunctionMetadataV10) Hashers() ([]hash.Hash, error) {
   286  	return nil, fmt.Errorf("Hashers is not supported for metadata v10, please upgrade to use metadata v13 or newer")
   287  }
   288  
   289  func (s StorageFunctionMetadataV10) Hasher() (hash.Hash, error) {
   290  	if s.Type.IsMap {
   291  		return s.Type.AsMap.Hasher.HashFunc()
   292  	}
   293  	if s.Type.IsDoubleMap {
   294  		return s.Type.AsDoubleMap.Hasher.HashFunc()
   295  	}
   296  	return xxhash.New128(nil), nil
   297  }
   298  
   299  func (s StorageFunctionMetadataV10) Hasher2() (hash.Hash, error) {
   300  	if !s.Type.IsDoubleMap {
   301  		return nil, fmt.Errorf("only DoubleMaps have a Hasher2")
   302  	}
   303  	return s.Type.AsDoubleMap.Key2Hasher.HashFunc()
   304  }
   305  
   306  type StorageFunctionTypeV10 struct {
   307  	IsType      bool
   308  	AsType      Type // 0
   309  	IsMap       bool
   310  	AsMap       MapTypeV10 // 1
   311  	IsDoubleMap bool
   312  	AsDoubleMap DoubleMapTypeV10 // 2
   313  }
   314  
   315  func (s *StorageFunctionTypeV10) Decode(decoder scale.Decoder) error {
   316  	var t uint8
   317  	err := decoder.Decode(&t)
   318  	if err != nil {
   319  		return err
   320  	}
   321  
   322  	switch t {
   323  	case 0:
   324  		s.IsType = true
   325  		err = decoder.Decode(&s.AsType)
   326  		if err != nil {
   327  			return err
   328  		}
   329  	case 1:
   330  		s.IsMap = true
   331  		err = decoder.Decode(&s.AsMap)
   332  		if err != nil {
   333  			return err
   334  		}
   335  	case 2:
   336  		s.IsDoubleMap = true
   337  		err = decoder.Decode(&s.AsDoubleMap)
   338  		if err != nil {
   339  			return err
   340  		}
   341  	default:
   342  		return fmt.Errorf("received unexpected type %v", t)
   343  	}
   344  	return nil
   345  }
   346  
   347  func (s StorageFunctionTypeV10) Encode(encoder scale.Encoder) error {
   348  	switch {
   349  	case s.IsType:
   350  		err := encoder.PushByte(0)
   351  		if err != nil {
   352  			return err
   353  		}
   354  		err = encoder.Encode(s.AsType)
   355  		if err != nil {
   356  			return err
   357  		}
   358  	case s.IsMap:
   359  		err := encoder.PushByte(1)
   360  		if err != nil {
   361  			return err
   362  		}
   363  		err = encoder.Encode(s.AsMap)
   364  		if err != nil {
   365  			return err
   366  		}
   367  	case s.IsDoubleMap:
   368  		err := encoder.PushByte(2)
   369  		if err != nil {
   370  			return err
   371  		}
   372  		err = encoder.Encode(s.AsDoubleMap)
   373  		if err != nil {
   374  			return err
   375  		}
   376  	default:
   377  		return fmt.Errorf("expected to be either type, map or double map, but none was set: %v", s)
   378  	}
   379  	return nil
   380  }
   381  
   382  type MapTypeV10 struct {
   383  	Hasher StorageHasherV10
   384  	Key    Type
   385  	Value  Type
   386  	Linked bool
   387  }
   388  
   389  type DoubleMapTypeV10 struct {
   390  	Hasher     StorageHasherV10
   391  	Key1       Type
   392  	Key2       Type
   393  	Value      Type
   394  	Key2Hasher StorageHasherV10
   395  }
   396  
   397  type StorageHasherV10 struct {
   398  	IsBlake2_128       bool // 0
   399  	IsBlake2_256       bool // 1
   400  	IsBlake2_128Concat bool // 2
   401  	IsTwox128          bool // 3
   402  	IsTwox256          bool // 4
   403  	IsTwox64Concat     bool // 5
   404  	IsIdentity         bool // 6
   405  }
   406  
   407  func (s *StorageHasherV10) Decode(decoder scale.Decoder) error {
   408  	var t uint8
   409  	err := decoder.Decode(&t)
   410  	if err != nil {
   411  		return err
   412  	}
   413  
   414  	switch t {
   415  	case 0:
   416  		s.IsBlake2_128 = true
   417  	case 1:
   418  		s.IsBlake2_256 = true
   419  	case 2:
   420  		s.IsBlake2_128Concat = true
   421  	case 3:
   422  		s.IsTwox128 = true
   423  	case 4:
   424  		s.IsTwox256 = true
   425  	case 5:
   426  		s.IsTwox64Concat = true
   427  	case 6:
   428  		s.IsIdentity = true
   429  	default:
   430  		return fmt.Errorf("received unexpected storage hasher type %v", t)
   431  	}
   432  	return nil
   433  }
   434  
   435  func (s StorageHasherV10) Encode(encoder scale.Encoder) error {
   436  	var t uint8
   437  	switch {
   438  	case s.IsBlake2_128:
   439  		t = 0
   440  	case s.IsBlake2_256:
   441  		t = 1
   442  	case s.IsBlake2_128Concat:
   443  		t = 2
   444  	case s.IsTwox128:
   445  		t = 3
   446  	case s.IsTwox256:
   447  		t = 4
   448  	case s.IsTwox64Concat:
   449  		t = 5
   450  	case s.IsIdentity:
   451  		t = 6
   452  	default:
   453  		return fmt.Errorf("expected storage hasher, but none was set: %v", s)
   454  	}
   455  	return encoder.PushByte(t)
   456  }
   457  
   458  func (s StorageHasherV10) HashFunc() (hash.Hash, error) {
   459  	// Blake2_128
   460  	if s.IsBlake2_128 {
   461  		return ghash.NewBlake2b128(nil)
   462  	}
   463  
   464  	// Blake2_256
   465  	if s.IsBlake2_256 {
   466  		return ghash.NewBlake2b256(nil)
   467  	}
   468  
   469  	// Blake2_128Concat
   470  	if s.IsBlake2_128Concat {
   471  		return ghash.NewBlake2b128Concat(nil)
   472  	}
   473  
   474  	// Twox128
   475  	if s.IsTwox128 {
   476  		return xxhash.New128(nil), nil
   477  	}
   478  
   479  	// Twox256
   480  	if s.IsTwox256 {
   481  		return xxhash.New256(nil), nil
   482  	}
   483  
   484  	// Twox64Concat
   485  	if s.IsTwox64Concat {
   486  		return xxhash.New64Concat(nil), nil
   487  	}
   488  
   489  	// Identity
   490  	if s.IsIdentity {
   491  		return ghash.NewIdentity(nil), nil
   492  	}
   493  
   494  	return nil, errors.New("hash function type not yet supported")
   495  }