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

     1  package execution
     2  
     3  import (
     4  	"github.com/onflow/flow-go/fvm/storage/snapshot"
     5  	"github.com/onflow/flow-go/model/flow"
     6  	"github.com/onflow/flow-go/module/finalizedreader"
     7  	"github.com/onflow/flow-go/storage"
     8  	"github.com/onflow/flow-go/storage/pebble"
     9  )
    10  
    11  // RegisterStore is the interface for register store
    12  // see implementation in engine/execution/storehouse/register_store.go
    13  type RegisterStore interface {
    14  	// GetRegister first try to get the register from InMemoryRegisterStore, then OnDiskRegisterStore
    15  	// It returns:
    16  	//  - (value, nil) if the register value is found at the given block
    17  	//  - (nil, nil) if the register is not found
    18  	//  - (nil, storage.ErrHeightNotIndexed) if the height is below the first height that is indexed.
    19  	//  - (nil, storehouse.ErrNotExecuted) if the block is not executed yet
    20  	//  - (nil, storehouse.ErrNotExecuted) if the block is conflicting iwth finalized block
    21  	//  - (nil, err) for any other exceptions
    22  	GetRegister(height uint64, blockID flow.Identifier, register flow.RegisterID) (flow.RegisterValue, error)
    23  
    24  	// SaveRegisters saves to InMemoryRegisterStore first, then trigger the same check as OnBlockFinalized
    25  	// Depend on InMemoryRegisterStore.SaveRegisters
    26  	// It returns:
    27  	// - nil if the registers are saved successfully
    28  	// - exception is the block is above the pruned height but does not connect to the pruned height (conflicting block).
    29  	// - exception if the block is below the pruned height
    30  	// - exception if the save block is saved again
    31  	// - exception for any other exception
    32  	SaveRegisters(header *flow.Header, registers flow.RegisterEntries) error
    33  
    34  	// Depend on FinalizedReader's FinalizedBlockIDAtHeight
    35  	// Depend on ExecutedFinalizedWAL.Append
    36  	// Depend on OnDiskRegisterStore.SaveRegisters
    37  	// OnBlockFinalized trigger the check of whether a block at the next height becomes finalized and executed.
    38  	// Note: This is a blocking call
    39  	// the next height is the existing finalized and executed block's height + 1.
    40  	// If a block at next height becomes finalized and executed, then:
    41  	// 1. write the registers to write ahead logs
    42  	// 2. save the registers of the block to OnDiskRegisterStore
    43  	// 3. prune the height in InMemoryRegisterStore
    44  	// any error returned are exception
    45  	OnBlockFinalized() error
    46  
    47  	// LastFinalizedAndExecutedHeight returns the height of the last finalized and executed block,
    48  	// which has been saved in OnDiskRegisterStore
    49  	LastFinalizedAndExecutedHeight() uint64
    50  
    51  	// IsBlockExecuted returns whether the given block is executed.
    52  	// If a block is not executed, it does not distinguish whether the block exists or not.
    53  	// It returns:
    54  	// - (true, nil) if the block is executed, regardless of whether the registers of the block is pruned on disk or not
    55  	// - (false, nil) if the block is not executed
    56  	// - (false, exception) if running into any exception
    57  	IsBlockExecuted(height uint64, blockID flow.Identifier) (bool, error)
    58  }
    59  
    60  // RegisterStoreNotifier is the interface for register store to notify when a block is finalized and executed
    61  type RegisterStoreNotifier interface {
    62  	OnFinalizedAndExecutedHeightUpdated(height uint64)
    63  }
    64  
    65  type FinalizedReader interface {
    66  	// FinalizedBlockIDAtHeight returns the block ID of the finalized block at the given height.
    67  	// It return storage.NotFound if the given height has not been finalized yet
    68  	// any other error returned are exceptions
    69  	FinalizedBlockIDAtHeight(height uint64) (flow.Identifier, error)
    70  }
    71  
    72  // finalizedreader.FinalizedReader is an implementation of FinalizedReader interface
    73  var _ FinalizedReader = (*finalizedreader.FinalizedReader)(nil)
    74  
    75  // see implementation in engine/execution/storehouse/in_memory_register_store.go
    76  type InMemoryRegisterStore interface {
    77  	Prune(finalizedHeight uint64, finalizedBlockID flow.Identifier) error
    78  	PrunedHeight() uint64
    79  
    80  	// GetRegister will return the latest updated value of the given register since the pruned height.
    81  	// It returns ErrPruned if the register is unknown or not updated since the pruned height
    82  	// It returns exception if internal index is inconsistent
    83  	GetRegister(height uint64, blockID flow.Identifier, register flow.RegisterID) (flow.RegisterValue, error)
    84  	GetUpdatedRegisters(height uint64, blockID flow.Identifier) (flow.RegisterEntries, error)
    85  	SaveRegisters(
    86  		height uint64,
    87  		blockID flow.Identifier,
    88  		parentID flow.Identifier,
    89  		registers flow.RegisterEntries,
    90  	) error
    91  
    92  	// IsBlockExecuted returns wheather the given block is executed.
    93  	// It returns:
    94  	// - (true, nil) if the block is above the pruned height and is executed
    95  	// - (true, nil) if the block is the pruned block, since the prunded block are finalized and executed
    96  	// - (false, nil) if the block is above the pruned height and is not executed
    97  	// - (false, nil) if the block's height is the pruned height, but is different from the pruned block
    98  	// - (false, exception) if the block is below the pruned height
    99  	IsBlockExecuted(height uint64, blockID flow.Identifier) (bool, error)
   100  }
   101  
   102  type OnDiskRegisterStore = storage.RegisterIndex
   103  
   104  // pebble.Registers is an implementation of OnDiskRegisterStore interface
   105  var _ OnDiskRegisterStore = (*pebble.Registers)(nil)
   106  
   107  type ExecutedFinalizedWAL interface {
   108  	Append(height uint64, registers flow.RegisterEntries) error
   109  
   110  	// Latest returns the latest height in the WAL.
   111  	Latest() (uint64, error)
   112  
   113  	GetReader(height uint64) WALReader
   114  }
   115  
   116  type WALReader interface {
   117  	// Next returns the next height and trie updates in the WAL.
   118  	// It returns EOF when there are no more entries.
   119  	Next() (height uint64, registers flow.RegisterEntries, err error)
   120  }
   121  
   122  type ExtendableStorageSnapshot interface {
   123  	snapshot.StorageSnapshot
   124  	Extend(newCommit flow.StateCommitment, updatedRegisters map[flow.RegisterID]flow.RegisterValue) ExtendableStorageSnapshot
   125  	Commitment() flow.StateCommitment
   126  }