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 }