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 }