github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/storage/state/storage_state.go (about)

     1  package state
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/onflow/flow-go/fvm/storage/snapshot"
     7  	"github.com/onflow/flow-go/model/flow"
     8  )
     9  
    10  type storageState struct {
    11  	baseStorage snapshot.StorageSnapshot
    12  
    13  	// The read set only include reads from the baseStorage
    14  	readSet map[flow.RegisterID]struct{}
    15  
    16  	writeSet map[flow.RegisterID]flow.RegisterValue
    17  }
    18  
    19  func newStorageState(base snapshot.StorageSnapshot) *storageState {
    20  	return &storageState{
    21  		baseStorage: base,
    22  		readSet:     map[flow.RegisterID]struct{}{},
    23  		writeSet:    map[flow.RegisterID]flow.RegisterValue{},
    24  	}
    25  }
    26  
    27  func (state *storageState) NewChild() *storageState {
    28  	return newStorageState(snapshot.NewPeekerStorageSnapshot(state))
    29  }
    30  
    31  func (state *storageState) Finalize() *snapshot.ExecutionSnapshot {
    32  	return &snapshot.ExecutionSnapshot{
    33  		ReadSet:  state.readSet,
    34  		WriteSet: state.writeSet,
    35  	}
    36  }
    37  
    38  func (state *storageState) Merge(snapshot *snapshot.ExecutionSnapshot) error {
    39  	for id := range snapshot.ReadSet {
    40  		_, ok := state.writeSet[id]
    41  		if ok {
    42  			continue
    43  		}
    44  		state.readSet[id] = struct{}{}
    45  	}
    46  
    47  	for id, value := range snapshot.WriteSet {
    48  		state.writeSet[id] = value
    49  	}
    50  
    51  	return nil
    52  }
    53  
    54  func (state *storageState) Set(
    55  	id flow.RegisterID,
    56  	value flow.RegisterValue,
    57  ) error {
    58  	state.writeSet[id] = value
    59  	return nil
    60  }
    61  
    62  func (state *storageState) get(
    63  	id flow.RegisterID,
    64  ) (
    65  	bool, // read from base storage
    66  	flow.RegisterValue,
    67  	error,
    68  ) {
    69  	value, ok := state.writeSet[id]
    70  	if ok {
    71  		return false, value, nil
    72  	}
    73  
    74  	if state.baseStorage == nil {
    75  		return true, nil, nil
    76  	}
    77  
    78  	value, err := state.baseStorage.Get(id)
    79  	if err != nil {
    80  		return true, nil, fmt.Errorf("get register failed: %w", err)
    81  	}
    82  
    83  	return true, value, nil
    84  }
    85  
    86  func (state *storageState) Get(
    87  	id flow.RegisterID,
    88  ) (
    89  	flow.RegisterValue,
    90  	error,
    91  ) {
    92  	readFromBaseStorage, value, err := state.get(id)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  
    97  	if readFromBaseStorage {
    98  		state.readSet[id] = struct{}{}
    99  	}
   100  
   101  	return value, nil
   102  }
   103  
   104  func (state *storageState) Peek(
   105  	id flow.RegisterID,
   106  ) (
   107  	flow.RegisterValue,
   108  	error,
   109  ) {
   110  	_, value, err := state.get(id)
   111  	return value, err
   112  }
   113  
   114  func (state *storageState) DropChanges() error {
   115  	state.writeSet = map[flow.RegisterID]flow.RegisterValue{}
   116  	return nil
   117  }
   118  
   119  func (state *storageState) readSetSize() int {
   120  	return len(state.readSet)
   121  }
   122  
   123  func (state *storageState) interimReadSet(
   124  	accumulator map[flow.RegisterID]struct{},
   125  ) {
   126  	for id := range state.writeSet {
   127  		delete(accumulator, id)
   128  	}
   129  
   130  	for id := range state.readSet {
   131  		accumulator[id] = struct{}{}
   132  	}
   133  }