github.com/diadata-org/diadata@v1.4.593/pkg/dia/helpers/substrate-helper/gsrpc/scale/codec.go (about) 1 // Copyright 2018 Jsgenesis 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package scale 16 17 import ( 18 "bytes" 19 "encoding/binary" 20 "errors" 21 "fmt" 22 "io" 23 "log" 24 "math" 25 "math/big" 26 "reflect" 27 ) 28 29 // Implementation for Parity codec in Go. 30 // Derived from https://github.com/paritytech/parity-codec/ 31 // While Rust implementation uses Rust type system and is highly optimized, this one 32 // has to rely on Go's reflection and thus is notably slower. 33 // Feature parity is almost full, apart from the lack of support for u128 (which are missing in Go). 34 35 const maxUint = ^uint(0) 36 const maxInt = int(maxUint >> 1) 37 38 // Encoder is a wrapper around a Writer that allows encoding data items to a stream. 39 // Allows passing encoding options 40 type Encoder struct { 41 writer io.Writer 42 } 43 44 func NewEncoder(writer io.Writer) *Encoder { 45 return &Encoder{writer: writer} 46 } 47 48 // Write several bytes to the encoder. 49 func (pe Encoder) Write(bytes []byte) error { 50 c, err := pe.writer.Write(bytes) 51 if err != nil { 52 return err 53 } 54 if c < len(bytes) { 55 return fmt.Errorf("Could not write %d bytes to writer", len(bytes)) 56 } 57 return nil 58 } 59 60 // PushByte writes a single byte to an encoder. 61 func (pe Encoder) PushByte(b byte) error { 62 return pe.Write([]byte{b}) 63 } 64 65 // EncodeUintCompact writes an unsigned integer to the stream using the compact encoding. 66 // A typical usage is storing the length of a collection. 67 // Definition of compact encoding: 68 // 0b00 00 00 00 / 00 00 00 00 / 00 00 00 00 / 00 00 00 00 69 // xx xx xx 00 (0 ... 2**6 - 1) (u8) 70 // yL yL yL 01 / yH yH yH yL (2**6 ... 2**14 - 1) (u8, u16) low LH high 71 // zL zL zL 10 / zM zM zM zL / zM zM zM zM / zH zH zH zM (2**14 ... 2**30 - 1) (u16, u32) low LMMH high 72 // nn nn nn 11 [ / zz zz zz zz ]{4 + n} (2**30 ... 2**536 - 1) (u32, u64, u128, U256, U512, U520) straight LE-encoded 73 // Rust implementation: see impl<'a> Encode for CompactRef<'a, u64> 74 func (pe Encoder) EncodeUintCompact(v big.Int) error { 75 if v.Sign() == -1 { 76 return errors.New("Assertion error: EncodeUintCompact cannot process negative numbers") 77 } 78 79 if v.IsUint64() { 80 if v.Uint64() < 1<<30 { 81 if v.Uint64() < 1<<6 { 82 err := pe.PushByte(byte(v.Uint64()) << 2) 83 if err != nil { 84 return err 85 } 86 } else if v.Uint64() < 1<<14 { 87 err := binary.Write(pe.writer, binary.LittleEndian, uint16(v.Uint64()<<2)+1) 88 if err != nil { 89 return err 90 } 91 } else { 92 err := binary.Write(pe.writer, binary.LittleEndian, uint32(v.Uint64()<<2)+2) 93 if err != nil { 94 return err 95 } 96 } 97 return nil 98 } 99 } 100 101 numBytes := len(v.Bytes()) 102 if numBytes > 255 { 103 return errors.New("Assertion error: numBytes>255 exeeds allowed for length prefix") 104 } 105 topSixBits := uint8(numBytes - 4) 106 lengthByte := topSixBits<<2 + 3 107 108 if topSixBits > 63 { 109 return errors.New("Assertion error: n<=63 needed to compact-encode substrate unsigned big integer") 110 } 111 err := pe.PushByte(lengthByte) 112 if err != nil { 113 return err 114 } 115 buf := v.Bytes() 116 Reverse(buf) 117 err = pe.Write(buf) 118 if err != nil { 119 return err 120 } 121 return nil 122 } 123 124 // Encode a value to the stream. 125 func (pe Encoder) Encode(value interface{}) error { 126 t := reflect.TypeOf(value) 127 128 // If the type implements encodeable, use that implementation 129 encodeable := reflect.TypeOf((*Encodeable)(nil)).Elem() 130 if t.Implements(encodeable) { 131 err := value.(Encodeable).Encode(pe) 132 if err != nil { 133 return err 134 } 135 return nil 136 } 137 138 tk := t.Kind() 139 switch tk { 140 141 // Boolean and numbers are trivially encoded via binary.Write 142 // It will use reflection again and take a performance hit 143 // TODO: consider handling every case directly 144 case reflect.Bool: 145 fallthrough 146 case reflect.Int8: 147 fallthrough 148 case reflect.Uint8: 149 fallthrough 150 case reflect.Int: 151 fallthrough 152 case reflect.Int16: 153 fallthrough 154 case reflect.Int32: 155 fallthrough 156 case reflect.Int64: 157 fallthrough 158 case reflect.Uint: 159 fallthrough 160 case reflect.Uint16: 161 fallthrough 162 case reflect.Uint32: 163 fallthrough 164 case reflect.Uint64: 165 fallthrough 166 case reflect.Uintptr: 167 fallthrough 168 case reflect.Float32: 169 fallthrough 170 case reflect.Float64: 171 err := binary.Write(pe.writer, binary.LittleEndian, value) 172 if err != nil { 173 return err 174 } 175 case reflect.Ptr: 176 rv := reflect.ValueOf(value) 177 if rv.IsNil() { 178 return errors.New("Encoding null pointers not supported; consider using Option type") 179 } else { 180 dereferenced := rv.Elem() 181 err := pe.Encode(dereferenced.Interface()) 182 if err != nil { 183 return err 184 } 185 } 186 187 // Arrays: no compact-encoded length prefix 188 case reflect.Array: 189 rv := reflect.ValueOf(value) 190 l := rv.Len() 191 for i := 0; i < l; i++ { 192 err := pe.Encode(rv.Index(i).Interface()) 193 if err != nil { 194 return err 195 } 196 } 197 198 // Slices: first compact-encode length, then each item individually 199 case reflect.Slice: 200 rv := reflect.ValueOf(value) 201 l := rv.Len() 202 len64 := uint64(l) 203 if len64 > math.MaxUint32 { 204 return errors.New("Attempted to serialize a collection with too many elements.") 205 } 206 err := pe.EncodeUintCompact(*big.NewInt(0).SetUint64(len64)) 207 if err != nil { 208 return err 209 } 210 for i := 0; i < l; i++ { 211 err = pe.Encode(rv.Index(i).Interface()) 212 if err != nil { 213 return err 214 } 215 } 216 217 // Strings are encoded as UTF-8 byte slices, just as in Rust 218 case reflect.String: 219 s := reflect.ValueOf(value).String() 220 err := pe.Encode([]byte(s)) 221 if err != nil { 222 return err 223 } 224 225 case reflect.Struct: 226 rv := reflect.ValueOf(value) 227 for i := 0; i < rv.NumField(); i++ { 228 ft := rv.Type().Field(i) 229 tv, ok := ft.Tag.Lookup("scale") 230 if ok && tv == "-" { 231 continue 232 } 233 err := pe.Encode(rv.Field(i).Interface()) 234 if err != nil { 235 return fmt.Errorf("type %s does not support Encodeable interface and could not be "+ 236 "encoded field by field, error: %v", t, err) 237 } 238 } 239 240 // Currently unsupported types 241 case reflect.Complex64: 242 fallthrough 243 case reflect.Complex128: 244 fallthrough 245 case reflect.Chan: 246 fallthrough 247 case reflect.Func: 248 fallthrough 249 case reflect.Interface: 250 fallthrough 251 case reflect.Map: 252 fallthrough 253 case reflect.UnsafePointer: 254 fallthrough 255 case reflect.Invalid: 256 return fmt.Errorf("Type %s cannot be encoded", t.Kind()) 257 default: 258 log.Println("not captured") 259 } 260 return nil 261 } 262 263 // EncodeOption stores optionally present value to the stream. 264 func (pe Encoder) EncodeOption(hasValue bool, value interface{}) error { 265 if !hasValue { 266 err := pe.PushByte(0) 267 if err != nil { 268 return err 269 } 270 } else { 271 err := pe.PushByte(1) 272 if err != nil { 273 return err 274 } 275 err = pe.Encode(value) 276 if err != nil { 277 return err 278 } 279 } 280 return nil 281 } 282 283 // Decoder is a wraper around a Reader that allows decoding data items from a stream. 284 type Decoder struct { 285 reader io.Reader 286 } 287 288 func NewDecoder(reader io.Reader) *Decoder { 289 return &Decoder{reader: reader} 290 } 291 292 // Read reads bytes from a stream into a buffer 293 func (pd Decoder) Read(bytes []byte) error { 294 c, err := pd.reader.Read(bytes) 295 if err != nil { 296 return err 297 } 298 if c < len(bytes) { 299 return fmt.Errorf("Cannot read the required number of bytes %d, only %d available", len(bytes), c) 300 } 301 return nil 302 } 303 304 // ReadOneByte reads a next byte from the stream. 305 // Named so to avoid a linter warning about a clash with io.ByteReader.ReadByte 306 func (pd Decoder) ReadOneByte() (byte, error) { 307 buf := []byte{0} 308 err := pd.Read(buf) 309 if err != nil { 310 return buf[0], err 311 } 312 return buf[0], nil 313 } 314 315 // Decode takes a pointer to a decodable value and populates it from the stream. 316 func (pd Decoder) Decode(target interface{}) error { 317 t0 := reflect.TypeOf(target) 318 if t0.Kind() != reflect.Ptr { 319 return errors.New("Target must be a pointer, but was " + fmt.Sprint(t0)) 320 } 321 val := reflect.ValueOf(target) 322 if val.IsNil() { 323 return errors.New("Target is a nil pointer") 324 } 325 return pd.DecodeIntoReflectValue(val.Elem()) 326 } 327 328 // DecodeIntoReflectValue populates a writable reflect.Value from the stream 329 func (pd Decoder) DecodeIntoReflectValue(target reflect.Value) error { 330 t := target.Type() 331 if !target.CanSet() { 332 return fmt.Errorf("Unsettable value %v", t) 333 } 334 335 // If the type implements decodeable, use that implementation 336 decodeable := reflect.TypeOf((*Decodeable)(nil)).Elem() 337 ptrType := reflect.PtrTo(t) 338 if ptrType.Implements(decodeable) { 339 var holder reflect.Value 340 if t.Kind() == reflect.Slice || t.Kind() == reflect.Array { 341 slice := reflect.MakeSlice(t, target.Len(), target.Len()) 342 holder = reflect.New(t) 343 holder.Elem().Set(slice) 344 } else { 345 holder = reflect.New(t) 346 } 347 348 err := holder.Interface().(Decodeable).Decode(pd) 349 if err != nil { 350 return err 351 } 352 target.Set(holder.Elem()) 353 return nil 354 } 355 356 switch t.Kind() { 357 358 // Boolean and numbers are trivially decoded via binary.Read 359 // It will use reflection again and take a performance hit 360 // TODO: consider handling every case directly 361 case reflect.Bool: 362 fallthrough 363 case reflect.Int8: 364 fallthrough 365 case reflect.Uint8: 366 fallthrough 367 case reflect.Int: 368 fallthrough 369 case reflect.Int16: 370 fallthrough 371 case reflect.Int32: 372 fallthrough 373 case reflect.Int64: 374 fallthrough 375 case reflect.Uint: 376 fallthrough 377 case reflect.Uint16: 378 fallthrough 379 case reflect.Uint32: 380 fallthrough 381 case reflect.Uint64: 382 fallthrough 383 case reflect.Uintptr: 384 fallthrough 385 case reflect.Float32: 386 fallthrough 387 case reflect.Float64: 388 intHolder := reflect.New(t) 389 intPointer := intHolder.Interface() 390 err := binary.Read(pd.reader, binary.LittleEndian, intPointer) 391 if err == io.EOF { 392 return errors.New("expected more bytes, but could not decode any more") 393 } 394 if err != nil { 395 return err 396 } 397 target.Set(intHolder.Elem()) 398 399 // If you want to replicate Option<T> behavior in Rust, see OptionBool and an 400 // example type OptionInt8 in tests. 401 case reflect.Ptr: 402 isNil := target.IsNil() 403 if isNil { 404 // target.set 405 // return nil 406 } 407 ptr := target.Elem() 408 err := pd.DecodeIntoReflectValue(ptr) 409 if err != nil { 410 return err 411 } 412 413 // Arrays: derive the length from the array length 414 case reflect.Array: 415 targetLen := target.Len() 416 for i := 0; i < targetLen; i++ { 417 err := pd.DecodeIntoReflectValue(target.Index(i)) 418 if err != nil { 419 return err 420 } 421 } 422 423 // Slices: first compact-encode length, then each item individually 424 case reflect.Slice: 425 codedLen64, _ := pd.DecodeUintCompact() 426 if codedLen64.Uint64() > math.MaxUint32 { 427 return errors.New("Encoded array length is higher than allowed by the protocol (32-bit unsigned integer)") 428 } 429 if codedLen64.Uint64() > uint64(maxInt) { 430 return errors.New("Encoded array length is higher than allowed by the platform") 431 } 432 codedLen := int(codedLen64.Uint64()) 433 targetLen := target.Len() 434 if codedLen != targetLen { 435 if int(codedLen) > target.Cap() { 436 newSlice := reflect.MakeSlice(t, int(codedLen), int(codedLen)) 437 target.Set(newSlice) 438 } else { 439 target.SetLen(int(codedLen)) 440 } 441 } 442 for i := 0; i < codedLen; i++ { 443 err := pd.DecodeIntoReflectValue(target.Index(i)) 444 if err != nil { 445 return err 446 } 447 } 448 449 // Strings are encoded as UTF-8 byte slices, just as in Rust 450 case reflect.String: 451 var b []byte 452 err := pd.Decode(&b) 453 if err != nil { 454 return err 455 } 456 target.SetString(string(b)) 457 458 case reflect.Struct: 459 for i := 0; i < target.NumField(); i++ { 460 ft := target.Type().Field(i) 461 tv, ok := ft.Tag.Lookup("scale") 462 if ok && tv == "-" { 463 continue 464 } 465 err := pd.DecodeIntoReflectValue(target.Field(i)) 466 if err != nil { 467 return fmt.Errorf("type %s does not support Decodeable interface and could not be "+ 468 "decoded field by field, error: %v", ptrType, err) 469 } 470 } 471 472 // Currently unsupported types 473 case reflect.Complex64: 474 fallthrough 475 case reflect.Complex128: 476 fallthrough 477 case reflect.Chan: 478 fallthrough 479 case reflect.Func: 480 fallthrough 481 case reflect.Interface: 482 fallthrough 483 case reflect.Map: 484 fallthrough 485 case reflect.UnsafePointer: 486 fallthrough 487 case reflect.Invalid: 488 return fmt.Errorf("Type %s cannot be decoded", t.Kind()) 489 } 490 return nil 491 } 492 493 // DecodeUintCompact decodes a compact-encoded integer. See EncodeUintCompact method. 494 func (pd Decoder) DecodeUintCompact() (*big.Int, error) { 495 b, err := pd.ReadOneByte() 496 497 if err != nil { 498 return nil, err 499 } 500 501 mode := b & 3 502 switch mode { 503 case 0: 504 // right shift to remove mode bits 505 return big.NewInt(0).SetUint64(uint64(b >> 2)), nil 506 case 1: 507 bb, err := pd.ReadOneByte() 508 if err != nil { 509 return nil, err 510 } 511 r := uint64(bb) 512 // * 2^6 513 r <<= 6 514 // right shift to remove mode bits and add to prev 515 r += uint64(b >> 2) 516 return big.NewInt(0).SetUint64(r), nil 517 case 2: 518 // value = 32 bits + mode 519 buf := make([]byte, 4) 520 buf[0] = b 521 err := pd.Read(buf[1:4]) 522 if err != nil { 523 return nil, err 524 } 525 // set the buffer in little endian order 526 r := binary.LittleEndian.Uint32(buf) 527 // remove the last 2 mode bits 528 r >>= 2 529 return big.NewInt(0).SetUint64(uint64(r)), nil 530 case 3: 531 // remove mode bits 532 l := b >> 2 533 534 if l > 63 { // Max upper bound of 536 is (67 - 4) 535 return nil, errors.New("Not supported: l>63 encountered when decoding a compact-encoded uint") 536 } 537 buf := make([]byte, l+4) 538 err := pd.Read(buf) 539 if err != nil { 540 return nil, err 541 } 542 Reverse(buf) 543 return new(big.Int).SetBytes(buf), nil 544 default: 545 return nil, errors.New("Code should be unreachable") 546 } 547 } 548 549 // Reverse reverses bytes in place (manipulates the underlying array) 550 func Reverse(b []byte) { 551 for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 { 552 b[i], b[j] = b[j], b[i] 553 } 554 } 555 556 // DecodeOption decodes a optionally available value into a boolean presence field and a value. 557 func (pd Decoder) DecodeOption(hasValue *bool, valuePointer interface{}) error { 558 b, _ := pd.ReadOneByte() 559 switch b { 560 case 0: 561 *hasValue = false 562 case 1: 563 *hasValue = true 564 err := pd.Decode(valuePointer) 565 if err != nil { 566 return err 567 } 568 default: 569 return fmt.Errorf("Unknown byte prefix for encoded OptionBool: %d", b) 570 } 571 return nil 572 } 573 574 // Encodeable is an interface that defines a custom encoding rules for a data type. 575 // Should be defined for structs (not pointers to them). 576 // See OptionBool for an example implementation. 577 type Encodeable interface { 578 // ParityEncode encodes and write this structure into a stream 579 Encode(encoder Encoder) error 580 } 581 582 // Decodeable is an interface that defines a custom encoding rules for a data type. 583 // Should be defined for pointers to structs. 584 // See OptionBool for an example implementation. 585 type Decodeable interface { 586 // ParityDecode populates this structure from a stream (overwriting the current contents), return false on failure 587 Decode(decoder Decoder) error 588 } 589 590 // OptionBool is a structure that can store a boolean or a missing value. 591 // Note that encoding rules are slightly different from other "Option" fields. 592 type OptionBool struct { 593 hasValue bool 594 value bool 595 } 596 597 // NewOptionBoolEmpty creates an OptionBool without a value. 598 func NewOptionBoolEmpty() OptionBool { 599 return OptionBool{false, false} 600 } 601 602 // NewOptionBool creates an OptionBool with a value. 603 func NewOptionBool(value bool) OptionBool { 604 return OptionBool{true, value} 605 } 606 607 // ParityEncode implements encoding for OptionBool as per Rust implementation. 608 func (o OptionBool) Encode(encoder Encoder) error { 609 var err error 610 if !o.hasValue { 611 err = encoder.PushByte(0) 612 } else { 613 if o.value { 614 err = encoder.PushByte(1) 615 } else { 616 err = encoder.PushByte(2) 617 } 618 } 619 if err != nil { 620 return err 621 } 622 return nil 623 } 624 625 // ParityDecode implements decoding for OptionBool as per Rust implementation. 626 func (o *OptionBool) Decode(decoder Decoder) error { 627 b, _ := decoder.ReadOneByte() 628 switch b { 629 case 0: 630 o.hasValue = false 631 o.value = false 632 case 1: 633 o.hasValue = true 634 o.value = true 635 case 2: 636 o.hasValue = true 637 o.value = false 638 default: 639 return fmt.Errorf("Unknown byte prefix for encoded OptionBool: %d", b) 640 } 641 return nil 642 } 643 644 // ToKeyedVec replicates the behaviour of Rust's to_keyed_vec helper. 645 func ToKeyedVec(value interface{}, prependKey []byte) ([]byte, error) { 646 var buffer = bytes.NewBuffer(prependKey) 647 err := Encoder{buffer}.Encode(value) 648 if err != nil { 649 return nil, err 650 } 651 return buffer.Bytes(), nil 652 }