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

     1  package ledger
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  
    10  	"github.com/fxamacker/cbor/v2"
    11  
    12  	cryptoHash "github.com/onflow/crypto/hash"
    13  
    14  	"github.com/onflow/flow-go/ledger/common/bitutils"
    15  	"github.com/onflow/flow-go/ledger/common/hash"
    16  	"github.com/onflow/flow-go/model/flow"
    17  )
    18  
    19  // Path captures storage path of a payload;
    20  // where we store a payload in the ledger
    21  type Path hash.Hash
    22  
    23  func (p Path) MarshalJSON() ([]byte, error) {
    24  	return json.Marshal(hex.EncodeToString(p[:]))
    25  }
    26  
    27  // DummyPath is an arbitrary path value, used in function error returns.
    28  var DummyPath = Path(hash.DummyHash)
    29  
    30  // PathLen is the size of paths in bytes.
    31  const PathLen = 32
    32  
    33  // The node maximum height or the tree height.
    34  // It corresponds to the path size in bits.
    35  const NodeMaxHeight = PathLen * 8
    36  
    37  // we are currently supporting paths of a size equal to 32 bytes.
    38  // I.e. path length from the rootNode of a fully expanded tree to the leaf node is 256.
    39  // A path of length k is comprised of k+1 vertices. Hence, we need 257 default hashes.
    40  const defaultHashesNum = NodeMaxHeight + 1
    41  
    42  // array to store all default hashes
    43  var defaultHashes [defaultHashesNum]hash.Hash
    44  
    45  func init() {
    46  
    47  	// default value and default hash value for a default node
    48  	var defaultLeafHash hash.Hash
    49  	castedPointer := (*[hash.HashLen]byte)(&defaultLeafHash)
    50  	cryptoHash.ComputeSHA3_256(castedPointer, []byte("default:"))
    51  
    52  	// Creates the Default hashes from base to level height
    53  	defaultHashes[0] = defaultLeafHash
    54  	for i := 1; i < defaultHashesNum; i++ {
    55  		defaultHashes[i] = hash.HashInterNode(defaultHashes[i-1], defaultHashes[i-1])
    56  	}
    57  }
    58  
    59  // GetDefaultHashForHeight returns the default hashes of the SMT at a specified height.
    60  //
    61  // For each tree level N, there is a default hash equal to the chained
    62  // hashing of the default value N times.
    63  func GetDefaultHashForHeight(height int) hash.Hash {
    64  	return defaultHashes[height]
    65  }
    66  
    67  // ComputeCompactValue computes the value for the node considering the sub tree
    68  // to only include this value and default values. It writes the hash result to the result input.
    69  // UNCHECKED: payload!= nil
    70  func ComputeCompactValue(path hash.Hash, value []byte, nodeHeight int) hash.Hash {
    71  	// if register is unallocated: return default hash
    72  	if len(value) == 0 {
    73  		return GetDefaultHashForHeight(nodeHeight)
    74  	}
    75  
    76  	var out hash.Hash
    77  	out = hash.HashLeaf(path, value)   // we first compute the hash of the fully-expanded leaf
    78  	for h := 1; h <= nodeHeight; h++ { // then, we hash our way upwards towards the root until we hit the specified nodeHeight
    79  		// h is the height of the node, whose hash we are computing in this iteration.
    80  		// The hash is computed from the node's children at height h-1.
    81  		bit := bitutils.ReadBit(path[:], NodeMaxHeight-h)
    82  		if bit == 1 { // right branching
    83  			out = hash.HashInterNode(GetDefaultHashForHeight(h-1), out)
    84  		} else { // left branching
    85  			out = hash.HashInterNode(out, GetDefaultHashForHeight(h-1))
    86  		}
    87  	}
    88  	return out
    89  }
    90  
    91  // TrieRead captures a trie read query
    92  type TrieRead struct {
    93  	RootHash RootHash
    94  	Paths    []Path
    95  }
    96  
    97  // TrieReadSinglePayload contains trie read query for a single payload
    98  type TrieReadSingleValue struct {
    99  	RootHash RootHash
   100  	Path     Path
   101  }
   102  
   103  // TrieUpdate holds all data for a trie update
   104  type TrieUpdate struct {
   105  	RootHash RootHash
   106  	Paths    []Path
   107  	Payloads []*Payload
   108  }
   109  
   110  // Size returns number of paths in the trie update
   111  func (u *TrieUpdate) Size() int {
   112  	return len(u.Paths)
   113  }
   114  
   115  // IsEmpty returns true if key or value is not empty
   116  func (u *TrieUpdate) IsEmpty() bool {
   117  	return u.Size() == 0
   118  }
   119  
   120  func (u *TrieUpdate) String() string {
   121  	str := "Trie Update:\n "
   122  	str += "\t triehash : " + u.RootHash.String() + "\n"
   123  	for i, p := range u.Paths {
   124  		str += fmt.Sprintf("\t\t path %d : %s\n", i, p)
   125  	}
   126  	str += fmt.Sprintf("\t paths len: %d , bytesize: %d\n", len(u.Paths), len(u.Paths)*PathLen)
   127  	tp := 0
   128  	for _, p := range u.Payloads {
   129  		tp += p.Size()
   130  	}
   131  	str += fmt.Sprintf("\t total size of payloads : %d \n", tp)
   132  	return str
   133  }
   134  
   135  // Equals compares this trie update to another trie update
   136  func (u *TrieUpdate) Equals(other *TrieUpdate) bool {
   137  	if other == nil {
   138  		return false
   139  	}
   140  	if !u.RootHash.Equals(other.RootHash) {
   141  		return false
   142  	}
   143  	if len(u.Paths) != len(other.Paths) {
   144  		return false
   145  	}
   146  	for i := range u.Paths {
   147  		if !u.Paths[i].Equals(other.Paths[i]) {
   148  			return false
   149  		}
   150  	}
   151  
   152  	if len(u.Payloads) != len(other.Payloads) {
   153  		return false
   154  	}
   155  	for i := range u.Payloads {
   156  		if !u.Payloads[i].Equals(other.Payloads[i]) {
   157  			return false
   158  		}
   159  	}
   160  	return true
   161  }
   162  
   163  // RootHash captures the root hash of a trie
   164  type RootHash hash.Hash
   165  
   166  func (rh RootHash) MarshalJSON() ([]byte, error) {
   167  	return json.Marshal(rh.String())
   168  }
   169  
   170  func (rh RootHash) String() string {
   171  	return hex.EncodeToString(rh[:])
   172  }
   173  
   174  // Equals compares the root hash to another one
   175  func (rh RootHash) Equals(o RootHash) bool {
   176  	return rh == o
   177  }
   178  
   179  // ToRootHash converts a byte slice into a root hash.
   180  // It returns an error if the slice has an invalid length.
   181  func ToRootHash(rootHashBytes []byte) (RootHash, error) {
   182  	var rootHash RootHash
   183  	if len(rootHashBytes) != len(rootHash) {
   184  		return RootHash(hash.DummyHash), fmt.Errorf("expecting %d bytes but got %d bytes", len(rootHash), len(rootHashBytes))
   185  	}
   186  	copy(rootHash[:], rootHashBytes)
   187  	return rootHash, nil
   188  }
   189  
   190  func (p Path) String() string {
   191  	str := ""
   192  	for _, i := range p {
   193  		str += fmt.Sprintf("%08b", i)
   194  	}
   195  	str = str[0:8] + "..." + str[len(str)-8:]
   196  	return str
   197  }
   198  
   199  // Equals compares this path to another path
   200  func (p Path) Equals(o Path) bool {
   201  	return p == o
   202  }
   203  
   204  // ToPath converts a byte slice into a path.
   205  // It returns an error if the slice has an invalid length.
   206  func ToPath(pathBytes []byte) (Path, error) {
   207  	var path Path
   208  	if len(pathBytes) != len(path) {
   209  		return DummyPath, fmt.Errorf("expecting %d bytes but got %d bytes", len(path), len(pathBytes))
   210  	}
   211  	copy(path[:], pathBytes)
   212  	return path, nil
   213  }
   214  
   215  // encKey represents an encoded ledger key.
   216  type encKey []byte
   217  
   218  // Size returns the byte size of the encoded key.
   219  func (k encKey) Size() int {
   220  	return len(k)
   221  }
   222  
   223  // String returns the string representation of the encoded key.
   224  func (k encKey) String() string {
   225  	return hex.EncodeToString(k)
   226  }
   227  
   228  // Equals compares this encoded key to another encoded key.
   229  // A nil encoded key is equivalent to an empty encoded key.
   230  func (k encKey) Equals(other encKey) bool {
   231  	return bytes.Equal(k, other)
   232  }
   233  
   234  // DeepCopy returns a deep copy of the encoded key.
   235  func (k encKey) DeepCopy() encKey {
   236  	newK := make([]byte, len(k))
   237  	copy(newK, k)
   238  	return newK
   239  }
   240  
   241  const (
   242  	KeyPartOwner = uint16(0)
   243  	// Deprecated: KeyPartController was only used by the very first
   244  	// version of Cadence for access control, which was later retired
   245  	_          = uint16(1) // DO NOT REUSE
   246  	KeyPartKey = uint16(2)
   247  )
   248  
   249  // Payload is the smallest immutable storable unit in ledger
   250  type Payload struct {
   251  	// encKey is key encoded using PayloadVersion.
   252  	// Version and type data are not encoded to save 3 bytes.
   253  	// NOTE: encKey translates to Key{} when encKey is
   254  	//       one of these three values:
   255  	//       nil, []byte{}, []byte{0,0}.
   256  	encKey encKey
   257  	value  Value
   258  }
   259  
   260  // serializablePayload is used to serialize ledger.Payload.
   261  // Encoder only serializes exported fields and ledger.Payload's
   262  // key and value fields are not exported.  So it is necessary to
   263  // use serializablePayload for encoding.
   264  type serializablePayload struct {
   265  	Key   Key
   266  	Value Value
   267  }
   268  
   269  // MarshalJSON returns JSON encoding of p.
   270  func (p Payload) MarshalJSON() ([]byte, error) {
   271  	k, err := p.Key()
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  	sp := serializablePayload{Key: k, Value: p.value}
   276  	return json.Marshal(sp)
   277  }
   278  
   279  // UnmarshalJSON unmarshals a JSON value of payload.
   280  func (p *Payload) UnmarshalJSON(b []byte) error {
   281  	if p == nil {
   282  		return errors.New("UnmarshalJSON on nil Payload")
   283  	}
   284  	var sp serializablePayload
   285  	if err := json.Unmarshal(b, &sp); err != nil {
   286  		return err
   287  	}
   288  	p.encKey = encodeKey(&sp.Key, PayloadVersion)
   289  	p.value = sp.Value
   290  	return nil
   291  }
   292  
   293  // MarshalCBOR returns CBOR encoding of p.
   294  func (p Payload) MarshalCBOR() ([]byte, error) {
   295  	k, err := p.Key()
   296  	if err != nil {
   297  		return nil, err
   298  	}
   299  	sp := serializablePayload{Key: k, Value: p.value}
   300  	return cbor.Marshal(sp)
   301  }
   302  
   303  // UnmarshalCBOR unmarshals a CBOR value of payload.
   304  func (p *Payload) UnmarshalCBOR(b []byte) error {
   305  	if p == nil {
   306  		return errors.New("UnmarshalCBOR on nil payload")
   307  	}
   308  	var sp serializablePayload
   309  	if err := cbor.Unmarshal(b, &sp); err != nil {
   310  		return err
   311  	}
   312  	p.encKey = encodeKey(&sp.Key, PayloadVersion)
   313  	p.value = sp.Value
   314  	return nil
   315  }
   316  
   317  // Key returns payload key.
   318  // Error indicates that ledger.Key can't be created from payload key, so
   319  // migration and reporting (known callers) should abort.
   320  // CAUTION: do not modify returned key because it shares underlying data with payload key.
   321  func (p *Payload) Key() (Key, error) {
   322  	if p == nil || len(p.encKey) == 0 {
   323  		return Key{}, nil
   324  	}
   325  	k, err := decodeKey(p.encKey, true, PayloadVersion)
   326  	if err != nil {
   327  		return Key{}, err
   328  	}
   329  	return *k, nil
   330  }
   331  
   332  // EncodedKey returns payload key.
   333  // CAUTION: do not modify returned encoded key
   334  // because it shares underlying data with payload key.
   335  func (p *Payload) EncodedKey() []byte {
   336  	if p == nil {
   337  		return nil
   338  	}
   339  	return p.encKey
   340  }
   341  
   342  // Address returns:
   343  // - (address, nil) if the payload is for an account, the account address is returned
   344  // - (flow.EmptyAddress, nil) if the payload is not for an account (global register)
   345  // - (flow.EmptyAddress, err) if running into any exception
   346  // The zero address is used for global Payloads and is not an actual account
   347  func (p *Payload) Address() (flow.Address, error) {
   348  	if p == nil {
   349  		return flow.EmptyAddress, fmt.Errorf("failed to get payload address: payload is nil")
   350  	}
   351  	if len(p.encKey) == 0 {
   352  		return flow.EmptyAddress, fmt.Errorf("failed to get payload address: encoded key is empty")
   353  	}
   354  	b, found, err := decodeKeyPartValueByType(p.encKey, KeyPartOwner, true, PayloadVersion)
   355  	if err != nil {
   356  		return flow.EmptyAddress, err
   357  	}
   358  	if !found {
   359  		return flow.EmptyAddress, fmt.Errorf("failed to find address by type %d", KeyPartOwner)
   360  	}
   361  	return flow.BytesToAddress(b), nil
   362  }
   363  
   364  // Value returns payload value.
   365  // CAUTION: do not modify returned value because it shares underlying data with payload value.
   366  func (p *Payload) Value() Value {
   367  	if p == nil {
   368  		return Value{}
   369  	}
   370  	return p.value
   371  }
   372  
   373  // Size returns the size of the payload
   374  func (p *Payload) Size() int {
   375  	if p == nil {
   376  		return 0
   377  	}
   378  	return p.encKey.Size() + p.value.Size()
   379  }
   380  
   381  // IsEmpty returns true if payload is nil or value is empty
   382  func (p *Payload) IsEmpty() bool {
   383  	return p == nil || p.value.Size() == 0
   384  }
   385  
   386  // TODO fix me
   387  func (p *Payload) String() string {
   388  	// TODO improve this key, values
   389  	return p.encKey.String() + " " + p.value.String()
   390  }
   391  
   392  // Equals compares this payload to another payload
   393  // A nil payload is equivalent to an empty payload.
   394  func (p *Payload) Equals(other *Payload) bool {
   395  	if p == nil || (p.encKey.Size() == 0 && p.value.Size() == 0) {
   396  		return other == nil || (other.encKey.Size() == 0 && other.value.Size() == 0)
   397  	}
   398  	if other == nil {
   399  		return false
   400  	}
   401  	return p.encKey.Equals(other.encKey) && p.value.Equals(other.value)
   402  }
   403  
   404  // ValueEquals compares this payload value to another payload value.
   405  // A nil payload is equivalent to an empty payload.
   406  // NOTE: prefer using this function over payload.Value.Equals()
   407  // when comparing payload values.  payload.ValueEquals() handles
   408  // nil payload, while payload.Value.Equals() panics on nil payload.
   409  func (p *Payload) ValueEquals(other *Payload) bool {
   410  	pEmpty := p.IsEmpty()
   411  	otherEmpty := other.IsEmpty()
   412  	if pEmpty != otherEmpty {
   413  		// Only one payload is empty
   414  		return false
   415  	}
   416  	if pEmpty {
   417  		// Both payloads are empty
   418  		return true
   419  	}
   420  	// Compare values since both payloads are not empty.
   421  	return p.value.Equals(other.value)
   422  }
   423  
   424  // DeepCopy returns a deep copy of the payload
   425  func (p *Payload) DeepCopy() *Payload {
   426  	if p == nil {
   427  		return nil
   428  	}
   429  	k := p.encKey.DeepCopy()
   430  	v := p.value.DeepCopy()
   431  	return &Payload{encKey: k, value: v}
   432  }
   433  
   434  // NewPayload returns a new payload
   435  func NewPayload(key Key, value Value) *Payload {
   436  	ek := encodeKey(&key, PayloadVersion)
   437  	return &Payload{encKey: ek, value: value}
   438  }
   439  
   440  // EmptyPayload returns an empty payload
   441  func EmptyPayload() *Payload {
   442  	return &Payload{}
   443  }
   444  
   445  // TrieProof includes all the information needed to walk
   446  // through a trie branch from an specific leaf node (key)
   447  // up to the root of the trie.
   448  type TrieProof struct {
   449  	Path      Path        // path
   450  	Payload   *Payload    // payload
   451  	Interims  []hash.Hash // the non-default intermediate nodes in the proof
   452  	Inclusion bool        // flag indicating if this is an inclusion or exclusion proof
   453  	Flags     []byte      // The flags of the proofs (is set if an intermediate node has a non-default)
   454  	Steps     uint8       // number of steps for the proof (path len) // TODO: should this be a type allowing for larger values?
   455  }
   456  
   457  // NewTrieProof creates a new instance of Trie Proof
   458  func NewTrieProof() *TrieProof {
   459  	return &TrieProof{
   460  		Payload:   EmptyPayload(),
   461  		Interims:  make([]hash.Hash, 0),
   462  		Inclusion: false,
   463  		Flags:     make([]byte, PathLen),
   464  		Steps:     0,
   465  	}
   466  }
   467  
   468  func (p *TrieProof) String() string {
   469  	flagStr := ""
   470  	for _, f := range p.Flags {
   471  		flagStr += fmt.Sprintf("%08b", f)
   472  	}
   473  	proofStr := fmt.Sprintf("size: %d flags: %v\n", p.Steps, flagStr)
   474  	proofStr += fmt.Sprintf("\t path: %v payload: %v\n", p.Path, p.Payload)
   475  
   476  	if p.Inclusion {
   477  		proofStr += "\t inclusion proof:\n"
   478  	} else {
   479  		proofStr += "\t noninclusion proof:\n"
   480  	}
   481  	interimIndex := 0
   482  	for j := 0; j < int(p.Steps); j++ {
   483  		// if bit is set
   484  		if p.Flags[j/8]&(1<<(7-j%8)) != 0 {
   485  			proofStr += fmt.Sprintf("\t\t %d: [%x]\n", j, p.Interims[interimIndex])
   486  			interimIndex++
   487  		}
   488  	}
   489  	return proofStr
   490  }
   491  
   492  // Equals compares this proof to another payload
   493  func (p *TrieProof) Equals(o *TrieProof) bool {
   494  	if o == nil {
   495  		return false
   496  	}
   497  	if !p.Path.Equals(o.Path) {
   498  		return false
   499  	}
   500  	if !p.Payload.Equals(o.Payload) {
   501  		return false
   502  	}
   503  	if len(p.Interims) != len(o.Interims) {
   504  		return false
   505  	}
   506  	for i, inter := range p.Interims {
   507  		if inter != o.Interims[i] {
   508  			return false
   509  		}
   510  	}
   511  	if p.Inclusion != o.Inclusion {
   512  		return false
   513  	}
   514  	if !bytes.Equal(p.Flags, o.Flags) {
   515  		return false
   516  	}
   517  	if p.Steps != o.Steps {
   518  		return false
   519  	}
   520  	return true
   521  }
   522  
   523  // TrieBatchProof is a struct that holds the proofs for several keys
   524  //
   525  // so there is no need for two calls (read, proofs)
   526  type TrieBatchProof struct {
   527  	Proofs []*TrieProof
   528  }
   529  
   530  // NewTrieBatchProof creates a new instance of BatchProof
   531  func NewTrieBatchProof() *TrieBatchProof {
   532  	bp := new(TrieBatchProof)
   533  	bp.Proofs = make([]*TrieProof, 0)
   534  	return bp
   535  }
   536  
   537  // NewTrieBatchProofWithEmptyProofs creates an instance of Batchproof
   538  // filled with n newly created proofs (empty)
   539  func NewTrieBatchProofWithEmptyProofs(numberOfProofs int) *TrieBatchProof {
   540  	bp := new(TrieBatchProof)
   541  	bp.Proofs = make([]*TrieProof, numberOfProofs)
   542  	for i := 0; i < numberOfProofs; i++ {
   543  		bp.Proofs[i] = NewTrieProof()
   544  	}
   545  	return bp
   546  }
   547  
   548  // Size returns the number of proofs
   549  func (bp *TrieBatchProof) Size() int {
   550  	return len(bp.Proofs)
   551  }
   552  
   553  // Paths returns the slice of paths for this batch proof
   554  func (bp *TrieBatchProof) Paths() []Path {
   555  	paths := make([]Path, len(bp.Proofs))
   556  	for i, p := range bp.Proofs {
   557  		paths[i] = p.Path
   558  	}
   559  	return paths
   560  }
   561  
   562  // Payloads returns the slice of paths for this batch proof
   563  func (bp *TrieBatchProof) Payloads() []*Payload {
   564  	payloads := make([]*Payload, len(bp.Proofs))
   565  	for i, p := range bp.Proofs {
   566  		payloads[i] = p.Payload
   567  	}
   568  	return payloads
   569  }
   570  
   571  func (bp *TrieBatchProof) String() string {
   572  	res := fmt.Sprintf("trie batch proof includes %d proofs: \n", bp.Size())
   573  	for _, proof := range bp.Proofs {
   574  		res = res + "\n" + proof.String()
   575  	}
   576  	return res
   577  }
   578  
   579  // AppendProof adds a proof to the batch proof
   580  func (bp *TrieBatchProof) AppendProof(p *TrieProof) {
   581  	bp.Proofs = append(bp.Proofs, p)
   582  }
   583  
   584  // MergeInto adds all of its proofs into the dest batch proof
   585  func (bp *TrieBatchProof) MergeInto(dest *TrieBatchProof) {
   586  	for _, p := range bp.Proofs {
   587  		dest.AppendProof(p)
   588  	}
   589  }
   590  
   591  // Equals compares this batch proof to another batch proof
   592  func (bp *TrieBatchProof) Equals(o *TrieBatchProof) bool {
   593  	if o == nil {
   594  		return false
   595  	}
   596  	if len(bp.Proofs) != len(o.Proofs) {
   597  		return false
   598  	}
   599  	for i, proof := range bp.Proofs {
   600  		if !proof.Equals(o.Proofs[i]) {
   601  			return false
   602  		}
   603  	}
   604  	return true
   605  }