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