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 }