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

     1  package ledger
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"encoding/hex"
     7  	"encoding/json"
     8  	"errors"
     9  	"fmt"
    10  	"strconv"
    11  
    12  	"github.com/onflow/flow-go/ledger/common/hash"
    13  	"github.com/onflow/flow-go/module"
    14  )
    15  
    16  // Ledger is a stateful fork-aware key/value storage.
    17  // Any update (value change for a key) to the ledger generates a new ledger state.
    18  // Updates can be applied to any recent states. These changes don't have to be sequential and ledger supports a tree of states.
    19  // Ledger provides value lookup by key at a particular state (historic lookups) and can prove the existence/non-existence of a key-value pair at the given state.
    20  // Ledger assumes the initial state includes all keys with an empty bytes slice as value.
    21  type Ledger interface {
    22  	// ledger implements methods needed to be ReadyDone aware
    23  	module.ReadyDoneAware
    24  
    25  	// InitialState returns the initial state of the ledger
    26  	InitialState() State
    27  
    28  	// HasState returns true if the given state exists inside the ledger
    29  	HasState(state State) bool
    30  
    31  	// GetSingleValue returns value for a given key at specific state
    32  	GetSingleValue(query *QuerySingleValue) (value Value, err error)
    33  
    34  	// Get returns values for the given slice of keys at specific state
    35  	Get(query *Query) (values []Value, err error)
    36  
    37  	// Update updates a list of keys with new values at specific state (update) and returns a new state
    38  	Set(update *Update) (newState State, trieUpdate *TrieUpdate, err error)
    39  
    40  	// Prove returns proofs for the given keys at specific state
    41  	Prove(query *Query) (proof Proof, err error)
    42  }
    43  
    44  // Query holds all data needed for a ledger read or ledger proof
    45  type Query struct {
    46  	state State
    47  	keys  []Key
    48  }
    49  
    50  // NewEmptyQuery returns an empty ledger query
    51  func NewEmptyQuery(sc State) (*Query, error) {
    52  	return &Query{state: sc}, nil
    53  }
    54  
    55  // NewQuery constructs a new ledger query
    56  func NewQuery(sc State, keys []Key) (*Query, error) {
    57  	return &Query{state: sc, keys: keys}, nil
    58  }
    59  
    60  // Keys returns keys of the query
    61  func (q *Query) Keys() []Key {
    62  	return q.keys
    63  }
    64  
    65  // Size returns number of keys in the query
    66  func (q *Query) Size() int {
    67  	return len(q.keys)
    68  }
    69  
    70  // State returns the state part of the query
    71  func (q *Query) State() State {
    72  	return q.state
    73  }
    74  
    75  // SetState sets the state part of the query
    76  func (q *Query) SetState(s State) {
    77  	q.state = s
    78  }
    79  
    80  // QuerySingleValue contains ledger query for a single value
    81  type QuerySingleValue struct {
    82  	state State
    83  	key   Key
    84  }
    85  
    86  // NewQuerySingleValue constructs a new ledger query for a single value
    87  func NewQuerySingleValue(sc State, key Key) (*QuerySingleValue, error) {
    88  	return &QuerySingleValue{state: sc, key: key}, nil
    89  }
    90  
    91  // Key returns key of the query
    92  func (q *QuerySingleValue) Key() Key {
    93  	return q.key
    94  }
    95  
    96  // State returns the state part of the query
    97  func (q *QuerySingleValue) State() State {
    98  	return q.state
    99  }
   100  
   101  // Update holds all data needed for a ledger update
   102  type Update struct {
   103  	state  State
   104  	keys   []Key
   105  	values []Value
   106  }
   107  
   108  // Size returns number of keys in the ledger update
   109  func (u *Update) Size() int {
   110  	return len(u.keys)
   111  }
   112  
   113  // Keys returns keys of the update
   114  func (u *Update) Keys() []Key {
   115  	return u.keys
   116  }
   117  
   118  // Values returns value of the update
   119  func (u *Update) Values() []Value {
   120  	return u.values
   121  }
   122  
   123  // State returns the state part of this update
   124  func (u *Update) State() State {
   125  	return u.state
   126  }
   127  
   128  // SetState sets the state part of the update
   129  func (u *Update) SetState(sc State) {
   130  	u.state = sc
   131  }
   132  
   133  // NewEmptyUpdate returns an empty ledger update
   134  func NewEmptyUpdate(sc State) (*Update, error) {
   135  	return &Update{state: sc}, nil
   136  }
   137  
   138  // NewUpdate returns an ledger update
   139  func NewUpdate(sc State, keys []Key, values []Value) (*Update, error) {
   140  	if len(keys) != len(values) {
   141  		return nil, fmt.Errorf("length mismatch: keys have %d elements, but values have %d elements", len(keys), len(values))
   142  	}
   143  	return &Update{state: sc, keys: keys, values: values}, nil
   144  
   145  }
   146  
   147  // State captures an state of the ledger
   148  type State hash.Hash
   149  
   150  // DummyState is an arbitrary value used in function failure cases,
   151  // although it can represent a valid state.
   152  var DummyState = State(hash.DummyHash)
   153  
   154  // String returns the hex encoding of the state
   155  func (sc State) String() string {
   156  	return hex.EncodeToString(sc[:])
   157  }
   158  
   159  // Base64 return the base64 encoding of the state
   160  func (sc State) Base64() string {
   161  	return base64.StdEncoding.EncodeToString(sc[:])
   162  }
   163  
   164  // Equals compares the state to another state
   165  func (sc State) Equals(o State) bool {
   166  	return sc == o
   167  }
   168  
   169  // ToState converts a byte slice into a State.
   170  // It returns an error if the slice has an invalid length.
   171  func ToState(stateBytes []byte) (State, error) {
   172  	var state State
   173  	if len(stateBytes) != len(state) {
   174  		return DummyState, fmt.Errorf("expecting %d bytes but got %d bytes", len(state), len(stateBytes))
   175  	}
   176  	copy(state[:], stateBytes)
   177  	return state, nil
   178  }
   179  
   180  // Proof is a byte slice capturing encoded version of a batch proof
   181  type Proof []byte
   182  
   183  func (pr Proof) String() string {
   184  	return hex.EncodeToString(pr)
   185  }
   186  
   187  // Equals compares a proof to another ledger proof
   188  func (pr Proof) Equals(o Proof) bool {
   189  	if o == nil {
   190  		return false
   191  	}
   192  	return bytes.Equal(pr, o)
   193  }
   194  
   195  // Key represents a hierarchical ledger key
   196  type Key struct {
   197  	KeyParts []KeyPart
   198  }
   199  
   200  // NewKey construct a new key
   201  func NewKey(kp []KeyPart) Key {
   202  	return Key{KeyParts: kp}
   203  }
   204  
   205  // Size returns the byte size needed to encode the key
   206  func (k *Key) Size() int {
   207  	size := 0
   208  	for _, kp := range k.KeyParts {
   209  		// value size + 2 bytes for type
   210  		size += len(kp.Value) + 2
   211  	}
   212  	return size
   213  }
   214  
   215  // CanonicalForm returns a byte slice describing the key
   216  // Warning: Changing this has an impact on how leaf hashes are computed!
   217  // don't use this to reconstruct the key later
   218  func (k *Key) CanonicalForm() []byte {
   219  	// calculate the size of the byte array
   220  
   221  	// the maximum size of a uint16 is 5 characters, so
   222  	// this is using 10 for the estimate, to include the two '/'
   223  	// characters and an extra 3 characters for padding safety
   224  
   225  	constant := 10
   226  
   227  	requiredLen := constant * len(k.KeyParts)
   228  	for _, kp := range k.KeyParts {
   229  		requiredLen += len(kp.Value)
   230  	}
   231  
   232  	retval := make([]byte, 0, requiredLen)
   233  
   234  	for _, kp := range k.KeyParts {
   235  		typeNumber := strconv.Itoa(int(kp.Type))
   236  
   237  		retval = append(retval, byte('/'))
   238  		retval = append(retval, []byte(typeNumber)...)
   239  		retval = append(retval, byte('/'))
   240  		retval = append(retval, kp.Value...)
   241  	}
   242  
   243  	// create a byte slice with the correct size and copy
   244  	// the estimated string into it.
   245  	return retval
   246  }
   247  
   248  func (k *Key) String() string {
   249  	return string(k.CanonicalForm())
   250  }
   251  
   252  // DeepCopy returns a deep copy of the key
   253  func (k *Key) DeepCopy() Key {
   254  	newKPs := make([]KeyPart, len(k.KeyParts))
   255  	for i, kp := range k.KeyParts {
   256  		newKPs[i] = *kp.DeepCopy()
   257  	}
   258  	return Key{KeyParts: newKPs}
   259  }
   260  
   261  // Equals compares this key to another key
   262  // A nil key is equivalent to an empty key.
   263  func (k *Key) Equals(other *Key) bool {
   264  	if k == nil || len(k.KeyParts) == 0 {
   265  		return other == nil || len(other.KeyParts) == 0
   266  	}
   267  	if other == nil {
   268  		return false
   269  	}
   270  	if len(k.KeyParts) != len(other.KeyParts) {
   271  		return false
   272  	}
   273  	for i, kp := range k.KeyParts {
   274  		if !kp.Equals(&other.KeyParts[i]) {
   275  			return false
   276  		}
   277  	}
   278  	return true
   279  }
   280  
   281  // KeyPart is a typed part of a key
   282  type KeyPart struct {
   283  	Type  uint16
   284  	Value []byte
   285  }
   286  
   287  // NewKeyPart construct a new key part
   288  func NewKeyPart(typ uint16, val []byte) KeyPart {
   289  	return KeyPart{Type: typ, Value: val}
   290  }
   291  
   292  // Equals compares this key part to another key part
   293  func (kp *KeyPart) Equals(other *KeyPart) bool {
   294  	if other == nil {
   295  		return false
   296  	}
   297  	if kp.Type != other.Type {
   298  		return false
   299  	}
   300  	return bytes.Equal(kp.Value, other.Value)
   301  }
   302  
   303  // DeepCopy returns a deep copy of the key part
   304  func (kp *KeyPart) DeepCopy() *KeyPart {
   305  	newV := make([]byte, len(kp.Value))
   306  	copy(newV, kp.Value)
   307  	return &KeyPart{Type: kp.Type, Value: newV}
   308  }
   309  
   310  func (kp KeyPart) MarshalJSON() ([]byte, error) {
   311  	return json.Marshal(struct {
   312  		Type  uint16
   313  		Value string
   314  	}{
   315  		Type:  kp.Type,
   316  		Value: hex.EncodeToString(kp.Value),
   317  	})
   318  }
   319  
   320  // UnmarshalJSON unmarshals a JSON value of KeyPart.
   321  func (kp *KeyPart) UnmarshalJSON(b []byte) error {
   322  	if kp == nil {
   323  		return errors.New("UnmarshalJSON on nil KeyPart")
   324  	}
   325  	var v struct {
   326  		Type  uint16
   327  		Value string
   328  	}
   329  	err := json.Unmarshal(b, &v)
   330  	if err != nil {
   331  		return err
   332  	}
   333  	data, err := hex.DecodeString(v.Value)
   334  	if err != nil {
   335  		return err
   336  	}
   337  	kp.Type = v.Type
   338  	kp.Value = data
   339  	return nil
   340  }
   341  
   342  // Value holds the value part of a ledger key value pair
   343  type Value []byte
   344  
   345  // Size returns the value size
   346  func (v Value) Size() int {
   347  	return len(v)
   348  }
   349  
   350  func (v Value) String() string {
   351  	return hex.EncodeToString(v)
   352  }
   353  
   354  // DeepCopy returns a deep copy of the value
   355  func (v Value) DeepCopy() Value {
   356  	newV := make([]byte, len(v))
   357  	copy(newV, v)
   358  	return newV
   359  }
   360  
   361  // Equals compares a ledger Value to another one
   362  // A nil value is equivalent to an empty value.
   363  func (v Value) Equals(other Value) bool {
   364  	return bytes.Equal(v, other)
   365  }
   366  
   367  func (v Value) MarshalJSON() ([]byte, error) {
   368  	return json.Marshal(hex.EncodeToString(v))
   369  }
   370  
   371  // UnmarshalJSON unmarshals a JSON value of Value.
   372  func (v *Value) UnmarshalJSON(b []byte) error {
   373  	if v == nil {
   374  		return errors.New("UnmarshalJSON on nil Value")
   375  	}
   376  	var s string
   377  	err := json.Unmarshal(b, &s)
   378  	if err != nil {
   379  		return err
   380  	}
   381  	data, err := hex.DecodeString(s)
   382  	if err != nil {
   383  		return err
   384  	}
   385  	*v = data
   386  	return nil
   387  }
   388  
   389  // Migration defines how to convert the given slice of input payloads into an slice of output payloads
   390  type Migration func(payloads []*Payload) ([]*Payload, error)
   391  
   392  // Reporter reports on data from the state
   393  type Reporter interface {
   394  	// Name returns the name of the reporter. Only used for logging.
   395  	Name() string
   396  	// Report accepts slice ledger payloads and reports the state of the ledger
   397  	Report(payloads []Payload, statecommitment State) error
   398  }