github.com/koko1123/flow-go-1@v0.29.6/ledger/trie_encoder.go (about) 1 package ledger 2 3 import ( 4 "fmt" 5 6 "github.com/koko1123/flow-go-1/ledger/common/bitutils" 7 "github.com/koko1123/flow-go-1/ledger/common/hash" 8 "github.com/koko1123/flow-go-1/ledger/common/utils" 9 ) 10 11 // Versions capture the maximum version of encoding this code supports. 12 // I.e. this code encodes data with the latest version and only decodes 13 // data with version smaller or equal to these versions. 14 // Bumping a version number prevents older versions of code from handling 15 // the newer version of data. New code handling new data version 16 // should be updated to also support backward compatibility if needed. 17 const ( 18 // CAUTION: if payload key encoding is changed, convertEncodedPayloadKey() 19 // must be modified to convert encoded payload key from one version to 20 // another version. 21 PayloadVersion = uint16(1) 22 TrieUpdateVersion = uint16(0) // Use payload version 0 encoding 23 TrieProofVersion = uint16(0) // Use payload version 0 encoding 24 TrieBatchProofVersion = uint16(0) // Use payload version 0 encoding 25 ) 26 27 // Type capture the type of encoded entity (e.g. State, Key, Value, Path) 28 type Type uint8 29 30 const ( 31 // TypeUnknown - unknown type 32 TypeUnknown = iota 33 // TypeState - type for State 34 TypeState 35 // TypeKeyPart - type for KeyParts (a subset of key) 36 TypeKeyPart 37 // TypeKey - type for Keys (unique identifier to reference a location in ledger) 38 TypeKey 39 // TypeValue - type for Ledger Values 40 TypeValue 41 // TypePath - type for Paths (trie storage location of a key value pair) 42 TypePath 43 // TypePayload - type for Payloads (stored at trie nodes including key value pair ) 44 TypePayload 45 // TypeProof type for Proofs 46 // (all data needed to verify a key value pair at specific state) 47 TypeProof 48 // TypeBatchProof - type for BatchProofs 49 TypeBatchProof 50 // TypeQuery - type for ledger query 51 TypeQuery 52 // TypeUpdate - type for ledger update 53 TypeUpdate 54 // TypeTrieUpdate - type for trie update 55 TypeTrieUpdate 56 // this is used to flag types from the future 57 typeUnsuported 58 ) 59 60 func (e Type) String() string { 61 return [...]string{"Unknown", "State", "KeyPart", "Key", "Value", "Path", "Payload", "Proof", "BatchProof", "Query", "Update", "Trie Update"}[e] 62 } 63 64 // CheckVersion extracts encoding bytes from a raw encoded message 65 // checks it against the supported versions and returns the rest of rawInput (excluding encDecVersion bytes) 66 func CheckVersion(rawInput []byte, maxVersion uint16) (rest []byte, version uint16, err error) { 67 version, rest, err = utils.ReadUint16(rawInput) 68 if err != nil { 69 return rest, version, fmt.Errorf("error checking the encoding decoding version: %w", err) 70 } 71 // error on versions coming from future till a time-machine is invented 72 if version > maxVersion { 73 return rest, version, fmt.Errorf("incompatible encoding decoding version (%d > %d): %w", version, maxVersion, err) 74 } 75 // return the rest of bytes 76 return rest, version, nil 77 } 78 79 // CheckType extracts encoding byte from a raw encoded message 80 // checks it against expected type and returns the rest of rawInput (excluding type byte) 81 func CheckType(rawInput []byte, expectedType uint8) (rest []byte, err error) { 82 t, r, err := utils.ReadUint8(rawInput) 83 if err != nil { 84 return r, fmt.Errorf("error checking type of the encoded entity: %w", err) 85 } 86 87 // error if type is known for this code 88 if t >= typeUnsuported { 89 return r, fmt.Errorf("unknown entity type in the encoded data (%d > %d)", t, typeUnsuported) 90 } 91 92 // error if type is known for this code 93 if t != expectedType { 94 return r, fmt.Errorf("unexpected entity type, got (%v) but (%v) was expected", Type(t), Type(expectedType)) 95 } 96 97 // return the rest of bytes 98 return r, nil 99 } 100 101 // EncodeKeyPart encodes a key part into a byte slice 102 func EncodeKeyPart(kp *KeyPart) []byte { 103 if kp == nil { 104 return []byte{} 105 } 106 // encode version 107 buffer := utils.AppendUint16([]byte{}, PayloadVersion) 108 109 // encode key part entity type 110 buffer = utils.AppendUint8(buffer, TypeKeyPart) 111 112 // encode the key part content 113 buffer = append(buffer, encodeKeyPart(kp, PayloadVersion)...) 114 return buffer 115 } 116 117 func encodeKeyPart(kp *KeyPart, version uint16) []byte { 118 buffer := make([]byte, 0, encodedKeyPartLength(kp, version)) 119 return encodeAndAppendKeyPart(buffer, kp, version) 120 } 121 122 func encodeAndAppendKeyPart(buffer []byte, kp *KeyPart, _ uint16) []byte { 123 // encode "Type" field of the key part 124 buffer = utils.AppendUint16(buffer, kp.Type) 125 126 // encode "Value" field of the key part 127 buffer = append(buffer, kp.Value...) 128 129 return buffer 130 } 131 132 func encodedKeyPartLength(kp *KeyPart, _ uint16) int { 133 // Key part is encoded as: type (2 bytes) + value 134 return 2 + len(kp.Value) 135 } 136 137 // DecodeKeyPart constructs a key part from an encoded key part 138 func DecodeKeyPart(encodedKeyPart []byte) (*KeyPart, error) { 139 rest, version, err := CheckVersion(encodedKeyPart, PayloadVersion) 140 if err != nil { 141 return nil, fmt.Errorf("error decoding key part: %w", err) 142 } 143 144 // check the type 145 rest, err = CheckType(rest, TypeKeyPart) 146 if err != nil { 147 return nil, fmt.Errorf("error decoding key part: %w", err) 148 } 149 150 // decode the key part content (zerocopy) 151 key, err := decodeKeyPart(rest, true, version) 152 if err != nil { 153 return nil, fmt.Errorf("error decoding key part: %w", err) 154 } 155 156 return key, nil 157 } 158 159 // decodeKeyPart decodes inp into KeyPart. If zeroCopy is true, KeyPart 160 // references data in inp. Otherwise, it is copied. 161 func decodeKeyPart(inp []byte, zeroCopy bool, _ uint16) (*KeyPart, error) { 162 // read key part type and the rest is the key item part 163 kpt, kpv, err := utils.ReadUint16(inp) 164 if err != nil { 165 return nil, fmt.Errorf("error decoding key part (content): %w", err) 166 } 167 if zeroCopy { 168 return &KeyPart{Type: kpt, Value: kpv}, nil 169 } 170 v := make([]byte, len(kpv)) 171 copy(v, kpv) 172 return &KeyPart{Type: kpt, Value: v}, nil 173 } 174 175 // EncodeKey encodes a key into a byte slice 176 func EncodeKey(k *Key) []byte { 177 if k == nil { 178 return []byte{} 179 } 180 // encode EncodingDecodingType 181 buffer := utils.AppendUint16([]byte{}, PayloadVersion) 182 // encode key entity type 183 buffer = utils.AppendUint8(buffer, TypeKey) 184 // encode key content 185 buffer = append(buffer, encodeKey(k, PayloadVersion)...) 186 187 return buffer 188 } 189 190 // encodeKey encodes a key into a byte slice 191 func encodeKey(k *Key, version uint16) []byte { 192 buffer := make([]byte, 0, encodedKeyLength(k, version)) 193 return encodeAndAppendKey(buffer, k, version) 194 } 195 196 func encodeAndAppendKey(buffer []byte, k *Key, version uint16) []byte { 197 // encode number of key parts 198 buffer = utils.AppendUint16(buffer, uint16(len(k.KeyParts))) 199 200 // iterate over key parts 201 for _, kp := range k.KeyParts { 202 // encode the len of the encoded key part 203 buffer = utils.AppendUint32(buffer, uint32(encodedKeyPartLength(&kp, version))) 204 205 // encode the key part 206 buffer = encodeAndAppendKeyPart(buffer, &kp, version) 207 } 208 209 return buffer 210 } 211 212 func encodedKeyLength(k *Key, version uint16) int { 213 // Key is encoded as: number of key parts (2 bytes) and for each key part, 214 // the key part size (4 bytes) + encoded key part (n bytes). 215 size := 2 + 4*len(k.KeyParts) 216 for _, kp := range k.KeyParts { 217 size += encodedKeyPartLength(&kp, version) 218 } 219 return size 220 } 221 222 // DecodeKey constructs a key from an encoded key part 223 func DecodeKey(encodedKey []byte) (*Key, error) { 224 // check the enc dec version 225 rest, version, err := CheckVersion(encodedKey, PayloadVersion) 226 if err != nil { 227 return nil, fmt.Errorf("error decoding key: %w", err) 228 } 229 // check the encoding type 230 rest, err = CheckType(rest, TypeKey) 231 if err != nil { 232 return nil, fmt.Errorf("error decoding key: %w", err) 233 } 234 235 // decode the key content (zerocopy) 236 key, err := decodeKey(rest, true, version) 237 if err != nil { 238 return nil, fmt.Errorf("error decoding key: %w", err) 239 } 240 return key, nil 241 } 242 243 // decodeKey decodes inp into Key. If zeroCopy is true, returned key 244 // references data in inp. Otherwise, it is copied. 245 func decodeKey(inp []byte, zeroCopy bool, version uint16) (*Key, error) { 246 key := &Key{} 247 248 numOfParts, rest, err := utils.ReadUint16(inp) 249 if err != nil { 250 return nil, fmt.Errorf("error decoding key (content): %w", err) 251 } 252 253 if numOfParts == 0 { 254 return key, nil 255 } 256 257 key.KeyParts = make([]KeyPart, numOfParts) 258 259 for i := 0; i < int(numOfParts); i++ { 260 var kpEncSize uint32 261 var kpEnc []byte 262 // read encoded key part size 263 kpEncSize, rest, err = utils.ReadUint32(rest) 264 if err != nil { 265 return nil, fmt.Errorf("error decoding key (content): %w", err) 266 } 267 268 // read encoded key part 269 kpEnc, rest, err = utils.ReadSlice(rest, int(kpEncSize)) 270 if err != nil { 271 return nil, fmt.Errorf("error decoding key (content): %w", err) 272 } 273 274 // decode encoded key part 275 kp, err := decodeKeyPart(kpEnc, zeroCopy, version) 276 if err != nil { 277 return nil, fmt.Errorf("error decoding key (content): %w", err) 278 } 279 280 key.KeyParts[i] = *kp 281 } 282 return key, nil 283 } 284 285 // EncodeValue encodes a value into a byte slice 286 func EncodeValue(v Value) []byte { 287 // encode EncodingDecodingType 288 buffer := utils.AppendUint16([]byte{}, PayloadVersion) 289 290 // encode key entity type 291 buffer = utils.AppendUint8(buffer, TypeValue) 292 293 // encode value 294 buffer = append(buffer, encodeValue(v, PayloadVersion)...) 295 296 return buffer 297 } 298 299 func encodeValue(v Value, _ uint16) []byte { 300 return v 301 } 302 303 func encodeAndAppendValue(buffer []byte, v Value, _ uint16) []byte { 304 return append(buffer, v...) 305 } 306 307 func encodedValueLength(v Value, _ uint16) int { 308 return len(v) 309 } 310 311 // DecodeValue constructs a ledger value using an encoded byte slice 312 func DecodeValue(encodedValue []byte) (Value, error) { 313 // check enc dec version 314 rest, _, err := CheckVersion(encodedValue, PayloadVersion) 315 if err != nil { 316 return nil, err 317 } 318 319 // check the encoding type 320 rest, err = CheckType(rest, TypeValue) 321 if err != nil { 322 return nil, err 323 } 324 325 return rest, nil 326 } 327 328 // EncodePayload encodes a ledger payload 329 func EncodePayload(p *Payload) []byte { 330 if p == nil { 331 return []byte{} 332 } 333 // encode EncodingDecodingType 334 buffer := utils.AppendUint16([]byte{}, PayloadVersion) 335 336 // encode key entity type 337 buffer = utils.AppendUint8(buffer, TypePayload) 338 339 // append encoded payload content 340 buffer = append(buffer, encodePayload(p, PayloadVersion)...) 341 return buffer 342 } 343 344 // EncodeAndAppendPayloadWithoutPrefix encodes a ledger payload 345 // without prefix (version and type) and appends to buffer. 346 // If payload is nil, unmodified buffer is returned. 347 func EncodeAndAppendPayloadWithoutPrefix(buffer []byte, p *Payload, version uint16) []byte { 348 if p == nil { 349 return buffer 350 } 351 return encodeAndAppendPayload(buffer, p, version) 352 } 353 354 func EncodedPayloadLengthWithoutPrefix(p *Payload, version uint16) int { 355 return encodedPayloadLength(p, version) 356 } 357 358 func encodePayload(p *Payload, version uint16) []byte { 359 buffer := make([]byte, 0, encodedPayloadLength(p, version)) 360 return encodeAndAppendPayload(buffer, p, version) 361 } 362 363 // convertEncodedPayloadKey returns encoded payload key in toVersion 364 // converted from encoded payload key in fromVersion. 365 func convertEncodedPayloadKey(key []byte, fromVersion uint16, toVersion uint16) []byte { 366 // No conversion is needed for now because 367 // payload key encoding version 0 is the same as version 1. 368 return key 369 } 370 371 func encodeAndAppendPayload(buffer []byte, p *Payload, version uint16) []byte { 372 373 // convert payload encoded key from PayloadVersion to version. 374 encKey := convertEncodedPayloadKey(p.encKey, PayloadVersion, version) 375 376 // encode encoded key size 377 buffer = utils.AppendUint32(buffer, uint32(len(encKey))) 378 379 // append encoded key 380 buffer = append(buffer, encKey...) 381 382 // encode encoded value size 383 encodedValueLen := encodedValueLength(p.Value(), version) 384 switch version { 385 case 0: 386 // In version 0, encoded value length is encoded as 8 bytes. 387 buffer = utils.AppendUint64(buffer, uint64(encodedValueLen)) 388 default: 389 // In version 1 and later, encoded value length is encoded as 4 bytes. 390 buffer = utils.AppendUint32(buffer, uint32(encodedValueLen)) 391 } 392 393 // encode value 394 buffer = encodeAndAppendValue(buffer, p.Value(), version) 395 396 return buffer 397 } 398 399 func encodedPayloadLength(p *Payload, version uint16) int { 400 if p == nil { 401 return 0 402 } 403 404 // Error isn't checked here because encoded key will be used directly 405 // in later commit and no error will be returned. 406 k, _ := p.Key() 407 408 switch version { 409 case 0: 410 // In version 0, payload is encoded as: 411 // encode key length (4 bytes) + encoded key + 412 // encoded value length (8 bytes) + encode value 413 return 4 + encodedKeyLength(&k, version) + 8 + encodedValueLength(p.Value(), version) 414 default: 415 // In version 1 and later, payload is encoded as: 416 // encode key length (4 bytes) + encoded key + 417 // encoded value length (4 bytes) + encode value 418 return 4 + encodedKeyLength(&k, version) + 4 + encodedValueLength(p.Value(), version) 419 } 420 } 421 422 // DecodePayload construct a payload from an encoded byte slice 423 func DecodePayload(encodedPayload []byte) (*Payload, error) { 424 // if empty don't decode 425 if len(encodedPayload) == 0 { 426 return nil, nil 427 } 428 // check the enc dec version 429 rest, version, err := CheckVersion(encodedPayload, PayloadVersion) 430 if err != nil { 431 return nil, fmt.Errorf("error decoding payload: %w", err) 432 } 433 // check the encoding type 434 rest, err = CheckType(rest, TypePayload) 435 if err != nil { 436 return nil, fmt.Errorf("error decoding payload: %w", err) 437 } 438 // decode payload (zerocopy) 439 return decodePayload(rest, true, version) 440 } 441 442 // DecodePayloadWithoutPrefix constructs a payload from encoded byte slice 443 // without prefix (version and type). If zeroCopy is true, returned payload 444 // references data in encodedPayload. Otherwise, it is copied. 445 func DecodePayloadWithoutPrefix(encodedPayload []byte, zeroCopy bool, version uint16) (*Payload, error) { 446 // if empty don't decode 447 if len(encodedPayload) == 0 { 448 return nil, nil 449 } 450 return decodePayload(encodedPayload, zeroCopy, version) 451 } 452 453 // decodePayload decodes inp into payload. If zeroCopy is true, 454 // returned payload references data in inp. Otherwise, it is copied. 455 func decodePayload(inp []byte, zeroCopy bool, version uint16) (*Payload, error) { 456 457 // read encoded key size 458 encKeySize, rest, err := utils.ReadUint32(inp) 459 if err != nil { 460 return nil, fmt.Errorf("error decoding payload: %w", err) 461 } 462 463 // read encoded key 464 ek, rest, err := utils.ReadSlice(rest, int(encKeySize)) 465 if err != nil { 466 return nil, fmt.Errorf("error decoding payload: %w", err) 467 } 468 469 // convert payload encoded key from version to PayloadVersion. 470 encKey := convertEncodedPayloadKey(ek, version, PayloadVersion) 471 472 // read encoded value size 473 var encValueSize int 474 switch version { 475 case 0: 476 var size uint64 477 size, rest, err = utils.ReadUint64(rest) 478 encValueSize = int(size) 479 default: 480 var size uint32 481 size, rest, err = utils.ReadUint32(rest) 482 encValueSize = int(size) 483 } 484 485 if err != nil { 486 return nil, fmt.Errorf("error decoding payload: %w", err) 487 } 488 489 // read encoded value 490 encValue, _, err := utils.ReadSlice(rest, encValueSize) 491 if err != nil { 492 return nil, fmt.Errorf("error decoding payload: %w", err) 493 } 494 495 if zeroCopy { 496 return &Payload{encKey, encValue}, nil 497 } 498 499 k := make([]byte, len(encKey)) 500 copy(k, encKey) 501 v := make([]byte, len(encValue)) 502 copy(v, encValue) 503 return &Payload{k, v}, nil 504 } 505 506 // EncodeTrieUpdate encodes a trie update struct 507 func EncodeTrieUpdate(t *TrieUpdate) []byte { 508 if t == nil { 509 return []byte{} 510 } 511 // encode EncodingDecodingType 512 buffer := utils.AppendUint16([]byte{}, TrieUpdateVersion) 513 514 // encode key entity type 515 buffer = utils.AppendUint8(buffer, TypeTrieUpdate) 516 517 // append encoded payload content 518 buffer = append(buffer, encodeTrieUpdate(t, TrieUpdateVersion)...) 519 520 return buffer 521 } 522 523 func encodeTrieUpdate(t *TrieUpdate, version uint16) []byte { 524 buffer := make([]byte, 0) 525 526 // encode root hash (size and data) 527 buffer = utils.AppendUint16(buffer, uint16(len(t.RootHash))) 528 buffer = append(buffer, t.RootHash[:]...) 529 530 // encode number of paths 531 buffer = utils.AppendUint32(buffer, uint32(t.Size())) 532 533 if t.Size() == 0 { 534 return buffer 535 } 536 537 // encode paths 538 // encode path size (assuming all paths are the same size) 539 buffer = utils.AppendUint16(buffer, uint16(PathLen)) 540 for _, path := range t.Paths { 541 buffer = append(buffer, path[:]...) 542 } 543 544 // we assume same number of payloads 545 // encode payloads 546 for _, pl := range t.Payloads { 547 encPl := encodePayload(pl, version) 548 buffer = utils.AppendUint32(buffer, uint32(len(encPl))) 549 buffer = append(buffer, encPl...) 550 } 551 552 return buffer 553 } 554 555 // DecodeTrieUpdate construct a trie update from an encoded byte slice 556 func DecodeTrieUpdate(encodedTrieUpdate []byte) (*TrieUpdate, error) { 557 // if empty don't decode 558 if len(encodedTrieUpdate) == 0 { 559 return nil, nil 560 } 561 // check the enc dec version 562 rest, version, err := CheckVersion(encodedTrieUpdate, TrieUpdateVersion) 563 if err != nil { 564 return nil, fmt.Errorf("error decoding trie update: %w", err) 565 } 566 // check the encoding type 567 rest, err = CheckType(rest, TypeTrieUpdate) 568 if err != nil { 569 return nil, fmt.Errorf("error decoding trie update: %w", err) 570 } 571 return decodeTrieUpdate(rest, version) 572 } 573 574 func decodeTrieUpdate(inp []byte, version uint16) (*TrieUpdate, error) { 575 576 // decode root hash 577 rhSize, rest, err := utils.ReadUint16(inp) 578 if err != nil { 579 return nil, fmt.Errorf("error decoding trie update: %w", err) 580 } 581 582 rhBytes, rest, err := utils.ReadSlice(rest, int(rhSize)) 583 if err != nil { 584 return nil, fmt.Errorf("error decoding trie update: %w", err) 585 } 586 rh, err := ToRootHash(rhBytes) 587 if err != nil { 588 return nil, fmt.Errorf("decode trie update failed: %w", err) 589 } 590 591 // decode number of paths 592 numOfPaths, rest, err := utils.ReadUint32(rest) 593 if err != nil { 594 return nil, fmt.Errorf("error decoding trie update: %w", err) 595 } 596 597 // decode path size 598 pathSize, rest, err := utils.ReadUint16(rest) 599 if err != nil { 600 return nil, fmt.Errorf("error decoding trie update: %w", err) 601 } 602 603 paths := make([]Path, numOfPaths) 604 payloads := make([]*Payload, numOfPaths) 605 606 var path Path 607 var encPath []byte 608 for i := 0; i < int(numOfPaths); i++ { 609 encPath, rest, err = utils.ReadSlice(rest, int(pathSize)) 610 if err != nil { 611 return nil, fmt.Errorf("error decoding trie update: %w", err) 612 } 613 path, err = ToPath(encPath) 614 if err != nil { 615 return nil, fmt.Errorf("error decoding trie update: %w", err) 616 } 617 paths[i] = path 618 } 619 620 var payloadSize uint32 621 var encPayload []byte 622 var payload *Payload 623 624 for i := 0; i < int(numOfPaths); i++ { 625 payloadSize, rest, err = utils.ReadUint32(rest) 626 if err != nil { 627 return nil, fmt.Errorf("error decoding trie update: %w", err) 628 } 629 encPayload, rest, err = utils.ReadSlice(rest, int(payloadSize)) 630 if err != nil { 631 return nil, fmt.Errorf("error decoding trie update: %w", err) 632 } 633 // Decode payload (zerocopy) 634 payload, err = decodePayload(encPayload, true, version) 635 if err != nil { 636 return nil, fmt.Errorf("error decoding trie update: %w", err) 637 } 638 payloads[i] = payload 639 } 640 return &TrieUpdate{RootHash: rh, Paths: paths, Payloads: payloads}, nil 641 } 642 643 // EncodeTrieProof encodes the content of a proof into a byte slice 644 func EncodeTrieProof(p *TrieProof) []byte { 645 if p == nil { 646 return []byte{} 647 } 648 // encode version 649 buffer := utils.AppendUint16([]byte{}, TrieProofVersion) 650 651 // encode proof entity type 652 buffer = utils.AppendUint8(buffer, TypeProof) 653 654 // append encoded proof content 655 proof := encodeTrieProof(p, TrieProofVersion) 656 buffer = append(buffer, proof...) 657 658 return buffer 659 } 660 661 func encodeTrieProof(p *TrieProof, version uint16) []byte { 662 // first byte is reserved for inclusion flag 663 buffer := make([]byte, 1) 664 if p.Inclusion { 665 // set the first bit to 1 if it is an inclusion proof 666 buffer[0] |= 1 << 7 667 } 668 669 // steps are encoded as a single byte 670 buffer = utils.AppendUint8(buffer, p.Steps) 671 672 // include flags size and content 673 buffer = utils.AppendUint8(buffer, uint8(len(p.Flags))) 674 buffer = append(buffer, p.Flags...) 675 676 // include path size and content 677 buffer = utils.AppendUint16(buffer, uint16(PathLen)) 678 buffer = append(buffer, p.Path[:]...) 679 680 // include encoded payload size and content 681 encPayload := encodePayload(p.Payload, version) 682 buffer = utils.AppendUint64(buffer, uint64(len(encPayload))) 683 buffer = append(buffer, encPayload...) 684 685 // and finally include all interims (hash values) 686 // number of interims 687 buffer = utils.AppendUint8(buffer, uint8(len(p.Interims))) 688 for _, inter := range p.Interims { 689 buffer = utils.AppendUint16(buffer, uint16(len(inter))) 690 buffer = append(buffer, inter[:]...) 691 } 692 693 return buffer 694 } 695 696 // DecodeTrieProof construct a proof from an encoded byte slice 697 func DecodeTrieProof(encodedProof []byte) (*TrieProof, error) { 698 // check the enc dec version 699 rest, version, err := CheckVersion(encodedProof, TrieProofVersion) 700 if err != nil { 701 return nil, fmt.Errorf("error decoding proof: %w", err) 702 } 703 // check the encoding type 704 rest, err = CheckType(rest, TypeProof) 705 if err != nil { 706 return nil, fmt.Errorf("error decoding proof: %w", err) 707 } 708 return decodeTrieProof(rest, version) 709 } 710 711 func decodeTrieProof(inp []byte, version uint16) (*TrieProof, error) { 712 pInst := NewTrieProof() 713 714 // Inclusion flag 715 byteInclusion, rest, err := utils.ReadSlice(inp, 1) 716 if err != nil { 717 return nil, fmt.Errorf("error decoding proof: %w", err) 718 } 719 pInst.Inclusion = bitutils.ReadBit(byteInclusion, 0) == 1 720 721 // read steps 722 steps, rest, err := utils.ReadUint8(rest) 723 if err != nil { 724 return nil, fmt.Errorf("error decoding proof: %w", err) 725 } 726 pInst.Steps = steps 727 728 // read flags 729 flagsSize, rest, err := utils.ReadUint8(rest) 730 if err != nil { 731 return nil, fmt.Errorf("error decoding proof: %w", err) 732 } 733 flags, rest, err := utils.ReadSlice(rest, int(flagsSize)) 734 if err != nil { 735 return nil, fmt.Errorf("error decoding proof: %w", err) 736 } 737 pInst.Flags = flags 738 739 // read path 740 pathSize, rest, err := utils.ReadUint16(rest) 741 if err != nil { 742 return nil, fmt.Errorf("error decoding proof: %w", err) 743 } 744 path, rest, err := utils.ReadSlice(rest, int(pathSize)) 745 if err != nil { 746 return nil, fmt.Errorf("error decoding proof: %w", err) 747 } 748 pInst.Path, err = ToPath(path) 749 if err != nil { 750 return nil, fmt.Errorf("error decoding proof: %w", err) 751 } 752 753 // read payload 754 encPayloadSize, rest, err := utils.ReadUint64(rest) 755 if err != nil { 756 return nil, fmt.Errorf("error decoding proof: %w", err) 757 } 758 encPayload, rest, err := utils.ReadSlice(rest, int(encPayloadSize)) 759 if err != nil { 760 return nil, fmt.Errorf("error decoding proof: %w", err) 761 } 762 // Decode payload (zerocopy) 763 payload, err := decodePayload(encPayload, true, version) 764 if err != nil { 765 return nil, fmt.Errorf("error decoding proof: %w", err) 766 } 767 pInst.Payload = payload 768 769 // read interims 770 interimsLen, rest, err := utils.ReadUint8(rest) 771 if err != nil { 772 return nil, fmt.Errorf("error decoding proof: %w", err) 773 } 774 775 interims := make([]hash.Hash, interimsLen) 776 777 var interimSize uint16 778 var interim hash.Hash 779 var interimBytes []byte 780 781 for i := 0; i < int(interimsLen); i++ { 782 interimSize, rest, err = utils.ReadUint16(rest) 783 if err != nil { 784 return nil, fmt.Errorf("error decoding proof: %w", err) 785 } 786 787 interimBytes, rest, err = utils.ReadSlice(rest, int(interimSize)) 788 if err != nil { 789 return nil, fmt.Errorf("error decoding proof: %w", err) 790 } 791 interim, err = hash.ToHash(interimBytes) 792 if err != nil { 793 return nil, fmt.Errorf("error decoding proof: %w", err) 794 } 795 796 interims[i] = interim 797 } 798 pInst.Interims = interims 799 800 return pInst, nil 801 } 802 803 // EncodeTrieBatchProof encodes a batch proof into a byte slice 804 func EncodeTrieBatchProof(bp *TrieBatchProof) []byte { 805 if bp == nil { 806 return []byte{} 807 } 808 // encode version 809 buffer := utils.AppendUint16([]byte{}, TrieBatchProofVersion) 810 811 // encode batch proof entity type 812 buffer = utils.AppendUint8(buffer, TypeBatchProof) 813 // encode batch proof content 814 buffer = append(buffer, encodeTrieBatchProof(bp, TrieBatchProofVersion)...) 815 816 return buffer 817 } 818 819 // encodeBatchProof encodes a batch proof into a byte slice 820 func encodeTrieBatchProof(bp *TrieBatchProof, version uint16) []byte { 821 buffer := make([]byte, 0) 822 // encode number of proofs 823 buffer = utils.AppendUint32(buffer, uint32(len(bp.Proofs))) 824 // iterate over proofs 825 for _, p := range bp.Proofs { 826 // encode the proof 827 encP := encodeTrieProof(p, version) 828 // encode the len of the encoded proof 829 buffer = utils.AppendUint64(buffer, uint64(len(encP))) 830 // append the encoded proof 831 buffer = append(buffer, encP...) 832 } 833 return buffer 834 } 835 836 // DecodeTrieBatchProof constructs a batch proof from an encoded byte slice 837 func DecodeTrieBatchProof(encodedBatchProof []byte) (*TrieBatchProof, error) { 838 // check the enc dec version 839 rest, version, err := CheckVersion(encodedBatchProof, TrieBatchProofVersion) 840 if err != nil { 841 return nil, fmt.Errorf("error decoding batch proof: %w", err) 842 } 843 // check the encoding type 844 rest, err = CheckType(rest, TypeBatchProof) 845 if err != nil { 846 return nil, fmt.Errorf("error decoding batch proof: %w", err) 847 } 848 849 // decode the batch proof content 850 bp, err := decodeTrieBatchProof(rest, version) 851 if err != nil { 852 return nil, fmt.Errorf("error decoding batch proof: %w", err) 853 } 854 return bp, nil 855 } 856 857 func decodeTrieBatchProof(inp []byte, version uint16) (*TrieBatchProof, error) { 858 bp := NewTrieBatchProof() 859 // number of proofs 860 numOfProofs, rest, err := utils.ReadUint32(inp) 861 if err != nil { 862 return nil, fmt.Errorf("error decoding batch proof (content): %w", err) 863 } 864 865 for i := 0; i < int(numOfProofs); i++ { 866 var encProofSize uint64 867 var encProof []byte 868 // read encoded proof size 869 encProofSize, rest, err = utils.ReadUint64(rest) 870 if err != nil { 871 return nil, fmt.Errorf("error decoding batch proof (content): %w", err) 872 } 873 874 // read encoded proof 875 encProof, rest, err = utils.ReadSlice(rest, int(encProofSize)) 876 if err != nil { 877 return nil, fmt.Errorf("error decoding batch proof (content): %w", err) 878 } 879 880 // decode encoded proof 881 proof, err := decodeTrieProof(encProof, version) 882 if err != nil { 883 return nil, fmt.Errorf("error decoding batch proof (content): %w", err) 884 } 885 bp.Proofs = append(bp.Proofs, proof) 886 } 887 return bp, nil 888 }