github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/types/metadataV7.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  	"fmt"
    21  	"hash"
    22  	"strings"
    23  
    24  	"github.com/stafiprotocol/go-substrate-rpc-client/pkg/scale"
    25  	"github.com/stafiprotocol/go-substrate-rpc-client/xxhash"
    26  )
    27  
    28  // Modelled after packages/types/src/Metadata/v7/Metadata.ts
    29  type MetadataV7 struct {
    30  	Modules []ModuleMetadataV7
    31  }
    32  
    33  func (m *MetadataV7) Decode(decoder scale.Decoder) error {
    34  	err := decoder.Decode(&m.Modules)
    35  	if err != nil {
    36  		return err
    37  	}
    38  	return nil
    39  }
    40  
    41  func (m MetadataV7) Encode(encoder scale.Encoder) error {
    42  	err := encoder.Encode(m.Modules)
    43  	if err != nil {
    44  		return err
    45  	}
    46  	return nil
    47  }
    48  
    49  func (m *MetadataV7) FindCallIndex(call string) (CallIndex, error) {
    50  	s := strings.Split(call, ".")
    51  	mi := uint8(0)
    52  	for _, mod := range m.Modules {
    53  		if !mod.HasCalls {
    54  			continue
    55  		}
    56  		if string(mod.Name) != s[0] {
    57  			mi++
    58  			continue
    59  		}
    60  		for ci, f := range mod.Calls {
    61  			if string(f.Name) == s[1] {
    62  				return CallIndex{mi, uint8(ci)}, nil
    63  			}
    64  		}
    65  		return CallIndex{}, fmt.Errorf("method %v not found within module %v for call %v", s[1], mod.Name, call)
    66  	}
    67  	return CallIndex{}, fmt.Errorf("module %v not found in metadata for call %v", s[0], call)
    68  }
    69  
    70  func (m *MetadataV7) FindEventNamesForEventID(eventID EventID) (Text, Text, error) {
    71  	mi := uint8(0)
    72  	for _, mod := range m.Modules {
    73  		if !mod.HasEvents {
    74  			continue
    75  		}
    76  		if mi != eventID[0] {
    77  			mi++
    78  			continue
    79  		}
    80  		if int(eventID[1]) >= len(mod.Events) {
    81  			return "", "", fmt.Errorf("event index %v for module %v out of range", eventID[1], mod.Name)
    82  		}
    83  		return mod.Name, mod.Events[eventID[1]].Name, nil
    84  	}
    85  	return "", "", fmt.Errorf("module index %v out of range", eventID[0])
    86  }
    87  
    88  func (m *MetadataV7) FindConstantValue(module Text, constant Text) ([]byte, error) {
    89  	for _, mod := range m.Modules {
    90  		if mod.Name == module {
    91  			for _, cons := range mod.Constants {
    92  				if cons.Name == constant {
    93  					return cons.Value, nil
    94  				}
    95  			}
    96  		}
    97  	}
    98  	return nil, fmt.Errorf("could not find constant %s.%s", module, constant)
    99  }
   100  
   101  func (m *MetadataV7) FindStorageEntryMetadata(module string, fn string) (StorageEntryMetadata, error) {
   102  	for _, mod := range m.Modules {
   103  		if !mod.HasStorage {
   104  			continue
   105  		}
   106  		if string(mod.Storage.Prefix) != module {
   107  			continue
   108  		}
   109  		for _, s := range mod.Storage.Items {
   110  			if string(s.Name) != fn {
   111  				continue
   112  			}
   113  			return s, nil
   114  		}
   115  		return nil, fmt.Errorf("storage %v not found within module %v", fn, module)
   116  	}
   117  	return nil, fmt.Errorf("module %v not found in metadata", module)
   118  }
   119  
   120  func (m *MetadataV7) ExistsModuleMetadata(module string) bool {
   121  	for _, mod := range m.Modules {
   122  		if string(mod.Name) == module {
   123  			return true
   124  		}
   125  	}
   126  	return false
   127  }
   128  
   129  type ModuleMetadataV7 struct {
   130  	Name       Text
   131  	HasStorage bool
   132  	Storage    StorageMetadata
   133  	HasCalls   bool
   134  	Calls      []FunctionMetadataV4
   135  	HasEvents  bool
   136  	Events     []EventMetadataV4
   137  	Constants  []ModuleConstantMetadataV6
   138  }
   139  
   140  func (m *ModuleMetadataV7) Decode(decoder scale.Decoder) error {
   141  	err := decoder.Decode(&m.Name)
   142  	if err != nil {
   143  		return err
   144  	}
   145  
   146  	err = decoder.Decode(&m.HasStorage)
   147  	if err != nil {
   148  		return err
   149  	}
   150  
   151  	if m.HasStorage {
   152  		err = decoder.Decode(&m.Storage)
   153  		if err != nil {
   154  			return err
   155  		}
   156  	}
   157  
   158  	err = decoder.Decode(&m.HasCalls)
   159  	if err != nil {
   160  		return err
   161  	}
   162  
   163  	if m.HasCalls {
   164  		err = decoder.Decode(&m.Calls)
   165  		if err != nil {
   166  			return err
   167  		}
   168  	}
   169  
   170  	err = decoder.Decode(&m.HasEvents)
   171  	if err != nil {
   172  		return err
   173  	}
   174  
   175  	if m.HasEvents {
   176  		err = decoder.Decode(&m.Events)
   177  		if err != nil {
   178  			return err
   179  		}
   180  	}
   181  
   182  	return decoder.Decode(&m.Constants)
   183  }
   184  
   185  func (m ModuleMetadataV7) Encode(encoder scale.Encoder) error {
   186  	err := encoder.Encode(m.Name)
   187  	if err != nil {
   188  		return err
   189  	}
   190  
   191  	err = encoder.Encode(m.HasStorage)
   192  	if err != nil {
   193  		return err
   194  	}
   195  
   196  	if m.HasStorage {
   197  		err = encoder.Encode(m.Storage)
   198  		if err != nil {
   199  			return err
   200  		}
   201  	}
   202  
   203  	err = encoder.Encode(m.HasCalls)
   204  	if err != nil {
   205  		return err
   206  	}
   207  
   208  	if m.HasCalls {
   209  		err = encoder.Encode(m.Calls)
   210  		if err != nil {
   211  			return err
   212  		}
   213  	}
   214  
   215  	err = encoder.Encode(m.HasEvents)
   216  	if err != nil {
   217  		return err
   218  	}
   219  
   220  	if m.HasEvents {
   221  		err = encoder.Encode(m.Events)
   222  		if err != nil {
   223  			return err
   224  		}
   225  	}
   226  
   227  	return encoder.Encode(m.Constants)
   228  }
   229  
   230  type StorageMetadata struct {
   231  	Prefix Text
   232  	Items  []StorageFunctionMetadataV5
   233  }
   234  
   235  type StorageFunctionMetadataV5 struct {
   236  	Name          Text
   237  	Modifier      StorageFunctionModifierV0
   238  	Type          StorageFunctionTypeV5
   239  	Fallback      Bytes
   240  	Documentation []Text
   241  }
   242  
   243  func (s StorageFunctionMetadataV5) IsPlain() bool {
   244  	return s.Type.IsType
   245  }
   246  
   247  func (s StorageFunctionMetadataV5) IsMap() bool {
   248  	return s.Type.IsMap
   249  }
   250  
   251  func (s StorageFunctionMetadataV5) IsDoubleMap() bool {
   252  	return s.Type.IsDoubleMap
   253  }
   254  
   255  func (s StorageFunctionMetadataV5) IsNMap() bool {
   256  	return false
   257  }
   258  
   259  func (s StorageFunctionMetadataV5) Hashers() ([]hash.Hash, error) {
   260  	return nil, fmt.Errorf("Hashers is not supported for metadata v5, please upgrade to use metadata v13 or newer")
   261  }
   262  
   263  func (s StorageFunctionMetadataV5) Hasher() (hash.Hash, error) {
   264  	if s.Type.IsMap {
   265  		return s.Type.AsMap.Hasher.HashFunc()
   266  	}
   267  	if s.Type.IsDoubleMap {
   268  		return s.Type.AsDoubleMap.Hasher.HashFunc()
   269  	}
   270  	return xxhash.New128(nil), nil
   271  }
   272  
   273  func (s StorageFunctionMetadataV5) Hasher2() (hash.Hash, error) {
   274  	if !s.Type.IsDoubleMap {
   275  		return nil, fmt.Errorf("only DoubleMaps have a Hasher2")
   276  	}
   277  	return s.Type.AsDoubleMap.Key2Hasher.HashFunc()
   278  }
   279  
   280  type StorageFunctionTypeV5 struct {
   281  	IsType      bool
   282  	AsType      Type // 0
   283  	IsMap       bool
   284  	AsMap       MapTypeV4 // 1
   285  	IsDoubleMap bool
   286  	AsDoubleMap DoubleMapTypeV5 // 2
   287  }
   288  
   289  func (s *StorageFunctionTypeV5) Decode(decoder scale.Decoder) error {
   290  	var t uint8
   291  	err := decoder.Decode(&t)
   292  	if err != nil {
   293  		return err
   294  	}
   295  
   296  	switch t {
   297  	case 0:
   298  		s.IsType = true
   299  		err = decoder.Decode(&s.AsType)
   300  		if err != nil {
   301  			return err
   302  		}
   303  	case 1:
   304  		s.IsMap = true
   305  		err = decoder.Decode(&s.AsMap)
   306  		if err != nil {
   307  			return err
   308  		}
   309  	case 2:
   310  		s.IsDoubleMap = true
   311  		err = decoder.Decode(&s.AsDoubleMap)
   312  		if err != nil {
   313  			return err
   314  		}
   315  	default:
   316  		return fmt.Errorf("received unexpected type %v", t)
   317  	}
   318  	return nil
   319  }
   320  
   321  func (s StorageFunctionTypeV5) Encode(encoder scale.Encoder) error {
   322  	switch {
   323  	case s.IsType:
   324  		err := encoder.PushByte(0)
   325  		if err != nil {
   326  			return err
   327  		}
   328  		err = encoder.Encode(s.AsType)
   329  		if err != nil {
   330  			return err
   331  		}
   332  	case s.IsMap:
   333  		err := encoder.PushByte(1)
   334  		if err != nil {
   335  			return err
   336  		}
   337  		err = encoder.Encode(s.AsMap)
   338  		if err != nil {
   339  			return err
   340  		}
   341  	case s.IsDoubleMap:
   342  		err := encoder.PushByte(2)
   343  		if err != nil {
   344  			return err
   345  		}
   346  		err = encoder.Encode(s.AsDoubleMap)
   347  		if err != nil {
   348  			return err
   349  		}
   350  	default:
   351  		return fmt.Errorf("expected to be either type, map or double map, but none was set: %v", s)
   352  	}
   353  	return nil
   354  }
   355  
   356  type DoubleMapTypeV5 struct {
   357  	Hasher     StorageHasher
   358  	Key1       Type
   359  	Key2       Type
   360  	Value      Type
   361  	Key2Hasher StorageHasher
   362  }
   363  
   364  type ModuleConstantMetadataV6 struct {
   365  	Name          Text
   366  	Type          Type
   367  	Value         Bytes
   368  	Documentation []Text
   369  }