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  }