github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/pkg/stafidecoder/typeRegistry.go (about) 1 package stafi_decoder 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 "regexp" 8 "strings" 9 10 "github.com/itering/scale.go/utiles" 11 ) 12 13 type RuntimeType struct{} 14 15 type Special struct { 16 Version []int 17 Registry interface{} 18 } 19 20 var TypeRegistry map[string]interface{} 21 22 var specialRegistry map[string][]Special 23 24 func (r RuntimeType) Reg() *RuntimeType { 25 registry := make(map[string]interface{}) 26 scales := []interface{}{ 27 &Null{}, 28 &U8{}, 29 &U16{}, 30 &U32{}, 31 &U64{}, 32 &U128{}, 33 &Compact{}, 34 &H160{}, 35 &H256{}, 36 &H512{}, 37 &Address{}, 38 &Option{}, 39 &Struct{}, 40 &Enum{}, 41 &Bytes{}, 42 &Vec{}, 43 &Set{}, 44 &CompactU32{}, 45 &Bool{}, 46 &StorageHasher{}, 47 &HexBytes{}, 48 &Moment{}, 49 &BlockNumber{}, 50 &AccountId{}, 51 &BoxProposal{}, 52 &Signature{}, 53 &Era{}, 54 &EraExtrinsic{}, 55 &Balance{}, 56 &Index{}, 57 &SessionIndex{}, 58 &EraIndex{}, 59 &ParaId{}, 60 &LogDigest{}, 61 &Other{}, 62 &ChangesTrieRoot{}, 63 &AuthoritiesChange{}, 64 &SealV0{}, 65 &Consensus{}, 66 &Seal{}, 67 &PreRuntime{}, 68 &Exposure{}, 69 &RawAuraPreDigest{}, 70 &RawBabePreDigest{}, 71 &RawBabePreDigestPrimary{}, 72 &RawBabePreDigestSecondary{}, 73 &RawBabePreDigestSecondaryVRF{}, 74 &SlotNumber{}, 75 &AccountIndex{}, 76 &LockIdentifier{}, 77 &BabeBlockWeight{}, 78 &AuthorityId{}, 79 &Call{}, 80 &ReferendumIndex{}, 81 &EcdsaSignature{}, 82 &EthereumAddress{}, 83 &PropIndex{}, 84 &Data{}, 85 &Vote{}, 86 &VoteOutcome{}, 87 &RawBabeLabel{}, 88 &Key{}, 89 &String{}, 90 &GenericAddress{}, 91 &OpaqueCall{}, 92 &BitVec{}, 93 &MetadataModuleEvent{}, 94 &MetadataModuleCallArgument{}, 95 &MetadataModuleCall{}, 96 &MetadataV6Decoder{}, 97 &MetadataV6Module{}, 98 &MetadataV6ModuleStorage{}, 99 &MetadataV6ModuleConstants{}, 100 &MetadataV7Decoder{}, 101 &MetadataV7Module{}, 102 &MetadataV7ModuleStorage{}, 103 &MetadataV7ModuleConstants{}, 104 &MetadataV7ModuleStorageEntry{}, 105 &MetadataV8Module{}, 106 &MetadataV8Decoder{}, 107 &MetadataV9Decoder{}, 108 &MetadataV10Decoder{}, 109 &MetadataV11Decoder{}, 110 &MetadataV12Decoder{}, 111 &MetadataV12Module{}, 112 &MetadataModuleError{}, 113 &GenericLookupSource{}, 114 &BTreeMap{}, 115 } 116 for _, class := range scales { 117 valueOf := reflect.ValueOf(class) 118 if valueOf.Type().Kind() == reflect.Ptr { 119 registry[strings.ToLower(reflect.Indirect(valueOf).Type().Name())] = class 120 } else { 121 registry[strings.ToLower(valueOf.Type().Name())] = class 122 } 123 } 124 registry["compact<u32>"] = &CompactU32{} 125 registry["compact<moment>"] = &Moment{} 126 registry["hash"] = &H256{} 127 registry["i8"] = &IntFixed{FixedLength: 1} 128 registry["i16"] = &IntFixed{FixedLength: 2} 129 registry["i32"] = &IntFixed{FixedLength: 4} 130 registry["i64"] = &IntFixed{FixedLength: 8} 131 registry["i128"] = &IntFixed{FixedLength: 16} 132 registry["[u8; 32]"] = &VecU8FixedLength{FixedLength: 32} 133 registry["[u8; 64]"] = &VecU8FixedLength{FixedLength: 64} 134 registry["[u8; 65]"] = &VecU8FixedLength{FixedLength: 65} 135 registry["[u8; 16]"] = &VecU8FixedLength{FixedLength: 16} 136 registry["[u8; 20]"] = &VecU8FixedLength{FixedLength: 20} 137 registry["[u8; 8]"] = &VecU8FixedLength{FixedLength: 8} 138 registry["[u8; 4]"] = &VecU8FixedLength{FixedLength: 4} 139 registry["[u8; 2]"] = &VecU8FixedLength{FixedLength: 2} 140 registry["[u8; 256]"] = &VecU8FixedLength{FixedLength: 256} 141 registry["[u128; 3]"] = &FixedLengthArray{FixedLength: 3, SubType: "u128"} 142 TypeRegistry = registry 143 144 RegCustomTypes(LoadTypeRegistry([]byte(BaseType))) 145 return &r 146 } 147 148 func (r *RuntimeType) getCodecInstant(t string, spec int) (reflect.Type, reflect.Value, error) { 149 t = strings.ToLower(t) 150 rt, err := r.specialVersionCodec(t, spec) 151 152 if err != nil { 153 rt = TypeRegistry[strings.ToLower(t)] 154 if rt == nil && t != "[]" && string(t[0]) == "[" && string(t[len(t)-1:]) == "]" { 155 if typePart := strings.Split(string(t[1:len(t)-1]), ";"); len(typePart) == 2 { 156 fixed := FixedLengthArray{ 157 FixedLength: utiles.StringToInt(strings.TrimSpace(typePart[1])), 158 SubType: strings.TrimSpace(typePart[0]), 159 } 160 rt = &fixed 161 } 162 } 163 if rt == nil { 164 return nil, reflect.ValueOf((*error)(nil)).Elem(), errors.New("Scale codec type nil" + t) 165 } 166 } 167 168 value := reflect.ValueOf(rt) 169 if value.Kind() == reflect.Ptr { 170 value = reflect.Indirect(value) 171 } 172 p := reflect.New(value.Type()) 173 p.Elem().Set(value) 174 return p.Type(), p, nil 175 } 176 177 func (r *RuntimeType) DecoderClass(typeString string, spec int) (reflect.Type, reflect.Value, string) { 178 var typeParts []string 179 typeString = ConvertType(typeString, true) 180 181 if typeString[len(typeString)-1:] == ">" { 182 decoderClass, rc, err := r.getCodecInstant(typeString, spec) 183 if err == nil { 184 return decoderClass, rc, "" 185 } 186 reg := regexp.MustCompile("^([^<]*)<(.+)>$") 187 typeParts = reg.FindStringSubmatch(typeString) 188 } 189 190 if len(typeParts) > 0 { 191 class, rc, err := r.getCodecInstant(typeParts[1], spec) 192 if err == nil { 193 return class, rc, typeParts[2] 194 } 195 } else { 196 class, rc, err := r.getCodecInstant(typeString, spec) 197 if err == nil { 198 return class, rc, "" 199 } 200 } 201 202 if typeString != "()" && string(typeString[0]) == "(" && typeString[len(typeString)-1:] == ")" { 203 decoderClass, rc, _ := r.getCodecInstant("Struct", spec) 204 s := rc.Interface().(*Struct) 205 s.TypeString = typeString 206 s.buildStruct() 207 return decoderClass, rc, "" 208 } 209 return nil, reflect.ValueOf((*error)(nil)).Elem(), "" 210 } 211 212 func (r *RuntimeType) specialVersionCodec(t string, spec int) (interface{}, error) { 213 var rt interface{} 214 215 if specials, ok := specialRegistry[t]; ok { 216 for _, special := range specials { 217 if spec >= special.Version[0] && spec <= special.Version[1] { 218 rt = special.Registry 219 return rt, nil 220 } 221 } 222 } 223 return rt, fmt.Errorf("not found") 224 }