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