github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/ledger/trie_encoder.go (about)

     1  package ledger
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/onflow/flow-go/ledger/common/bitutils"
     7  	"github.com/onflow/flow-go/ledger/common/hash"
     8  	"github.com/onflow/flow-go/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  	kpt, kpv, err := decodeKeyPart(rest, true, version)
   152  	if err != nil {
   153  		return nil, fmt.Errorf("error decoding key part: %w", err)
   154  	}
   155  
   156  	return &KeyPart{Type: kpt, Value: kpv}, 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) (uint16, []byte, 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 0, nil, fmt.Errorf("error decoding key part (content): %w", err)
   166  	}
   167  	if zeroCopy {
   168  		return kpt, kpv, nil
   169  	}
   170  	v := make([]byte, len(kpv))
   171  	copy(v, kpv)
   172  	return kpt, 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  func decodeKeyPartValueByType(inp []byte, typ uint16, zeroCopy bool, version uint16) ([]byte, bool, error) {
   244  	// Read number of key parts
   245  	numOfParts, rest, err := utils.ReadUint16(inp)
   246  	if err != nil {
   247  		return nil, false, fmt.Errorf("error decoding number of key parts: %w", err)
   248  	}
   249  
   250  	for i := 0; i < int(numOfParts); i++ {
   251  		var kpt uint16
   252  		var kpv []byte
   253  
   254  		kpt, kpv, rest, err = decodeKeyPartWithEncodedSizeInfo(rest, zeroCopy, version)
   255  		if err != nil {
   256  			return nil, false, err
   257  		}
   258  		if kpt == typ {
   259  			return kpv, true, nil
   260  		}
   261  	}
   262  
   263  	return nil, false, nil
   264  }
   265  
   266  func decodeKeyPartWithEncodedSizeInfo(
   267  	inp []byte,
   268  	zeroCopy bool,
   269  	version uint16,
   270  ) (
   271  	// kp KeyPart,
   272  	kpt uint16,
   273  	kpv []byte,
   274  	rest []byte,
   275  	err error,
   276  ) {
   277  
   278  	// Read encoded key part size
   279  	kpEncSize, rest, err := utils.ReadUint32(inp)
   280  	if err != nil {
   281  		return 0, nil, nil, fmt.Errorf("error decoding key part: %w", err)
   282  	}
   283  
   284  	// Read encoded key part
   285  	var kpEnc []byte
   286  	kpEnc, rest, err = utils.ReadSlice(rest, int(kpEncSize))
   287  	if err != nil {
   288  		return 0, nil, nil, fmt.Errorf("error decoding key part: %w", err)
   289  	}
   290  
   291  	// Decode encoded key part
   292  	kpType, kpValue, err := decodeKeyPart(kpEnc, zeroCopy, version)
   293  	if err != nil {
   294  		return 0, nil, nil, fmt.Errorf("error decoding key part: %w", err)
   295  	}
   296  
   297  	return kpType, kpValue, rest, nil
   298  }
   299  
   300  // decodeKey decodes inp into Key. If zeroCopy is true, returned key
   301  // references data in inp.  Otherwise, it is copied.
   302  func decodeKey(inp []byte, zeroCopy bool, version uint16) (*Key, error) {
   303  	key := &Key{}
   304  
   305  	numOfParts, rest, err := utils.ReadUint16(inp)
   306  	if err != nil {
   307  		return nil, fmt.Errorf("error decoding key (content): %w", err)
   308  	}
   309  
   310  	if numOfParts == 0 {
   311  		return key, nil
   312  	}
   313  
   314  	key.KeyParts = make([]KeyPart, numOfParts)
   315  
   316  	for i := 0; i < int(numOfParts); i++ {
   317  		var kpt uint16
   318  		var kpv []byte
   319  
   320  		kpt, kpv, rest, err = decodeKeyPartWithEncodedSizeInfo(rest, zeroCopy, version)
   321  		if err != nil {
   322  			return nil, err
   323  		}
   324  
   325  		key.KeyParts[i] = KeyPart{kpt, kpv}
   326  	}
   327  	return key, nil
   328  }
   329  
   330  // EncodeValue encodes a value into a byte slice
   331  func EncodeValue(v Value) []byte {
   332  	// encode EncodingDecodingType
   333  	buffer := utils.AppendUint16([]byte{}, PayloadVersion)
   334  
   335  	// encode key entity type
   336  	buffer = utils.AppendUint8(buffer, TypeValue)
   337  
   338  	// encode value
   339  	buffer = append(buffer, encodeValue(v, PayloadVersion)...)
   340  
   341  	return buffer
   342  }
   343  
   344  func encodeValue(v Value, _ uint16) []byte {
   345  	return v
   346  }
   347  
   348  func encodeAndAppendValue(buffer []byte, v Value, _ uint16) []byte {
   349  	return append(buffer, v...)
   350  }
   351  
   352  func encodedValueLength(v Value, _ uint16) int {
   353  	return len(v)
   354  }
   355  
   356  // DecodeValue constructs a ledger value using an encoded byte slice
   357  func DecodeValue(encodedValue []byte) (Value, error) {
   358  	// check enc dec version
   359  	rest, _, err := CheckVersion(encodedValue, PayloadVersion)
   360  	if err != nil {
   361  		return nil, err
   362  	}
   363  
   364  	// check the encoding type
   365  	rest, err = CheckType(rest, TypeValue)
   366  	if err != nil {
   367  		return nil, err
   368  	}
   369  
   370  	return rest, nil
   371  }
   372  
   373  // EncodePayload encodes a ledger payload
   374  func EncodePayload(p *Payload) []byte {
   375  	if p == nil {
   376  		return []byte{}
   377  	}
   378  	// encode EncodingDecodingType
   379  	buffer := utils.AppendUint16([]byte{}, PayloadVersion)
   380  
   381  	// encode key entity type
   382  	buffer = utils.AppendUint8(buffer, TypePayload)
   383  
   384  	// append encoded payload content
   385  	buffer = append(buffer, encodePayload(p, PayloadVersion)...)
   386  	return buffer
   387  }
   388  
   389  // EncodeAndAppendPayloadWithoutPrefix encodes a ledger payload
   390  // without prefix (version and type) and appends to buffer.
   391  // If payload is nil, unmodified buffer is returned.
   392  func EncodeAndAppendPayloadWithoutPrefix(buffer []byte, p *Payload, version uint16) []byte {
   393  	if p == nil {
   394  		return buffer
   395  	}
   396  	return encodeAndAppendPayload(buffer, p, version)
   397  }
   398  
   399  func EncodedPayloadLengthWithoutPrefix(p *Payload, version uint16) int {
   400  	return encodedPayloadLength(p, version)
   401  }
   402  
   403  func encodePayload(p *Payload, version uint16) []byte {
   404  	buffer := make([]byte, 0, encodedPayloadLength(p, version))
   405  	return encodeAndAppendPayload(buffer, p, version)
   406  }
   407  
   408  // convertEncodedPayloadKey returns encoded payload key in toVersion
   409  // converted from encoded payload key in fromVersion.
   410  func convertEncodedPayloadKey(key []byte, fromVersion uint16, toVersion uint16) []byte {
   411  	// No conversion is needed for now because
   412  	// payload key encoding version 0 is the same as version 1.
   413  	return key
   414  }
   415  
   416  func encodeAndAppendPayload(buffer []byte, p *Payload, version uint16) []byte {
   417  
   418  	// convert payload encoded key from PayloadVersion to version.
   419  	encKey := convertEncodedPayloadKey(p.encKey, PayloadVersion, version)
   420  
   421  	// encode encoded key size
   422  	buffer = utils.AppendUint32(buffer, uint32(len(encKey)))
   423  
   424  	// append encoded key
   425  	buffer = append(buffer, encKey...)
   426  
   427  	// encode encoded value size
   428  	encodedValueLen := encodedValueLength(p.Value(), version)
   429  	switch version {
   430  	case 0:
   431  		// In version 0, encoded value length is encoded as 8 bytes.
   432  		buffer = utils.AppendUint64(buffer, uint64(encodedValueLen))
   433  	default:
   434  		// In version 1 and later, encoded value length is encoded as 4 bytes.
   435  		buffer = utils.AppendUint32(buffer, uint32(encodedValueLen))
   436  	}
   437  
   438  	// encode value
   439  	buffer = encodeAndAppendValue(buffer, p.Value(), version)
   440  
   441  	return buffer
   442  }
   443  
   444  func encodedPayloadLength(p *Payload, version uint16) int {
   445  	if p == nil {
   446  		return 0
   447  	}
   448  
   449  	// Error isn't checked here because encoded key will be used directly
   450  	// in later commit and no error will be returned.
   451  	k, _ := p.Key()
   452  
   453  	switch version {
   454  	case 0:
   455  		// In version 0, payload is encoded as:
   456  		//   encode key length (4 bytes) + encoded key +
   457  		//   encoded value length (8 bytes) + encode value
   458  		return 4 + encodedKeyLength(&k, version) + 8 + encodedValueLength(p.Value(), version)
   459  	default:
   460  		// In version 1 and later, payload is encoded as:
   461  		//   encode key length (4 bytes) + encoded key +
   462  		//   encoded value length (4 bytes) + encode value
   463  		return 4 + encodedKeyLength(&k, version) + 4 + encodedValueLength(p.Value(), version)
   464  	}
   465  }
   466  
   467  // DecodePayload construct a payload from an encoded byte slice
   468  func DecodePayload(encodedPayload []byte) (*Payload, error) {
   469  	// if empty don't decode
   470  	if len(encodedPayload) == 0 {
   471  		return nil, nil
   472  	}
   473  	// check the enc dec version
   474  	rest, version, err := CheckVersion(encodedPayload, PayloadVersion)
   475  	if err != nil {
   476  		return nil, fmt.Errorf("error decoding payload: %w", err)
   477  	}
   478  	// check the encoding type
   479  	rest, err = CheckType(rest, TypePayload)
   480  	if err != nil {
   481  		return nil, fmt.Errorf("error decoding payload: %w", err)
   482  	}
   483  	// decode payload (zerocopy)
   484  	return decodePayload(rest, true, version)
   485  }
   486  
   487  // DecodePayloadWithoutPrefix constructs a payload from encoded byte slice
   488  // without prefix (version and type). If zeroCopy is true, returned payload
   489  // references data in encodedPayload. Otherwise, it is copied.
   490  func DecodePayloadWithoutPrefix(encodedPayload []byte, zeroCopy bool, version uint16) (*Payload, error) {
   491  	// if empty don't decode
   492  	if len(encodedPayload) == 0 {
   493  		return nil, nil
   494  	}
   495  	return decodePayload(encodedPayload, zeroCopy, version)
   496  }
   497  
   498  // decodePayload decodes inp into payload.  If zeroCopy is true,
   499  // returned payload references data in inp.  Otherwise, it is copied.
   500  func decodePayload(inp []byte, zeroCopy bool, version uint16) (*Payload, error) {
   501  
   502  	// read encoded key size
   503  	encKeySize, rest, err := utils.ReadUint32(inp)
   504  	if err != nil {
   505  		return nil, fmt.Errorf("error decoding payload: %w", err)
   506  	}
   507  
   508  	// read encoded key
   509  	ek, rest, err := utils.ReadSlice(rest, int(encKeySize))
   510  	if err != nil {
   511  		return nil, fmt.Errorf("error decoding payload: %w", err)
   512  	}
   513  
   514  	// convert payload encoded key from version to PayloadVersion.
   515  	encKey := convertEncodedPayloadKey(ek, version, PayloadVersion)
   516  
   517  	// read encoded value size
   518  	var encValueSize int
   519  	switch version {
   520  	case 0:
   521  		var size uint64
   522  		size, rest, err = utils.ReadUint64(rest)
   523  		encValueSize = int(size)
   524  	default:
   525  		var size uint32
   526  		size, rest, err = utils.ReadUint32(rest)
   527  		encValueSize = int(size)
   528  	}
   529  
   530  	if err != nil {
   531  		return nil, fmt.Errorf("error decoding payload: %w", err)
   532  	}
   533  
   534  	// read encoded value
   535  	encValue, _, err := utils.ReadSlice(rest, encValueSize)
   536  	if err != nil {
   537  		return nil, fmt.Errorf("error decoding payload: %w", err)
   538  	}
   539  
   540  	if zeroCopy {
   541  		return &Payload{encKey, encValue}, nil
   542  	}
   543  
   544  	k := make([]byte, len(encKey))
   545  	copy(k, encKey)
   546  	v := make([]byte, len(encValue))
   547  	copy(v, encValue)
   548  	return &Payload{k, v}, nil
   549  }
   550  
   551  // EncodeTrieUpdate encodes a trie update struct
   552  func EncodeTrieUpdate(t *TrieUpdate) []byte {
   553  	if t == nil {
   554  		return []byte{}
   555  	}
   556  	// encode EncodingDecodingType
   557  	buffer := utils.AppendUint16([]byte{}, TrieUpdateVersion)
   558  
   559  	// encode key entity type
   560  	buffer = utils.AppendUint8(buffer, TypeTrieUpdate)
   561  
   562  	// append encoded payload content
   563  	buffer = append(buffer, encodeTrieUpdate(t, TrieUpdateVersion)...)
   564  
   565  	return buffer
   566  }
   567  
   568  func encodeTrieUpdate(t *TrieUpdate, version uint16) []byte {
   569  	buffer := make([]byte, 0)
   570  
   571  	// encode root hash (size and data)
   572  	buffer = utils.AppendUint16(buffer, uint16(len(t.RootHash)))
   573  	buffer = append(buffer, t.RootHash[:]...)
   574  
   575  	// encode number of paths
   576  	buffer = utils.AppendUint32(buffer, uint32(t.Size()))
   577  
   578  	if t.Size() == 0 {
   579  		return buffer
   580  	}
   581  
   582  	// encode paths
   583  	// encode path size (assuming all paths are the same size)
   584  	buffer = utils.AppendUint16(buffer, uint16(PathLen))
   585  	for _, path := range t.Paths {
   586  		buffer = append(buffer, path[:]...)
   587  	}
   588  
   589  	// we assume same number of payloads
   590  	// encode payloads
   591  	for _, pl := range t.Payloads {
   592  		encPl := encodePayload(pl, version)
   593  		buffer = utils.AppendUint32(buffer, uint32(len(encPl)))
   594  		buffer = append(buffer, encPl...)
   595  	}
   596  
   597  	return buffer
   598  }
   599  
   600  // DecodeTrieUpdate construct a trie update from an encoded byte slice
   601  func DecodeTrieUpdate(encodedTrieUpdate []byte) (*TrieUpdate, error) {
   602  	// if empty don't decode
   603  	if len(encodedTrieUpdate) == 0 {
   604  		return nil, nil
   605  	}
   606  	// check the enc dec version
   607  	rest, version, err := CheckVersion(encodedTrieUpdate, TrieUpdateVersion)
   608  	if err != nil {
   609  		return nil, fmt.Errorf("error decoding trie update: %w", err)
   610  	}
   611  	// check the encoding type
   612  	rest, err = CheckType(rest, TypeTrieUpdate)
   613  	if err != nil {
   614  		return nil, fmt.Errorf("error decoding trie update: %w", err)
   615  	}
   616  	return decodeTrieUpdate(rest, version)
   617  }
   618  
   619  func decodeTrieUpdate(inp []byte, version uint16) (*TrieUpdate, error) {
   620  
   621  	// decode root hash
   622  	rhSize, rest, err := utils.ReadUint16(inp)
   623  	if err != nil {
   624  		return nil, fmt.Errorf("error decoding trie update: %w", err)
   625  	}
   626  
   627  	rhBytes, rest, err := utils.ReadSlice(rest, int(rhSize))
   628  	if err != nil {
   629  		return nil, fmt.Errorf("error decoding trie update: %w", err)
   630  	}
   631  	rh, err := ToRootHash(rhBytes)
   632  	if err != nil {
   633  		return nil, fmt.Errorf("decode trie update failed: %w", err)
   634  	}
   635  
   636  	// decode number of paths
   637  	numOfPaths, rest, err := utils.ReadUint32(rest)
   638  	if err != nil {
   639  		return nil, fmt.Errorf("error decoding trie update: %w", err)
   640  	}
   641  
   642  	// decode path size
   643  	pathSize, rest, err := utils.ReadUint16(rest)
   644  	if err != nil {
   645  		return nil, fmt.Errorf("error decoding trie update: %w", err)
   646  	}
   647  
   648  	paths := make([]Path, numOfPaths)
   649  	payloads := make([]*Payload, numOfPaths)
   650  
   651  	var path Path
   652  	var encPath []byte
   653  	for i := 0; i < int(numOfPaths); i++ {
   654  		encPath, rest, err = utils.ReadSlice(rest, int(pathSize))
   655  		if err != nil {
   656  			return nil, fmt.Errorf("error decoding trie update: %w", err)
   657  		}
   658  		path, err = ToPath(encPath)
   659  		if err != nil {
   660  			return nil, fmt.Errorf("error decoding trie update: %w", err)
   661  		}
   662  		paths[i] = path
   663  	}
   664  
   665  	var payloadSize uint32
   666  	var encPayload []byte
   667  	var payload *Payload
   668  
   669  	for i := 0; i < int(numOfPaths); i++ {
   670  		payloadSize, rest, err = utils.ReadUint32(rest)
   671  		if err != nil {
   672  			return nil, fmt.Errorf("error decoding trie update: %w", err)
   673  		}
   674  		encPayload, rest, err = utils.ReadSlice(rest, int(payloadSize))
   675  		if err != nil {
   676  			return nil, fmt.Errorf("error decoding trie update: %w", err)
   677  		}
   678  		// Decode payload (zerocopy)
   679  		payload, err = decodePayload(encPayload, true, version)
   680  		if err != nil {
   681  			return nil, fmt.Errorf("error decoding trie update: %w", err)
   682  		}
   683  		payloads[i] = payload
   684  	}
   685  	return &TrieUpdate{RootHash: rh, Paths: paths, Payloads: payloads}, nil
   686  }
   687  
   688  // EncodeTrieProof encodes the content of a proof into a byte slice
   689  func EncodeTrieProof(p *TrieProof) []byte {
   690  	if p == nil {
   691  		return []byte{}
   692  	}
   693  	// encode version
   694  	buffer := utils.AppendUint16([]byte{}, TrieProofVersion)
   695  
   696  	// encode proof entity type
   697  	buffer = utils.AppendUint8(buffer, TypeProof)
   698  
   699  	// append encoded proof content
   700  	proof := encodeTrieProof(p, TrieProofVersion)
   701  	buffer = append(buffer, proof...)
   702  
   703  	return buffer
   704  }
   705  
   706  func encodeTrieProof(p *TrieProof, version uint16) []byte {
   707  	// first byte is reserved for inclusion flag
   708  	buffer := make([]byte, 1)
   709  	if p.Inclusion {
   710  		// set the first bit to 1 if it is an inclusion proof
   711  		buffer[0] |= 1 << 7
   712  	}
   713  
   714  	// steps are encoded as a single byte
   715  	buffer = utils.AppendUint8(buffer, p.Steps)
   716  
   717  	// include flags size and content
   718  	buffer = utils.AppendUint8(buffer, uint8(len(p.Flags)))
   719  	buffer = append(buffer, p.Flags...)
   720  
   721  	// include path size and content
   722  	buffer = utils.AppendUint16(buffer, uint16(PathLen))
   723  	buffer = append(buffer, p.Path[:]...)
   724  
   725  	// include encoded payload size and content
   726  	encPayload := encodePayload(p.Payload, version)
   727  	buffer = utils.AppendUint64(buffer, uint64(len(encPayload)))
   728  	buffer = append(buffer, encPayload...)
   729  
   730  	// and finally include all interims (hash values)
   731  	// number of interims
   732  	buffer = utils.AppendUint8(buffer, uint8(len(p.Interims)))
   733  	for _, inter := range p.Interims {
   734  		buffer = utils.AppendUint16(buffer, uint16(len(inter)))
   735  		buffer = append(buffer, inter[:]...)
   736  	}
   737  
   738  	return buffer
   739  }
   740  
   741  // DecodeTrieProof construct a proof from an encoded byte slice
   742  func DecodeTrieProof(encodedProof []byte) (*TrieProof, error) {
   743  	// check the enc dec version
   744  	rest, version, err := CheckVersion(encodedProof, TrieProofVersion)
   745  	if err != nil {
   746  		return nil, fmt.Errorf("error decoding proof: %w", err)
   747  	}
   748  	// check the encoding type
   749  	rest, err = CheckType(rest, TypeProof)
   750  	if err != nil {
   751  		return nil, fmt.Errorf("error decoding proof: %w", err)
   752  	}
   753  	return decodeTrieProof(rest, version)
   754  }
   755  
   756  func decodeTrieProof(inp []byte, version uint16) (*TrieProof, error) {
   757  	pInst := NewTrieProof()
   758  
   759  	// Inclusion flag
   760  	byteInclusion, rest, err := utils.ReadSlice(inp, 1)
   761  	if err != nil {
   762  		return nil, fmt.Errorf("error decoding proof: %w", err)
   763  	}
   764  	pInst.Inclusion = bitutils.ReadBit(byteInclusion, 0) == 1
   765  
   766  	// read steps
   767  	steps, rest, err := utils.ReadUint8(rest)
   768  	if err != nil {
   769  		return nil, fmt.Errorf("error decoding proof: %w", err)
   770  	}
   771  	pInst.Steps = steps
   772  
   773  	// read flags
   774  	flagsSize, rest, err := utils.ReadUint8(rest)
   775  	if err != nil {
   776  		return nil, fmt.Errorf("error decoding proof: %w", err)
   777  	}
   778  	flags, rest, err := utils.ReadSlice(rest, int(flagsSize))
   779  	if err != nil {
   780  		return nil, fmt.Errorf("error decoding proof: %w", err)
   781  	}
   782  	pInst.Flags = flags
   783  
   784  	// read path
   785  	pathSize, rest, err := utils.ReadUint16(rest)
   786  	if err != nil {
   787  		return nil, fmt.Errorf("error decoding proof: %w", err)
   788  	}
   789  	path, rest, err := utils.ReadSlice(rest, int(pathSize))
   790  	if err != nil {
   791  		return nil, fmt.Errorf("error decoding proof: %w", err)
   792  	}
   793  	pInst.Path, err = ToPath(path)
   794  	if err != nil {
   795  		return nil, fmt.Errorf("error decoding proof: %w", err)
   796  	}
   797  
   798  	// read payload
   799  	encPayloadSize, rest, err := utils.ReadUint64(rest)
   800  	if err != nil {
   801  		return nil, fmt.Errorf("error decoding proof: %w", err)
   802  	}
   803  	encPayload, rest, err := utils.ReadSlice(rest, int(encPayloadSize))
   804  	if err != nil {
   805  		return nil, fmt.Errorf("error decoding proof: %w", err)
   806  	}
   807  	// Decode payload (zerocopy)
   808  	payload, err := decodePayload(encPayload, true, version)
   809  	if err != nil {
   810  		return nil, fmt.Errorf("error decoding proof: %w", err)
   811  	}
   812  	pInst.Payload = payload
   813  
   814  	// read interims
   815  	interimsLen, rest, err := utils.ReadUint8(rest)
   816  	if err != nil {
   817  		return nil, fmt.Errorf("error decoding proof: %w", err)
   818  	}
   819  
   820  	interims := make([]hash.Hash, interimsLen)
   821  
   822  	var interimSize uint16
   823  	var interim hash.Hash
   824  	var interimBytes []byte
   825  
   826  	for i := 0; i < int(interimsLen); i++ {
   827  		interimSize, rest, err = utils.ReadUint16(rest)
   828  		if err != nil {
   829  			return nil, fmt.Errorf("error decoding proof: %w", err)
   830  		}
   831  
   832  		interimBytes, rest, err = utils.ReadSlice(rest, int(interimSize))
   833  		if err != nil {
   834  			return nil, fmt.Errorf("error decoding proof: %w", err)
   835  		}
   836  		interim, err = hash.ToHash(interimBytes)
   837  		if err != nil {
   838  			return nil, fmt.Errorf("error decoding proof: %w", err)
   839  		}
   840  
   841  		interims[i] = interim
   842  	}
   843  	pInst.Interims = interims
   844  
   845  	return pInst, nil
   846  }
   847  
   848  // EncodeTrieBatchProof encodes a batch proof into a byte slice
   849  func EncodeTrieBatchProof(bp *TrieBatchProof) []byte {
   850  	if bp == nil {
   851  		return []byte{}
   852  	}
   853  	// encode version
   854  	buffer := utils.AppendUint16([]byte{}, TrieBatchProofVersion)
   855  
   856  	// encode batch proof entity type
   857  	buffer = utils.AppendUint8(buffer, TypeBatchProof)
   858  	// encode batch proof content
   859  	buffer = append(buffer, encodeTrieBatchProof(bp, TrieBatchProofVersion)...)
   860  
   861  	return buffer
   862  }
   863  
   864  // encodeBatchProof encodes a batch proof into a byte slice
   865  func encodeTrieBatchProof(bp *TrieBatchProof, version uint16) []byte {
   866  	buffer := make([]byte, 0)
   867  	// encode number of proofs
   868  	buffer = utils.AppendUint32(buffer, uint32(len(bp.Proofs)))
   869  	// iterate over proofs
   870  	for _, p := range bp.Proofs {
   871  		// encode the proof
   872  		encP := encodeTrieProof(p, version)
   873  		// encode the len of the encoded proof
   874  		buffer = utils.AppendUint64(buffer, uint64(len(encP)))
   875  		// append the encoded proof
   876  		buffer = append(buffer, encP...)
   877  	}
   878  	return buffer
   879  }
   880  
   881  // DecodeTrieBatchProof constructs a batch proof from an encoded byte slice
   882  func DecodeTrieBatchProof(encodedBatchProof []byte) (*TrieBatchProof, error) {
   883  	// check the enc dec version
   884  	rest, version, err := CheckVersion(encodedBatchProof, TrieBatchProofVersion)
   885  	if err != nil {
   886  		return nil, fmt.Errorf("error decoding batch proof: %w", err)
   887  	}
   888  	// check the encoding type
   889  	rest, err = CheckType(rest, TypeBatchProof)
   890  	if err != nil {
   891  		return nil, fmt.Errorf("error decoding batch proof: %w", err)
   892  	}
   893  
   894  	// decode the batch proof content
   895  	bp, err := decodeTrieBatchProof(rest, version)
   896  	if err != nil {
   897  		return nil, fmt.Errorf("error decoding batch proof: %w", err)
   898  	}
   899  	return bp, nil
   900  }
   901  
   902  func decodeTrieBatchProof(inp []byte, version uint16) (*TrieBatchProof, error) {
   903  	bp := NewTrieBatchProof()
   904  	// number of proofs
   905  	numOfProofs, rest, err := utils.ReadUint32(inp)
   906  	if err != nil {
   907  		return nil, fmt.Errorf("error decoding batch proof (content): %w", err)
   908  	}
   909  
   910  	for i := 0; i < int(numOfProofs); i++ {
   911  		var encProofSize uint64
   912  		var encProof []byte
   913  		// read encoded proof size
   914  		encProofSize, rest, err = utils.ReadUint64(rest)
   915  		if err != nil {
   916  			return nil, fmt.Errorf("error decoding batch proof (content): %w", err)
   917  		}
   918  
   919  		// read encoded proof
   920  		encProof, rest, err = utils.ReadSlice(rest, int(encProofSize))
   921  		if err != nil {
   922  			return nil, fmt.Errorf("error decoding batch proof (content): %w", err)
   923  		}
   924  
   925  		// decode encoded proof
   926  		proof, err := decodeTrieProof(encProof, version)
   927  		if err != nil {
   928  			return nil, fmt.Errorf("error decoding batch proof (content): %w", err)
   929  		}
   930  		bp.Proofs = append(bp.Proofs, proof)
   931  	}
   932  	return bp, nil
   933  }